Webpack 4 SplitChunks插件多入口拆分后如何引用特定文件?
我当前使用Webpack的SplitChunks插件做了如下配置:
{ entry: { entry1: [entry1.js], entry2: [entry2.js], entry3: [entry3.js], ... }, optimization: { splitChunks: { chunks: "all" } } }打包后代码被拆分为这些文件:
vendors-entry1-entry2-entry3.js(所有入口共用的依赖)vendors-entry1-entry3.js(仅entry1和entry3共用的依赖)entry1-entry2.js(entry1和entry2的公共代码)entry1.js、entry2.js、entry3.js(各入口独有代码)
想请教:该如何引用这些拆分出来的特定文件?
嘿,针对这个问题,我整理了几个实用的方案,你可以根据自己的场景选择:
1. 让Webpack自动管理(最省心)
最简单的方式是借助Webpack的runtimeChunk功能,让它自动帮你处理所有chunk的加载顺序和引用。只需要在optimization里加一行配置:
optimization: { splitChunks: { chunks: "all" }, runtimeChunk: 'single' // 生成单独的runtime文件 }
之后你只需要在HTML里先引入这个runtime文件,再引入对应的入口文件(比如entry1.js),Webpack会自动识别并加载它依赖的所有拆分chunk——包括那些共用的vendors和公共代码文件,完全不用你手动操心顺序。
2. 用html-webpack-plugin自动生成HTML引用(生产环境首选)
这是前端项目里最常用的方案,html-webpack-plugin会自动分析打包后的所有chunk依赖关系,然后在生成的HTML文件里自动插入正确顺序的<script>标签。
首先安装插件,然后在Webpack配置里添加:
const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { // 你的entry、optimization配置... plugins: [ // 为entry1生成对应的HTML文件 new HtmlWebpackPlugin({ filename: 'entry1.html', chunks: ['entry1'] // 指定只包含entry1相关的所有chunk }), // 同理为entry2、entry3生成对应HTML new HtmlWebpackPlugin({ filename: 'entry2.html', chunks: ['entry2'] }), new HtmlWebpackPlugin({ filename: 'entry3.html', chunks: ['entry3'] }) ] };
这样生成的每个HTML文件里,都会自动包含该入口需要的所有拆分chunk的引用,哪怕后续调整SplitChunks配置导致文件名或依赖变化,插件也会自动更新引用,非常省心。
3. 手动在HTML里引用(不推荐)
如果你一定要手动引用特定文件,必须严格按照依赖顺序加载:先加载最基础的公共依赖,再加载层级高的共用代码,最后加载入口独有文件。比如加载entry1的顺序应该是:
vendors-entry1-entry2-entry3.js(所有入口共用的基础依赖)vendors-entry1-entry3.js(entry1和entry3的共用依赖)entry1-entry2.js(entry1和entry2的公共代码)entry1.js(entry1的独有代码)
不过这种方式维护成本极高,一旦你调整了SplitChunks配置或者依赖关系,就得手动修改HTML里的引用顺序和文件名,所以除非特殊场景,不建议这么做。
4. 生成清单文件用于自定义引用
如果需要在服务端逻辑或者自己的业务代码里动态引用这些chunk,可以用webpack-manifest-plugin生成一个manifest.json清单文件,里面记录了所有chunk的原始名称和打包后的哈希文件名。
配置示例:
const { WebpackManifestPlugin } = require('webpack-manifest-plugin'); module.exports = { // 其他配置... plugins: [ new WebpackManifestPlugin() ] };
生成的manifest.json大概长这样:
{ "entry1.js": "entry1.abc123.js", "vendors-entry1-entry2-entry3.js": "vendors-entry1-entry2-entry3.def456.js", // ...其他chunk的映射关系 }
之后你就可以读取这个JSON文件,根据需求获取对应的chunk文件名来进行引用。
内容的提问来源于stack exchange,提问作者Daniel

