
我们知道 Webpack 是一款打包工具,但现在为什么又要进行代码分割呢?
如果把所有代码都打包到一起,可能最终的代码非常大。从而影响加载时间。
而且,很多代码是初始加载时,不需要的。因此,我们可以根据代码使用的紧急程度,将代码分割打包后,按需加载。
例如:打包后的 bundle.js 中,可能包含多个页面的 js

但是,加载首页(index.js)时,我们不需要加载 about.js。此时,我们就可以进行代码分割。

Webpack 中进行代码分割的方式有三个:
多入口打包:配置 entry 加载多个入口文件
提取公用模块:optimization.splitChunks.chunks: all
动态导入:按需加载 | 预加载
将 entry 配置为对象的形式
// webpack.config.js
module.exports = (env, argv) => {
// ......
// 单入口文件
// entry: './src/index.js',
// 多入口打包
entry: {
'index': './src/index.js',
'about': './src/about.js'
},
}
修改输出文件名
如果输出文件名称写成固定的,最后会生成一个文件,就失去了代码分割的意义。
// webpack.config.js
module.exports = (env, argv) => {
// ......
// 出口配置
output: {
// 输出目录(输出目录必须是绝对路径)
path: resolve(__dirname, 'output'),
// 单入口输出文件名称
// filename: 'bundle.js'
// 多入口输出文件名称
filename: '[name].bundle.js'
},
}
不同页面(模板)加载各自的 bundle
在 HtmlWebpackPlugin 中指定 chunks 配置,表明 index.html 中加载 index.bundle.js,about.html 中加载 about.bundle.js。 如果不指定 chunks,所有页面默认加载 bundle.js
// webpack.config.js
module.exports = (env, argv) => {
// ......
// 插件配置
plugins: [
// Html 的配置
new HtmlWebpackPlugin({
// 指定打包后的文件名称
filename: 'index.html',
// 用来指定,生成 HTML 的模板
template: './src/index.ejs',
// 指定要加载的打包文件 - index.bundle.js
chunks: ['index']
}),
new HtmlWebpackPlugin({
// 指定打包后的文件名称
filename: 'about.html',
// 用来指定,生成 HTML 的模板
template: './src/index.ejs',
// 指定要加载的打包文件 - about.bundle.js
chunks: ['about']
}),
]
}
提取原理(为什么提取)
如果多个页面都用到了一个公共文件(例如:jQuery),每个页面都将公共文件打包一次是不合理的。
如果有 100 个页面,将 jQuery 重复打包 100 次,肯定是不合理的。

更好的办法是将公共文件提取出来。
这样,不管有多少个页面,我们只需要打包一次 jQuery 就可以了。(减少了打包体积,提高了打包效率)

具体配置
// webpack.config.js
module.exports = (env, argv) => {
// ......
// 优化策略
optimization: {
// 将所有公共模块单独打包
splitChunks: {
chunks: 'all'
}
},
}
配置完成后,再次执行打包,可以在输出目录看到单独打包的文件。
动态导入可以通过 import 函数来实现,常用的配置有两个内容:
懒加载
默认不加载,事件触发后才加载
webpackChunkName: '打包后的文件名称'
预加载
先等待其他资源加载,浏览器空闲时,在加载不紧急的资源
webpackPrefetch: true
缺点:在移动端有兼容性问题(建议:实际测试后,再酌情使用)
代码示例:
声明模块
// wp.js
// 判断模块是否加载
console.log('模块加载了')
export function desc() {
return "Webpack 是一款前端打包工具"
}
通过 import 引入模块
// index.js
// 验证按需加载
document.getElementById('btn').onclick = function() {
// import 启动懒加载
// webpackChunkName: 'desc' 指定懒加载的文件名称
// webpackPrefetch: true 启动预加载
import(/* webpackChunkName: 'desc', webpackPrefetch: true */'./wp').then(({ desc }) => {
alert(desc())
})
}
再浏览器查看效果
打开 console,通过点击按钮,查看懒加载效果。
打开 network,查看预加载效果