webpack工程化03(提取公共代码)
模块化开发过程中,或多或少都会有一些公共代码。而这些重复性的代码往往会增加冗余,降低页面的加载速度。
举个例子:比如说一个网站的菜单,我们把它封装成一个menu组件,那么我们之后的每个页面使用menu组件的时候都需要重新下载,这明显是不合理的(单页面只会下载一次)。
所以我们很有必要来解决这个问题。
在webpack中有一个插件,叫CommonsChunkPlugin。
options中的参数一般有这几个取值:
1.name or names 可以是已经存在的chunk(一般指入口文件)对应的name,那么就会把公共模块代码合并到这个chunk上;否则,会创建名字为name的commons chunk进行合并
2.filename 指定commons chunk的文件名
3.minChunks 可以是数字(对出现多少次以上的代码进行提取),函数(可自定义提取逻辑)和特殊值(Infinity 不会打包任何模块,具体看下文)
4.chunks 指定提取代码的范围
我们来看看具体的例子。创建如下的4个文件,app中依赖childA,childB模块,而childA,childB模块又同时依赖common模块
//app.js
import './childA'
import './childB'
export default 'app'
//childA.js
import './common'
export default 'childA'
//childB.js
import './common'
export default 'childB'
//common.js
export default 'common'
const path = require('path')
const Webpack = require('webpack')
module.exports = {
entry: {
'app': './app.js'
},
output: {
path: path.resolve(__dirname, './dist'),
filename: '[name].bundle.js'
},
plugins: [
new
Webpack.optimize.CommonsChunkPlugin({
name: 'common',
minChunks: 2
})
]
}
因为CommonsChunkPlugin是webpack的插件,所以使用之前需要先安装一下webpack
npm install webpack@3.10.0 -D
打包之后可以看到生成了两个文件,common中只有webpack生成的一些代码,并没有公共的模块
这是因为CommonsChunkPlugin插件需要对多入口生效。我们做一点修改,再加一个入口page
//page.js
import './childA'
import './childB'
export default 'page'
const path = require('path')
const Webpack = require('webpack')
module.exports = {
entry: {
'app': './app.js',
'page': './page.js'
},
output: {
path: path.resolve(__dirname, './dist'),
filename: '[name].bundle.js',
chunkFilename: '[name].chunk.js'
},
plugins: [
new Webpack.optimize.CommonsChunkPlugin({
name: 'common',
minChunks: 2
})
]
}
再打包一下,我们可以看到生成了3个文件。
现在common中就已经把公共代码提取出来了。
接下去我们再看一下第三方依赖的情况该怎么处理。
比如我们再app.js文件中引入jquery,再重新打包一下,文件变成了200多KB。
//app.js
import './childA'
import './childB'
import $ from 'jquery'
export default 'app'
我们修改一下配置,再打包一下,可以看到第三方依赖就被我们单独打包出来了。
plugins: [
new Webpack.optimize.CommonsChunkPlugin({
name: 'vender',
minChunks: Infinity
})
]
但是我们可能还想单独打包出webpack生成的代码,和模块之前的公共代码。我们再修改一下配置,重新打包一下。
plugins: [
new Webpack.optimize.CommonsChunkPlugin({
name: 'common',
minChunks: 2,
chunks: ['app', 'page']
}),
new Webpack.optimize.CommonsChunkPlugin({
name: 'vender',
minChunks: Infinity
}),
new Webpack.optimize.CommonsChunkPlugin({
name: 'manifest',
minChunks: Infinity
})
]
我们之前说过,minChunks还可以是函数,我们再把配置文件改一下,用函数来进行打包,打包的结果是一样的。
entry: {
'app': './app.js',
'page': './page.js'
}
plugins: [
new Webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks (module) {
return module.resource && (/jquery/).test(module.resource);
}
}),
new Webpack.optimize.CommonsChunkPlugin({
name: 'common',
minChunks: 2,
chunks: ['app', 'page']
}),
new Webpack.optimize.CommonsChunkPlugin({
name: 'manifest',
minChunks: Infinity
})
]
除了插件提取公共代码,
想要知道更多详细的信息,大家可以看看官方文档。
但是.....
在webpack4中,CommonsChunkPlugin已经不支持了,替代它的是一个叫SplitChunksPlugin的插件,惊不惊喜,意不意外。(以后有机会还是会讲的哈)