commons-chunk-plugin 使用方法
1、commons-chunk-plugin概述
CommonsChunkPlugin提取代码中的公共模块,然后将公共模块打包到一个独立的文件中,也可以将第三方模块分开打包,以便在其他的入口和模块中使用。需要在html中单独引入抽离出来的公共模块。
2、commons-chunk-plugin配置参数
{
name: string, // or
names: string[],
// 这是 common chunk 的名称。已经存在的 chunk 可以通过传入一个已存在的 chunk 名称而被选择。
// 如果一个字符串数组被传入,这相当于插件针对每个 chunk 名被多次调用
// 如果该选项被忽略,同时 `options.async` 或者 `options.children` 被设置,所有的 chunk 都会被使用,否则 `options.filename` 会用于作为 chunk 名。
filename: string,
// common chunk 的文件名模板。可以包含与 `output.filename` 相同的占位符。
// 如果被忽略,原本的文件名不会被修改(通常是 `output.filename` 或者 `output.chunkFilename`)
minChunks: number|Infinity|function(module, count) -> boolean,
// 在传入 公共chunk(commons chunk) 之前所需要包含的最少数量的 chunks 。
// 数量必须大于等于2,或者少于等于 chunks的数量
// 传入 `Infinity` 会马上生成 公共chunk,但里面没有模块。
// 你可以传入一个 `function` ,以添加定制的逻辑(默认是 chunk 的数量)
chunks: string[],
// 通过 chunk name 去选择 chunks 的来源。chunk 必须是 公共chunk 的子模块。
// 如果被忽略,所有的,所有的 入口chunk (entry chunk) 都会被选择。
children: boolean,
// 如果设置为 `true`,所有 公共chunk 的子模块都会被选择
async: boolean|string,
// 如果设置为 `true`,一个异步的 公共chunk 会作为 `options.name` 的子模块,和 `options.chunks` 的兄弟模块被创建。
// 它会与 `options.chunks` 并行被加载。可以通过提供想要的字符串,而不是 `true` 来对输出的文件进行更换名称。
minSize: number,
// 在 公共chunk 被创建立之前,所有 公共模块 (common module) 的最少大小。
}
3、commons-chunk-plugin打包情况及对应代码分析
公共代码:
//chunk1.js
import Chunk2 from './chunk2';
export default (ctx) => {
console.log('我是chunk1');
//chunk2.js
export default (ctx) => {
console.log('我是chunk2')
}
//index1.html
import Vue from 'vue';
import VueRouter from 'vue-router';
import Chunk1 from './component/chunk1';
import Chunk2 from './component/chunk2';
//index2.html
import Vue from 'vue';
import VueRouter from 'vue-router';
import Chunk1 from './component/chunk1';
import Chunk2 from './component/chunk2';
3-1、单入口文件时候不能把引用多次的模块打印到commonChunkPlugin中。
//webpack.config.js单入口文件配置代码
var webpack = require('webpack')
var path = require('path')
module.exports = {
entry: {
index1: path.resolve(__dirname, 'src/index1.js')
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].js'
},
module: {
rules: [{
test: /\.js$/,
exclude: /node_modules|vue\/dist/,
loader: 'babel-loader'
}]
},
resolve: {
extensions: ['.js', '.vue']
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: 'commons'
})
]
}
打包结果:commons.js里面并没有打入什么东西,但在引入的时候commons.js必须先于index1.js引入。
3-2、多入口文件时候能把引用多次的模块打印到commonChunkPlugin中。
//webpack.config.js单入口文件配置代码,并minChunks:2
var webpack = require('webpack')
var path = require('path')
module.exports = {
entry: {
index1: path.resolve(__dirname, 'src/index1.js'),
index2: path.resolve(__dirname, 'src/index2.js'),
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].js'
},
module: {
rules: [{
test: /\.js$/,
exclude: /node_modules|vue\/dist/,
loader: 'babel-loader'
}]
},
resolve: {
extensions: ['.js', '.vue']
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: 'commons',
minChunks: 2
})
]
}
打包结果:两个入口文件中都引入了的chunk1和chunk2都已打包到了commons.js中。
3-3、将公共业务模块与类库或框架分开打包。
//webpack.config.js将公共业务模块与类库或框架分开打包
var webpack = require('webpack')
var path = require('path')
module.exports = {
entry: {
index1: path.resolve(__dirname, 'src/index1.js'),
index2: path.resolve(__dirname, 'src/index2.js'),
common1:["vue"],
common2:["vue-router"]
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].js'
},
module: {
rules: [{
test: /\.js$/,
exclude: /node_modules|vue\/dist/,
loader: 'babel-loader'
}]
},
resolve: {
extensions: ['.js', '.vue']
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: ["commons",'common1','common2'],//对应于上面的entry的key
minChunks:2
})
]
}
打包结果:vue,vue-router分别打包到一个独立的commons中,分别为common1.js,common2.js。同时把index1,index2的公共业务模块打包到commons.js中,而其他非公共的业务代码全部保留在index1.js和index2.js中。
3-4、参数minChunks: Infinity
//webpack.config.js 参数minChunks: Infinity
var webpack = require('webpack')
var path = require('path')
module.exports = {
entry: {
index1: path.resolve(__dirname, 'src/index1.js'),
index2: path.resolve(__dirname, 'src/index2.js'),
common1:["vue"]
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].js'
},
module: {
rules: [{
test: /\.js$/,
exclude: /node_modules|vue\/dist/,
loader: 'babel-loader'
}]
},
resolve: {
extensions: ['.js', '.vue']
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: ["vue"],//对应于上面的entry的key
minChunks:Infinity
})
]
}
打包结果:如果把minChunks修改为Infinity,那么index1和index2(公有的业务逻辑部分)都打包到index1.js,index2.js里,也就是共有逻辑不会抽取出来作为一个单独的commons。第三方库vue打包到vue.js中,vue.js包含webpack生成的在浏览器上使用各个块的加载代码,所以页面上使用的时候vue.js必须最先加载。
3-5、参数chunks
//webpack.config.js 添加参数chunks
var webpack = require('webpack')
var path = require('path')
module.exports = {
entry: {
index1: path.resolve(__dirname, 'src/index1.js'),
index2: path.resolve(__dirname, 'src/index2.js')
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].js'
},
module: {
rules: [{
test: /\.js$/,
exclude: /node_modules|vue\/dist/,
loader: 'babel-loader'
}]
},
resolve: {
extensions: ['.js', '.vue']
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: "commons",//对应于上面的entry的key
minChunks:2,
chunks:["index1","index2"]
})
]
}
打包结果:只有在index1.js和index2.js中都引用的模块才会被打包的到公共模块。
4、注意点
4-1、webpack用插件CommonsChunkPlugin进行打包的时候,将符合引用次数(minChunks)的模块打包到name参数的数组的第一个块里(chunk),然后数组后面的块依次打包(查找entry里的key,没有找到相关的key就生成一个空的块),最后一个块包含webpack生成的在浏览器上使用各个块的加载代码,所以页面上使用的时候最后一个块必须最先加载。