模塊化開發(fā)過程中,或多或少都會有一些公共代碼。而這些重復性的代碼往往會增加冗余,降低頁面的加載速度。
舉個例子:比如說一個網(wǎng)站的菜單,我們把它封裝成一個menu組件,那么我們之后的每個頁面使用menu組件的時候都需要重新下載,這明顯是不合理的(單頁面只會下載一次)。
所以我們很有必要來解決這個問題。
在webpack中有一個插件,叫CommonsChunkPlugin。

options中的參數(shù)一般有這幾個取值:
1.name or names 可以是已經(jīng)存在的chunk(一般指入口文件)對應(yīng)的name,那么就會把公共模塊代碼合并到這個chunk上;否則,會創(chuàng)建名字為name的commons chunk進行合并
2.filename 指定commons chunk的文件名
3.minChunks 可以是數(shù)字(對出現(xiàn)多少次以上的代碼進行提取),函數(shù)(可自定義提取邏輯)和特殊值(Infinity 不會打包任何模塊,具體看下文)
4.chunks 指定提取代碼的范圍
我們來看看具體的例子。創(chuàng)建如下的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個文件。

現(xiàn)在common中就已經(jīng)把公共代碼提取出來了。

接下去我們再看一下第三方依賴的情況該怎么處理。
比如我們再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還可以是函數(shù),我們再把配置文件改一下,用函數(shù)來進行打包,打包的結(jié)果是一樣的。
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已經(jīng)不支持了,替代它的是一個叫SplitChunksPlugin的插件,驚不驚喜,意不意外。(以后有機會還是會講的哈)