我需要帮助将以下代码从webpack 3迁移到4。
new webpack.optimize.CommonsChunkPlugin({
minChunks: module => module.context && module.context.indexOf("node_modules") !== -1,
name: "vendor",
chunks: ["main"]
})
我有两个条目文件,并且只希望第一个的依赖项包含在供应商块中。第二个条目的依赖关系应该都保留在自己的包中。
答案 0 :(得分:46)
我们已弃用并删除了CommonsChunkPlugin,并已更换 它有一组默认值和易于覆盖的API调用
optimization.splitChunks
。
webpack.optimize.CommonsChunkPlugin has been removed,
please use config.optimization.splitChunks instead.
您不再需要使用这些插件:
DedupePlugin has been removed too in v4
NoEmitOnErrorsPlugin - > optimization.noEmitOnErrors(默认情况下在生产模式下启用) ModuleConcatenationPlugin - > optimization.concatenateModules(在prod模式下默认为on) NamedModulesPlugin - > optimization.namedModules(默认情况下在开发模式下启用)
使用mini-css-extract-plugin
代替text-extract-plugin
。
使用webpack-bundle-analyzer
以图形方式分析捆绑的输出。
条目脚本是您应用程序的真正“入门脚本”,不要将供应商文件明确添加到entry:
中的webpack.config.js
。
SPA应用程序只有一个条目,而经典ASP.NET MVC
应用程序等多页应用程序有多个入口点。 Webpack将根据您的条目脚本构建一个依赖图,并为您的应用生成优化的捆绑包。
如果您想从较旧的网络包版本迁移,最好结帐migration guide
树摇动(死代码消除)仅在生产模式下启用。
Webpack 4,捆绑资产的新方式
(你必须从头脑中删除你的CommonsChunkPlugin )
!!! Meanwhile the webpack doc has been updated,
a section SplitChunks
was added !!!
默认情况下,Webpack 4现在会自动进行优化。它根据以下条件分析您的依赖关系图并创建最佳的包(输出):
- 可以共享新块或者来自node_modules文件夹的模块
- 新块将大于30kb(在min + gz之前)
- 按需加载块时的最大并行请求数< = 5
- 初始页面加载时的最大并行请求数< = 3
醇>
所有这一切都可以使用SplitChunksPlugin进行调整! (see SplitChunksPlugin documentation)
A more detailed explanation了解如何使用新的optimization.splitChunks
API。
CommonsChunkPlugin已删除,因为它存在很多问题:
SplitChunksPlugin还有一些很棒的属性:
关于您的问题,您希望将entry1和entry2的所有deps拆分为单独的包。
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
}
}
}
您可以将optimization.splitChunks.cacheGroups。默认设置为false以禁用默认缓存组,对于供应商缓存组也是如此!< / p>
<小时/> 可以找到
SplitChunksOptions
,CachGroupOptions
和Optimization
的最新界面实现here。
下面的界面定义可能不是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's 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's 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 don’t 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;
}
}
答案 1 :(得分:5)
我有两个条目文件,并且只希望第一个的依赖项包含在供应商块中。第二个条目的依赖关系应该都保留在自己的包中。
假设您的入口点为main
和secondary
:
entry: {
main: 'path-to/main.js',
secondary: 'path-to/secondary.js'
}
使用webpack-4您只能从vendors
块中提取main
模块,但使用secondary
将test
中引用的其他第三方模块留在该块中1}}您要创建的功能。
cacheGroups
答案 2 :(得分:2)
我花了一些时间来弄明白,但对我而言,关键的实现是webpack 4中的chunks
参数现在需要一个函数,它允许您只包含一个特定的条目。我假设这是最近的更改,因为在发布时它不在官方文档中。
splitChunks: {
cacheGroups: {
vendor: {
name: 'vendor',
chunks: chunk => chunk.name == 'main',
reuseExistingChunk: true,
priority: 1,
test: module =>
/[\\/]node_modules[\\/]/.test(module.context),
minChunks: 1,
minSize: 0,
},
},
},
答案 3 :(得分:0)
请注意,我通过在webpack.common.js中进行更改来解决了该问题:
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: ['vendor']
})
]
对此:
optimization: {
runtimeChunk: "single", // enable "runtime" chunk
splitChunks: {
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: "vendor",
chunks: "all"
}
}
}
},