建议在github阅读
注意:example1(对应于目录example1,修改webpack.config.js中的配置就可以了,以下例子相同)
虽然在example1中chunk2被引用了两次,但是最终并没有打包到chunk.js中,我们看看chunk.js中的内容:
/******/ (function(modules) { // webpackBootstrap/******/ // install a JSONP callback for chunk loading/******/ var parentJsonpFunction = window["webpackJsonp"];/******/ window["webpackJsonp"] = function webpackJsonpCallback(chunkIds, moreModules) {/******/ // add "moreModules" to the modules object,/******/ // then flag all "chunkIds" as loaded and fire callback/******/ var moduleId, chunkId, i = 0, callbacks = [];/******/ for(;i < chunkIds.length; i++) {/******/ chunkId = chunkIds[i];/******/ if(installedChunks[chunkId])/******/ callbacks.push.apply(callbacks, installedChunks[chunkId]);/******/ installedChunks[chunkId] = 0;/******/ }/******/ for(moduleId in moreModules) {/******/ modules[moduleId] = moreModules[moduleId];/******/ }/******/ if(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules);/******/ while(callbacks.length)/******/ callbacks.shift().call(null, __webpack_require__);/******/ if(moreModules[0]) {/******/ installedModules[0] = 0;/******/ return __webpack_require__(0);/******/ }/******/ };/******/ // The module cache/******/ var installedModules = {};/******/ // object to store loaded and loading chunks/******/ // "0" means "already loaded"/******/ // Array means "loading", array contains callbacks/******/ var installedChunks = {/******/ 1:0/******/ };/******/ // The require function/******/ function __webpack_require__(moduleId) {/******/ // Check if module is in cache/******/ if(installedModules[moduleId])/******/ return installedModules[moduleId].exports;/******/ // Create a new module (and put it into the cache)/******/ var module = installedModules[moduleId] = {/******/ exports: {},/******/ id: moduleId,/******/ loaded: false/******/ };/******/ // Execute the module function/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);/******/ // Flag the module as loaded/******/ module.loaded = true;/******/ // Return the exports of the module/******/ return module.exports;/******/ }/******/ // This file contains only the entry chunk./******/ // The chunk loading function for additional chunks/******/ __webpack_require__.e = function requireEnsure(chunkId, callback) {/******/ // "0" is the signal for "already loaded"/******/ if(installedChunks[chunkId] === 0)/******/ return callback.call(null, __webpack_require__);/******/ // an array means "currently loading"./******/ if(installedChunks[chunkId] !== undefined) {/******/ installedChunks[chunkId].push(callback);/******/ } else {/******/ // start chunk loading/******/ installedChunks[chunkId] = [callback];/******/ var head = document.getElementsByTagName('head')[0];/******/ var script = document.createElement('script');/******/ script.type = 'text/javascript';/******/ script.charset = 'utf-8';/******/ script.async = true;/******/ script.src = __webpack_require__.p + "" + chunkId + "." + ({"0":"main"}[chunkId]||chunkId) + ".js";/******/ head.appendChild(script);/******/ }/******/ };/******/ // expose the modules object (__webpack_modules__)/******/ __webpack_require__.m = modules;/******/ // expose the module cache/******/ __webpack_require__.c = installedModules;/******/ // __webpack_public_path__/******/ __webpack_require__.p = "";/******/ })/************************************************************************//******/ ([]);打包成的main.js中内容是:
webpackJsonp([0,1],[/* 0 *//***/ function(module, exports, __webpack_require__) { __webpack_require__(1); __webpack_require__(2);/***/ },/* 1 *//***/ function(module, exports, __webpack_require__) { __webpack_require__(2); var chunk1=1; exports.chunk1=chunk1;/***/ },/* 2 *//***/ function(module, exports) { var chunk2=1; exports.chunk2=chunk2;/***/ }]);在example2中我们配置了如下:
minChunks:2我们两个入口文件中公有的chunk1.js和chunk2.js被打印到chunk.js中!
/******/ (function(modules) { // webpackBootstrap/******/ // install a JSONP callback for chunk loading/******/ var parentJsonpFunction = window["webpackJsonp"];/******/ window["webpackJsonp"] = function webpackJsonpCallback(chunkIds, moreModules) {/******/ // add "moreModules" to the modules object,/******/ // then flag all "chunkIds" as loaded and fire callback/******/ var moduleId, chunkId, i = 0, callbacks = [];/******/ for(;i < chunkIds.length; i++) {/******/ chunkId = chunkIds[i];/******/ if(installedChunks[chunkId])/******/ callbacks.push.apply(callbacks, installedChunks[chunkId]);/******/ installedChunks[chunkId] = 0;/******/ }/******/ for(moduleId in moreModules) {/******/ modules[moduleId] = moreModules[moduleId];/******/ }/******/ if(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules);/******/ while(callbacks.length)/******/ callbacks.shift().call(null, __webpack_require__);/******/ if(moreModules[0]) {/******/ installedModules[0] = 0;/******/ return __webpack_require__(0);/******/ }/******/ };/******/ // The module cache/******/ var installedModules = {};/******/ // object to store loaded and loading chunks/******/ // "0" means "already loaded"/******/ // Array means "loading", array contains callbacks/******/ var installedChunks = {/******/ 2:0/******/ };/******/ // The require function/******/ function __webpack_require__(moduleId) {/******/ // Check if module is in cache/******/ if(installedModules[moduleId])/******/ return installedModules[moduleId].exports;/******/ // Create a new module (and put it into the cache)/******/ var module = installedModules[moduleId] = {/******/ exports: {},/******/ id: moduleId,/******/ loaded: false/******/ };/******/ // Execute the module function/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);/******/ // Flag the module as loaded/******/ module.loaded = true;/******/ // Return the exports of the module/******/ return module.exports;/******/ }/******/ // This file contains only the entry chunk./******/ // The chunk loading function for additional chunks/******/ __webpack_require__.e = function requireEnsure(chunkId, callback) {/******/ // "0" is the signal for "already loaded"/******/ if(installedChunks[chunkId] === 0)/******/ return callback.call(null, __webpack_require__);/******/ // an array means "currently loading"./******/ if(installedChunks[chunkId] !== undefined) {/******/ installedChunks[chunkId].push(callback);/******/ } else {/******/ // start chunk loading/******/ installedChunks[chunkId] = [callback];/******/ var head = document.getElementsByTagName('head')[0];/******/ var script = document.createElement('script');/******/ script.type = 'text/Javascript';/******/ script.charset = 'utf-8';/******/ script.async = true;/******/ script.src = __webpack_require__.p + "" + chunkId + "." + ({"0":"main","1":"main1"}[chunkId]||chunkId) + ".js";/******/ head.appendChild(script);/******/ }/******/ };/******/ // expose the modules object (__webpack_modules__)/******/ __webpack_require__.m = modules;/******/ // expose the module cache/******/ __webpack_require__.c = installedModules;/******/ // __webpack_public_path__/******/ __webpack_require__.p = "";/******/ })/************************************************************************//******/ ([/* 0 */,/* 1 *//***/ function(module, exports, __webpack_require__) { __webpack_require__(2); var chunk1=1; exports.chunk1=chunk1;/***/ },/* 2 *//***/ function(module, exports) { var chunk2=1; exports.chunk2=chunk2;/***/ }/******/ ]);上面的配置就可以把jquery,vue分别打包到一个独立的chunk中,分别为common1.js,common2.js。同时把main1,main的公共业务模块
打包到chunk.js中,而其他非公共的业务代码全部保留在main.js和main1.js中。
注意:webpack用插件CommonsChunkPlugin进行打包的时候,将符合引用次数(minChunks)
的模块打包到name参数的数组的第一个块里(chunk),然后数组后面的块依次打包(查找entry里的key,没有找到相关的key就生成一个空的块
),最后一个块包含webpack生成的在浏览器上使用各个块的加载代码,所以页面上使用的时候最后一个块必须最先加载,我们看看最后一个块,也就是common2.js的内容头部:
看到这里你就会明白为什么他要最后加载了把。
这样我们的业务共享代码会提取到common.js中,如下:
webpackJsonp([4,5],[//第一个参数是一个数组,数组中第一个元素是该chunkId,而其余元素是该chunk依赖的其他模块/* 0 */,/* 1 */,/* 2 *//***/ function(module, exports, __webpack_require__) { __webpack_require__(3); var chunk1=1; exports.chunk1=chunk1;/***/ },/* 3 *//***/ function(module, exports) { var chunk2=1; exports.chunk2=chunk2;/***/ }]);而我们的load.js中仅仅是用于加载其他chunk代码的函数,所以必须在最后加载才行:
/******/ (function(modules) { // webpackBootstrap/******/ // install a JSONP callback for chunk loading/******/ var parentJsonpFunction = window["webpackJsonp"];/******/ window["webpackJsonp"] = function webpackJsonpCallback(chunkIds, moreModules) {/******/ // add "moreModules" to the modules object,/******/ // then flag all "chunkIds" as loaded and fire callback/******/ var moduleId, chunkId, i = 0, callbacks = [];/******/ for(;i < chunkIds.length; i++) {/******/ chunkId = chunkIds[i];/******/ if(installedChunks[chunkId])/******/ callbacks.push.apply(callbacks, installedChunks[chunkId]);/******/ installedChunks[chunkId] = 0;/******/ }/******/ for(moduleId in moreModules) {/******/ modules[moduleId] = moreModules[moduleId];/******/ }/******/ if(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules);/******/ while(callbacks.length)/******/ callbacks.shift().call(null, __webpack_require__);/******/ if(moreModules[0]) {/******/ installedModules[0] = 0;/******/ return __webpack_require__(0);/******/ }/******/ };/******/ // The module cache/******/ var installedModules = {};/******/ // object to store loaded and loading chunks/******/ // "0" means "already loaded"/******/ // Array means "loading", array contains callbacks/******/ var installedChunks = {/******/ 5:0/******/ };/******/ // The require function/******/ function __webpack_require__(moduleId) {/******/ // Check if module is in cache/******/ if(installedModules[moduleId])/******/ return installedModules[moduleId].exports;/******/ // Create a new module (and put it into the cache)/******/ var module = installedModules[moduleId] = {/******/ exports: {},/******/ id: moduleId,/******/ loaded: false/******/ };/******/ // Execute the module function/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);/******/ // Flag the module as loaded/******/ module.loaded = true;/******/ // Return the exports of the module/******/ return module.exports;/******/ }/******/ // This file contains only the entry chunk./******/ // The chunk loading function for additional chunks/******/ __webpack_require__.e = function requireEnsure(chunkId, callback) {/******/ // "0" is the signal for "already loaded"/******/ if(installedChunks[chunkId] === 0)/******/ return callback.call(null, __webpack_require__);/******/ // an array means "currently loading"./******/ if(installedChunks[chunkId] !== undefined) {/******/ installedChunks[chunkId].push(callback);/******/ } else {/******/ // start chunk loading/******/ installedChunks[chunkId] = [callback];/******/ var head = document.getElementsByTagName('head')[0];/******/ var script = document.createElement('script');/******/ script.type = 'text/javascript';/******/ script.charset = 'utf-8';/******/ script.async = true;/******/ script.src = __webpack_require__.p + "" + chunkId + "." + ({"0":"jquery","1":"main","2":"main1","3":"vue","4":"common"}[chunkId]||chunkId) + ".js";/******/ head.appendChild(script);/******/ }/******/ };/******/ // expose the modules object (__webpack_modules__)/******/ __webpack_require__.m = modules;/******/ // expose the module cache/******/ __webpack_require__.c = installedModules;/******/ // __webpack_public_path__/******/ __webpack_require__.p = "";/******/ })/************************************************************************//******/ ([]);下面的配置会把main.js和main1.js公共的业务代码打包到jquery.js中:
var CommonsChunkPlugin = require("webpack/lib/optimize/CommonsChunkPlugin");module.exports = { entry: { main: process.cwd()+'/example5/main.js', main1: process.cwd()+'/example5/main1.js', jquery:["jquery"] //minChunks: Infinity时候框架代码依然会被单独打包成一个文件 }, output: { path: process.cwd() + '/dest/example5', filename: '[name].js' }, plugins: [ new CommonsChunkPlugin({ name: "jquery", minChunks:2//被引用两次及以上 }) ]};如果把上面的minChunks修改为Infinity,那么chunk1和chunk2(公有的业务逻辑部分,在main.js和main1.js中require进来)都打包到main.js,main1.js里
,也就是共有逻辑不会抽取出来作为一个单独的chunk,而是打包到jquery.js中!注意:此处的jquery必须在最先加载,因为window.webpackJsonp函数是被打包到jquery.js中的!
下面的配置表示:只有在main.js和main1.js中都引用的模块才会被打包的到公共模块(这里即jquery.js)
var CommonsChunkPlugin = require("webpack/lib/optimize/CommonsChunkPlugin");module.exports = { entry: { main: process.cwd()+'/example6/main.js', main1: process.cwd()+'/example6/main1.js', jquery:["jquery"] }, output: { path: process.cwd() + '/dest/example6', filename: '[name].js' }, plugins: [ new CommonsChunkPlugin({ name: "jquery", minChunks:2, chunks:["main","main1"] }) ]};此时你会发现在我们的jquery.js的最后会打包进来我们的chunk1.js和chunk2.js
/* 2 *//***/ function(module, exports, __webpack_require__) { __webpack_require__(3); var chunk1=1; exports.chunk1=chunk1;/***/ },/* 3 *//***/ function(module, exports) { var chunk2=1; exports.chunk2=chunk2;/***/ }参考资料:
webpack打包策略分析
webpack CommonsChunkPlugin详细教程
新闻热点
疑难解答