接下来就要使用CommonsChunkPlugin插件
(一)单一入口,模块单一引用,分文件输出,单一入口,模块重复引用,分文件输
main.js代码
require('./static/js/main1.js') require('./static/js/main2.js') console.log('I`m main.js');
webpack.config.js代码
'use strict' const path = require('path'); const webpack = require('webpack') module.exports = { entry:{ main:'./main.js' }, output:{ path: path.resolve(__dirname, './dist'), filename:'bundle.js' }, plugins:[ new webpack.optimize.CommonsChunkPlugin({ name:'app', // ( 公共chunk(commnons chunk) 的名称) filename: "app.js", // ( 公共chunk 的文件名) }) ] }
输出文件main.js main.js,main1.js,main2.js,都被打包到main.js里
webpackJsonp([0],[ /* 0 */ /***/ (function(module, exports) { var chunk2=2; exports.chunk2=chunk2; console.log('chunk2') /***/ }), /* 1 */ /***/ (function(module, exports, __webpack_require__) { __webpack_require__(2) __webpack_require__(0) console.log('I`m main.js'); /***/ }), /* 2 */ /***/ (function(module, exports, __webpack_require__) { __webpack_require__(0); var chunk1=1; exports.chunk1=chunk1; console.log('chunk1') /***/ }) ],[1]);
单一入口,模块单一引用,分文件输出和单一入口,模块重复引用,分文件输是一样的
main2.js模块被引用了两次.打包后,所有模块还是被打包到main.js中
(二)多入口,模块重复引用,分文件输出(将多次引用的模块打包到公共模块)
webpack.config.js
'use strict' const path = require('path'); const webpack = require('webpack') module.exports = { entry:{ main:'./main.js', maindemo:'./maindemo.js' }, output:{ path: path.resolve(__dirname, './dist'), filename:'[name].js' }, plugins:[ new webpack.optimize.CommonsChunkPlugin({ name:'app', // ( 公共chunk(commnons chunk) 的名称) //filename: "app.js", // ( 公共chunk 的文件名) minChunks: 2 }) ] }
打包完我们可以看到
app.js中代码
(function(module, exports) { var chunk2=2; exports.chunk2=chunk2; console.log('chunk2') /***/ }), /* 1 */ /***/ (function(module, exports, __webpack_require__) { __webpack_require__(0); var chunk1=1; exports.chunk1=chunk1; console.log('chunk1')
这里把main1.js和main2.js打包到app.js。
这些是基础的使用。接下来看一下项目中的使用
(三)项目中分vendor,manifest,app打包
new webpack.optimize.CommonsChunkPlugin({ name: 'vendor',
minChunks (module,count) { // any required modules inside node_modules are extracted to vendor return ( module.resource && /\.js$/.test(module.resource) && module.resource.indexOf( path.join(__dirname, '../node_modules') ) === 0 ) } }) //提取公共代码 new webpack.optimize.CommonsChunkPlugin({ name: 'manifest', //应当在生成入口 chunk 时,尽量减少入口 chunk 的体积,以提高性能。下述代码块将 //只提取包含 runtime 的 chunk ,其他 chunk 都作为子模块: minChunks: Infinity }), // This instance extracts shared chunks from code splitted chunks and bundles them // in a separate chunk, similar to the vendor chunk // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk new webpack.optimize.CommonsChunkPlugin({ name: 'app', // 如果设置为 `true`,一个异步的 公共chunk 会作为 `options.name` 的子模块,和 `options.chunks` 的兄弟模块被创建。 // 它会与 `options.chunks` 并行被加载。 async: 'vendor-async', children: true,// 如果设置为 `true`,所有 公共chunk 的子模块都会被选择 minChunks: 3 }),
1.其中的 vendor 的chunk 是打包公共组件的代码,分离公共js到vendor中,
声明公共的模块来自node_modules文件夹
minChunks: number|Infinity|function(module, count) -> boolean, // 在传入 公共chunk(commons chunk) 之前所需要包含的最少数量的 chunks 。 // 数量必须大于等于2,或者少于等于 chunks的数量 // 传入 `Infinity` 会马上生成 公共chunk,但里面没有模块。 // 你可以传入一个 `function` ,以添加定制的逻辑(默认是 chunk 的数量)
注:结合长期缓存,你可能需要使用这个插件去避免 公共chunk 改变。 你也需要使用 records
去保持稳定的模块 id,例如,使用 NamedModulesPlugin
或 HashedModuleIdsPlugin
。
2. 上面虽然已经分离了第三方库,每次修改编译都会改变vendor的hash值,导致浏览器缓存失效。原因是vendor包含了webpack在打包过程中会产生一些运行时代码,运行时代码中实际上保存了打包后的文件名。
当修改业务代码时,业务代码的js文件的hash值必然会改变。一旦改变必然会导致vendor变化。vendor变化会导致其hash值变化。
maifest下面主要是将运行时代码提取到单独的manifest文件中,防止其影响vendor.js
注:CommonsChunkPlugin
可以用于将模块分离到单独的文件中。然而 CommonsChunkPlugin
有一个较少有人知道的功能是,能够在每次修改后的构建结果中,将 webpack 的样板(boilerplate)和 manifest 提取出来。通过指定 entry
配置中未用到的名称,此插件会自动将我们需要的内容提取到单独的包中:
注意,引入顺序在这里很重要。CommonsChunkPlugin
的 'vendor'
实例,必须在 'manifest'
实例之前引入。
minChunks
设置为Infinity
这个配置保证没其它的模块会打包进 公共chunk
3.当设置async的意思是:用新的异步加载的额外公共chunk。当下载额外的 chunk 时,它将自动并行下载。