下面我将详细讲解“webpack优化之代码分割与公共代码提取详解”的完整攻略。
什么是代码分割
代码分割可以让我们把代码分割成更小的块,然后按需加载。这样做的好处是:
- 减少首次加载时间,加速页面呈现。
- 减少代码的重复加载,减少总代码量,提升性能。
- 优化代码加载策略,按需加载不常用的模块,减少负担。
如何进行代码分割
Webpack提供了多种代码分割的方法:
方法一:使用entry
配置(推荐)
entry: {
index: './src/index.js',
about: './src/about.js'
}
直接在entry
配置属性中定义多个入口,Webpack会自动为每个入口文件生成一个相应的chunk。
方法二:使用require.ensure
方法
require.ensure
方法可以将代码分割成多个chunk,提供了更加灵活的语法糖。
require.ensure([], function(require){
var about = require('./about.js');
about();
}, 'about');
require.ensure
方法支持三个参数,第一个参数是依赖的模块数组,这里可以写入要依赖的模块;第二个参数是回调函数,用于加载完成后的回调;第三个参数是chunk的名称,可以为空,如果不为空,则生成的chunk会以这个名称命名。
公共代码提取
上面的方法虽然可以将代码分割成多个chunk,但是如果多个入口文件之间有公共的模块,就会存在重复加载的问题。这时候,我们可以使用公共代码提取,将公共代码提取出来,单独打包成一个chunk,实现代码复用,减少加载。
Webpack提供了CommonsChunkPlugin
插件,可以将公共代码提取出来。
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: 'common'
})
]
上面的代码定义了一个名为common
的chunk,将所有入口文件中的公共代码提取出来打包成一个单独的chunk。
除此之外,CommonsChunkPlugin
还有其它可配置项,例如:
filename
:生成的chunk的名称。minChunks
:模块被引用的最小次数,默认为2。chunks
:插件处理的chunk的范围,默认处理所有的chunk。
示例说明
// webpack.config.js
const path = require('path');
module.exports = {
entry: {
index: './src/index.js',
about: './src/about.js'
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[chunkhash:8].js'
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: 'common',
minChunks: 2
})
]
};
上面的Webpack配置文件定义了两个入口文件,分别对应了index.js
和about.js
,Webpack会自动将它们分别打包成两个chunk,名称分别为index
和about
。另外还定义了一个名为common
的chunk,用于提取公共代码,当模块被引用的次数>=2时,才会被提取到common
chunk中。
<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Webpack Code Splitting Demo</title>
</head>
<body>
<button id="index-btn">Index</button>
<button id="about-btn">About</button>
<script src="common.eaefa36c.js"></script>
<script src="index.06c5e979.js"></script>
<script src="about.88d33d8f.js"></script>
</body>
</html>
上面的HTML代码是输出的页面,可以看到在body
标签下引用了三个JS文件,分别对应index chunk、about chunk、common chunk。
// index.js
import './common.css';
console.log('index');
const indexBtn = document.querySelector('#index-btn');
indexBtn.addEventListener('click', function(){
// 动态加载about模块
import(/* webpackChunkName: "about" */ './about.js').then(function(about){
about();
});
});
上面的JS代码是index入口文件,其中引用了一个公共的CSS文件common.css
,然后为index-btn
按钮绑定了一个click事件,动态加载about模块。
// about.js
import './common.css';
console.log('about');
export default function(){
alert('about');
}
上面的JS代码是about模块,同样引用了公共的CSS文件common.css
,然后导出了一个默认函数。
在例子中,当用户点击index-btn
按钮时,动态加载了about模块。如果没有进行代码分割,用户第一次访问页面时,会同时下载index.js
和about.js
,增加了页面加载时间和带宽消耗。但是分割后,当用户第一次访问页面时,只会下载index.js
和common.js
,避免了重复下载about.js模块。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:webpack优化之代码分割与公共代码提取详解 - Python技术站