Ответ 1
Начиная с webpack v4 CommonsChunkPlugin устарел.
Мы возражали и удалены CommonsChunkPlugin, и заменили его с набором значений по умолчанию и легко перегружаемых API называется
optimization.splitChunks
.
webpack.optimize.CommonsChunkPlugin has been removed,
please use config.optimization.splitChunks instead.
Устаревшие
Вам больше не нужно использовать эти плагины:
DedupePlugin также был удален в v4
NoEmitOnErrorsPlugin → optim.noEmitOnErrors (по умолчанию в режиме производства) ModuleConcatenationPlugin → optim.concatenateModules (по умолчанию в режиме prod) NamedModulesPlugin → optim.namedModules (по умолчанию в режиме dev)
Рекомендации по webpack 4
Используйте mini-css-extract-plugin
вместо text-extract-plugin
. Используйте webpack-bundle-analyzer
чтобы анализировать собранный результат графически.
Сценарии ввода - это настоящие "Entry-Scripts" для вашего приложения, не добавляйте файлы поставщиков явно для entry:
в webpack.config.js
. Приложения SPA имеют одну запись, а приложения с несколькими страницами, такие как классические приложения ASP.NET MVC
имеют несколько точек входа. Webpack построит график зависимостей из ваших сценариев ввода и создаст оптимизированные пакеты для вашего приложения.
Если вы хотите перейти с более старой версии веб-пакета, лучше всего проверить руководство по миграции
Встряхивание дерева (исключение мертвого кода) разрешено только в режиме производства.
Webpack 4, новый способ связывания активов
(Вы должны удалить мышление CommonsChunkPlugin со своей головы)
!!! Тем временем обновлен webpack doc, добавлен раздел SplitChunks
!!!
Webpack 4 по умолчанию автоматически выполняет оптимизацию. Он анализирует график зависимостей и создает оптимальные пакеты (выходные данные) на основе следующих условий:
- Новый фрагмент может быть разделен или модули из папки node_modules
- Новый кусок будет больше 30 КБ (до min + gz)
- Максимальное количество параллельных запросов при загрузке кусков по запросу <= 5
- Максимальное количество параллельных запросов при начальной загрузке страницы <= 3
Все это можно настроить с помощью SplitChunksPlugin! (см. документацию SplitChunksPlugin)
Более подробное объяснение того, как использовать новый API optimization.splitChunks
.
CommonsChunkPlugin был удален, потому что у него много проблем:
- Это может привести к загрузке большего количества кода, чем требуется.
- Это неэффективно для асинхронных кусков.
- Его сложно использовать.
- Реализация трудно понять.
SplitChunksPlugin также обладает отличными свойствами:
- Он никогда не загружает ненужный модуль (пока вы не применяете слияние chunk через имя)
- Он работает эффективно и в асинхронных кусках
- Его по умолчанию для асинхронных фрагментов
- Он обрабатывает разделение поставщиков с несколькими кусками поставщиков
- Его проще в использовании
- Он не полагается на hack graph hacks
- В основном автоматический
Что касается вашей проблемы, вы хотите разбить все отпечатки entry1 и entry2 на отдельные пакеты.
optimization: {
splitChunks: {
cacheGroups: {
"entry1-bundle": {
test: /.../, // <-- use the test property to specify which deps go here
chunks: "all",
name: "entry1-bundle",
/** Ignore minimum size, minimum chunks and maximum requests and always create chunks for this cache group */
enforce: true,
priority: .. // use the priority, to tell where a shared dep should go
},
"entry2-bundle": {
test: /..../, // <-- use the test property to specify which deps go here
chunks: "all",
name: "entry2-bundle",
enforce: true,
priority: ..
}
}
}
},
Если вы не добавляете оптимизацию: запись splitChunks по умолчанию выглядит следующим образом:
splitChunks: {
chunks: "async",
minSize: 30000,
minChunks: 1,
maxAsyncRequests: 5,
maxInitialRequests: 3,
automaticNameDelimiter: '~',
name: true,
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true
}
}
}
Вы можете установить optim.splitChunks.cacheGroups. по умолчанию false, чтобы отключить группу кеша по умолчанию, то же самое для группы кэшей поставщиков !
Современные реализации интерфейса для
SplitChunksOptions
, CachGroupOptions
и Optimization
можно найти здесь. Определения интерфейса ниже не могут быть на 100% точными, но хороши для простого обзора:
Интерфейс SplitChunksOptions
interface SplitChunksOptions {
/** Select chunks for determining shared modules (defaults to \"async\", \"initial\" and \"all\" requires adding these chunks to the HTML) */
chunks?: "initial" | "async" | "all" | ((chunk: compilation.Chunk) => boolean);
/** Minimal size for the created chunk */
minSize?: number;
/** Minimum number of times a module has to be duplicated until it considered for splitting */
minChunks?: number;
/** Maximum number of requests which are accepted for on-demand loading */
maxAsyncRequests?: number;
/** Maximum number of initial chunks which are accepted for an entry point */
maxInitialRequests?: number;
/** Give chunks created a name (chunks with equal name are merged) */
name?: boolean | string | ((...args: any[]) => any);
/** Assign modules to a cache group (modules from different cache groups are tried to keep in separate chunks) */
cacheGroups?: false | string | ((...args: any[]) => any) | RegExp | { [key: string]: CacheGroupsOptions };
}
Интерфейс CacheGroupsOptions
:
interface CacheGroupsOptions {
/** Assign modules to a cache group */
test?: ((...args: any[]) => boolean) | string | RegExp;
/** Select chunks for determining cache group content (defaults to \"initial\", \"initial\" and \"all\" requires adding these chunks to the HTML) */
chunks?: "initial" | "async" | "all" | ((chunk: compilation.Chunk) => boolean);
/** Ignore minimum size, minimum chunks and maximum requests and always create chunks for this cache group */
enforce?: boolean;
/** Priority of this cache group */
priority?: number;
/** Minimal size for the created chunk */
minSize?: number;
/** Minimum number of times a module has to be duplicated until it considered for splitting */
minChunks?: number;
/** Maximum number of requests which are accepted for on-demand loading */
maxAsyncRequests?: number;
/** Maximum number of initial chunks which are accepted for an entry point */
maxInitialRequests?: number;
/** Try to reuse existing chunk (with name) when it has matching modules */
reuseExistingChunk?: boolean;
/** Give chunks created a name (chunks with equal name are merged) */
name?: boolean | string | ((...args: any[]) => any);
}
Интерфейс Optimization
interface Optimization {
/**
* Modules are removed from chunks when they are already available in all parent chunk groups.
* This reduces asset size. Smaller assets also result in faster builds since less code generation has to be performed.
*/
removeAvailableModules?: boolean;
/** Empty chunks are removed. This reduces load in filesystem and results in faster builds. */
removeEmptyChunks?: boolean;
/** Equal chunks are merged. This results in less code generation and faster builds. */
mergeDuplicateChunks?: boolean;
/** Chunks which are subsets of other chunks are determined and flagged in a way that subsets dont have to be loaded when the bigger chunk has been loaded. */
flagIncludedChunks?: boolean;
/** Give more often used ids smaller (shorter) values. */
occurrenceOrder?: boolean;
/** Determine exports for each module when possible. This information is used by other optimizations or code generation. I. e. to generate more efficient code for export * from. */
providedExports?: boolean;
/**
* Determine used exports for each module. This depends on optimization.providedExports. This information is used by other optimizations or code generation.
* I. e. exports are not generated for unused exports, export names are mangled to single char identifiers when all usages are compatible.
* DCE in minimizers will benefit from this and can remove unused exports.
*/
usedExports?: boolean;
/**
* Recognise the sideEffects flag in package.json or rules to eliminate modules. This depends on optimization.providedExports and optimization.usedExports.
* These dependencies have a cost, but eliminating modules has positive impact on performance because of less code generation. It depends on your codebase.
* Try it for possible performance wins.
*/
sideEffects?: boolean;
/** Tries to find segments of the module graph which can be safely concatenated into a single module. Depends on optimization.providedExports and optimization.usedExports. */
concatenateModules?: boolean;
/** Finds modules which are shared between chunk and splits them into separate chunks to reduce duplication or separate vendor modules from application modules. */
splitChunks?: SplitChunksOptions | false;
/** Create a separate chunk for the webpack runtime code and chunk hash maps. This chunk should be inlined into the HTML */
runtimeChunk?: boolean | "single" | "multiple" | RuntimeChunkOptions;
/** Avoid emitting assets when errors occur. */
noEmitOnErrors?: boolean;
/** Instead of numeric ids, give modules readable names for better debugging. */
namedModules?: boolean;
/** Instead of numeric ids, give chunks readable names for better debugging. */
namedChunks?: boolean;
/** Defines the process.env.NODE_ENV constant to a compile-time-constant value. This allows to remove development only code from code. */
nodeEnv?: string | false;
/** Use the minimizer (optimization.minimizer, by default uglify-js) to minimize output assets. */
minimize?: boolean;
/** Minimizer(s) to use for minimizing the output */
minimizer?: Array<Plugin | Tapable.Plugin>;
/** Generate records with relative paths to be able to move the context folder". */
portableRecords?: boolean;
}
}