memory cache — встроенный механизм кэширования Webpack,
при котором результаты сборки сохраняются в оперативной памяти процесса
Node.js. Такой кэш существует только во время жизни текущего процесса и
полностью очищается после завершения работы сборщика.
В Webpack 5 память стала полноценным уровнем кэширования, позволяющим значительно ускорять повторные компиляции, rebuild-процессы и работу dev server.
Базовая настройка:
module.exports = {
cache: {
type: 'memory'
}
};
Во время компиляции Webpack выполняет множество дорогостоящих операций:
Memory cache позволяет не выполнять повторно операции, результаты которых уже известны.
Например:
src/index.js
├── import './app.js'
├── import './styles.css'
└── import 'lodash'
После первой компиляции Webpack сохраняет в памяти:
При повторной сборке неизменённые модули извлекаются из памяти мгновенно.
Хранение:
RAM процесса Node.js
Жизненный цикл:
До завершения процесса
Скорость:
Очень высокая
Персистентность:
Нет
Хранение:
Файлы на диске
Жизненный цикл:
Между запусками Webpack
Скорость:
Ниже memory cache
Персистентность:
Да
Пример filesystem cache:
module.exports = {
cache: {
type: 'filesystem'
}
};
Наиболее распространённый сценарий.
Во время разработки процесс Webpack живёт долго:
npm run dev
или:
webpack serve
Изменения происходят постоянно, а memory cache ускоряет incremental rebuild.
Пример:
Первая сборка: 12 секунд
Повторная сборка: 300 мс
webpack --watch
Webpack отслеживает изменения файлов и пересобирает только изменённые модули.
Memory cache хранит:
При HMR происходит частичная замена модулей без полной перезагрузки приложения.
Memory cache здесь критически важен, потому что:
Настройка:
module.exports = {
cache: {
type: 'memory'
}
};
означает:
Webpack 5 автоматически использует memory cache в development mode.
Эквивалентно:
module.exports = {
mode: 'development',
cache: {
type: 'memory'
}
};
В production режиме кэш часто отключён или используется filesystem cache.
Внутри Webpack кэшируются разные сущности.
Webpack хранит:
Пример:
module.exports = {
module: {
rules: [
{
test: /\.js$/,
use: 'babel-loader'
}
]
}
};
babel-loader — дорогая операция.
Memory cache сохраняет результат трансформации:
ESNext → ES5
Повторная обработка не требуется.
Webpack активно использует resolver:
import Button from '@/components/Button';
Разрешение путей:
Результаты также кэшируются.
Chunk graph строится дорого.
Memory cache хранит:
Ключевая задача любого кэша — корректная инвалидизация.
Webpack отслеживает:
Если модуль изменился:
src/utils.js
Webpack пересобирает:
Остальная часть кэша остаётся валидной.
Memory cache тесно связан с incremental compilation.
Пример:
1000 модулей
Изменился один файл:
src/Button.js
Без кэша:
1000 модулей пересобираются
С memory cache:
Пересобирается только dependency subtree
Это фундамент высокой скорости Webpack Dev Server.
Memory cache ускоряет сборку ценой увеличения RAM usage.
Крупные проекты могут занимать:
1–4 GB RAM
Иногда больше.
Особенно при использовании:
Memory cache очищается автоматически:
Процесс завершён → кэш уничтожен
Например:
CTRL + C
или:
kill node
Также кэш пересоздаётся после:
module.exports = {
cache: {
type: 'memory'
}
};
module.exports = {
cache: false
};
Такой режим полезен:
Многие loader’ы имеют собственный уровень кэширования.
Пример:
{
loader: 'babel-loader',
options: {
cacheDirectory: true
}
}
Здесь возникает два уровня кэша:
Трансформированный JS
Compilation results
Совместное использование даёт максимальное ускорение.
Пример:
{
test: /\.js$/,
use: [
'thread-loader',
'babel-loader'
]
}
thread-loader создаёт worker pool.
Memory cache уменьшает необходимость повторной работы потоков.
Без кэша:
Потоки постоянно заново компилируют модули
С кэшем:
Многие результаты извлекаются мгновенно
Source maps значительно увеличивают объём кэшируемых данных.
Особенно:
devtool: 'source-map'
или:
devtool: 'inline-source-map'
Поскольку Webpack хранит:
Это может резко увеличить потребление памяти.
При недостатке RAM возможны проблемы:
Типичная ошибка:
JavaScript heap out of memory
Node.js позволяет увеличить память:
node --max-old-space-size=4096 node_modules/webpack/bin/webpack.js
4096:
4 GB RAM
Для крупных monorepo это часто обязательно.
Memory cache напрямую зависит от GC V8.
При больших объёмах кэша:
Иногда слишком большой memory cache ухудшает производительность.
devtool: 'inline-source-map'
10k+ modules
preset-env
polyfills
typescript
decorators
sass-loader
postcss-loader
css-loader
Webpack 5 позволяет комбинировать memory cache с filesystem cache.
Filesystem cache хранит данные между перезапусками, а memory cache ускоряет текущий runtime.
Внутри одного dev server возможна схема:
Disk cache → RAM cache → Compilation
Webpack 5 использует snapshot system для определения валидности кэша.
Snapshot хранит:
Если snapshot совпадает:
Кэш считается валидным
Webpack отслеживает зависимости сборки.
Например:
module.exports = {
cache: {
buildDependencies: {
config: [__filename]
}
}
};
Если изменится webpack.config.js:
Кэш инвалидируется
Webpack считает некоторые директории стабильными.
Например:
node_modules
Это уменьшает количество проверок.
Настройка:
module.exports = {
snapshot: {
managedPaths: [
/node_modules/
]
}
};
Некоторые пути можно считать полностью неизменяемыми.
Пример:
module.exports = {
snapshot: {
immutablePaths: [
path.resolve(__dirname, 'vendor')
]
}
};
Webpack перестаёт проверять их содержимое.
Development mode максимально ориентирован на скорость rebuild.
Webpack:
Production build обычно запускается:
Один раз
Поэтому memory cache менее полезен.
Пример:
webpack --mode production
После завершения процесса кэш исчезнет.
Для production чаще используется filesystem cache.
В CI memory cache почти бесполезен:
Процесс стартует → build → процесс завершается
RAM cache не успевает принести выгоду.
Лучше использовать:
cache: {
type: 'filesystem'
}
Для анализа производительности используются:
webpack --profile
и:
node --inspect
Также полезны:
< 1 секунды
Без постоянного роста памяти.
Изменение одного файла не вызывает full rebuild.
memory leak
Несмотря на cache.
Webpack не может переиспользовать кэш.
[GC] Mark-sweep ...
в консоли Node.js.
const path = require('path');
module.exports = {
mode: 'development',
cache: {
type: 'memory'
},
devtool: 'eval-cheap-module-source-map',
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
cacheDirectory: true
}
}
}
]
},
resolve: {
extensions: ['.js']
}
};
Особенности:
module.exports = {
cache: {
type: 'memory'
},
parallelism: 50,
snapshot: {
managedPaths: [
/node_modules/
]
},
infrastructureLogging: {
level: 'warn'
}
};
File change
↓
Read file
↓
Parse
↓
Loader execution
↓
AST transform
↓
Dependency analysis
↓
Chunk rebuild
↓
Emit
File change
↓
Invalidate affected module
↓
Reuse cached graph
↓
Reuse cached loaders
↓
Partial rebuild
↓
Emit
Разница во времени может составлять десятки раз.
Webpack использует:
CacheFacade;MemoryCachePlugin;Многие внутренние сущности сериализуются и переиспользуются между этапами compilation pipeline.
npm run dev
↓
stop
↓
start again
↓
cache empty
Очень крупные проекты могут упираться в память.
Иногда баг проявляется только без кэша.
Из-за короткого жизненного цикла процессов.
Особенно:
Где rebuild должен быть почти мгновенным.
При постоянных изменениях файлов.
Если процесс Webpack работает длительное время.
Filesystem cache снижает давление на память.
Memory cache особенно эффективен вместе с:
thread-loader;babel-loader cacheDirectory;splitChunks;lazy compilation;managedPaths;persistent filesystem cache;eval-cheap-module-source-map.Совокупный эффект может уменьшить rebuild:
с 15–20 секунд
до 200–500 мс