mirror of https://github.com/webpack/webpack.git
Merge branch 'master' into next
This commit is contained in:
commit
03b0ff2c9c
|
@ -0,0 +1,856 @@
|
|||
This example illustrates how common modules from deep ancestors of an entry point can be split into a seperate common chunk
|
||||
|
||||
* `pageA` and `pageB` are dynamically required
|
||||
* `pageC` and `pageA` both require the `reusableComponent`
|
||||
* `pageB` dynamically requires `PageC`
|
||||
|
||||
You can see that webpack outputs four files/chunks:
|
||||
|
||||
* `output.js` is the entry chunk and contains
|
||||
* the module system
|
||||
* chunk loading logic
|
||||
* the entry point `example.js`
|
||||
* module `reusableComponent`
|
||||
* `0.output.js` is an additional chunk
|
||||
* module `pageC`
|
||||
* `1.output.js` is an additional chunk
|
||||
* module `pageB`
|
||||
* `2.output.js` is an additional chunk
|
||||
* module `pageA`
|
||||
|
||||
|
||||
# example.js
|
||||
|
||||
``` javascript
|
||||
var main = function() {
|
||||
console.log("Main class");
|
||||
require.ensure([], () => {
|
||||
const page = require("./pageA");
|
||||
page();
|
||||
});
|
||||
require.ensure([], () => {
|
||||
const page = require("./pageB");
|
||||
page();
|
||||
});
|
||||
};
|
||||
|
||||
main();
|
||||
```
|
||||
|
||||
# pageA.js
|
||||
|
||||
``` javascript
|
||||
var reusableComponent = require("./reusableComponent");
|
||||
|
||||
module.exports = function() {
|
||||
console.log("Page A");
|
||||
reusableComponent();
|
||||
};
|
||||
```
|
||||
|
||||
# pageB.js
|
||||
|
||||
``` javascript
|
||||
module.exports = function() {
|
||||
console.log("Page B");
|
||||
require.ensure([], ()=>{
|
||||
const page = require("./pageC");
|
||||
page();
|
||||
});
|
||||
};
|
||||
```
|
||||
|
||||
# pageC.js
|
||||
|
||||
``` javascript
|
||||
var reusableComponent = require("./reusableComponent");
|
||||
|
||||
module.exports = function() {
|
||||
console.log("Page C");
|
||||
reusableComponent();
|
||||
};
|
||||
```
|
||||
|
||||
# reusableComponent.js
|
||||
|
||||
``` javascript
|
||||
module.exports = function() {
|
||||
console.log("reusable Component");
|
||||
};
|
||||
```
|
||||
|
||||
# webpack.config.js
|
||||
|
||||
``` javascript
|
||||
"use strict";
|
||||
const webpack = require("../../");
|
||||
const path = require("path");
|
||||
|
||||
module.exports = [
|
||||
{
|
||||
entry: {
|
||||
main: ["./example.js"]
|
||||
},
|
||||
output: {
|
||||
path: path.resolve(__dirname, "js"),
|
||||
filename: "output.js"
|
||||
},
|
||||
plugins: [
|
||||
new webpack.optimize.CommonsChunkPlugin({
|
||||
name: "main",
|
||||
minChunks: 2,
|
||||
children: true,
|
||||
deepChildren: true,
|
||||
})
|
||||
]
|
||||
},
|
||||
{
|
||||
entry: {
|
||||
main: ["./example.js"]
|
||||
},
|
||||
output: {
|
||||
path: path.resolve(__dirname, "js"),
|
||||
filename: "asyncoutput.js"
|
||||
},
|
||||
plugins: [
|
||||
new webpack.optimize.CommonsChunkPlugin({
|
||||
name: "main",
|
||||
minChunks: 2,
|
||||
async: true,
|
||||
children: true,
|
||||
deepChildren: true,
|
||||
})
|
||||
]
|
||||
}
|
||||
];
|
||||
```
|
||||
|
||||
# js/output.js
|
||||
|
||||
<details><summary><code>/******/ (function(modules) { /* webpackBootstrap */ })</code></summary>
|
||||
|
||||
``` javascript
|
||||
/******/ (function(modules) { // webpackBootstrap
|
||||
/******/ // install a JSONP callback for chunk loading
|
||||
/******/ var parentJsonpFunction = window["webpackJsonp"];
|
||||
/******/ window["webpackJsonp"] = function webpackJsonpCallback(chunkIds, moreModules, executeModules) {
|
||||
/******/ // add "moreModules" to the modules object,
|
||||
/******/ // then flag all "chunkIds" as loaded and fire callback
|
||||
/******/ var moduleId, chunkId, i = 0, resolves = [], result;
|
||||
/******/ for(;i < chunkIds.length; i++) {
|
||||
/******/ chunkId = chunkIds[i];
|
||||
/******/ if(installedChunks[chunkId]) {
|
||||
/******/ resolves.push(installedChunks[chunkId][0]);
|
||||
/******/ }
|
||||
/******/ installedChunks[chunkId] = 0;
|
||||
/******/ }
|
||||
/******/ for(moduleId in moreModules) {
|
||||
/******/ if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {
|
||||
/******/ modules[moduleId] = moreModules[moduleId];
|
||||
/******/ }
|
||||
/******/ }
|
||||
/******/ if(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules, executeModules);
|
||||
/******/ while(resolves.length) {
|
||||
/******/ resolves.shift()();
|
||||
/******/ }
|
||||
/******/
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // The module cache
|
||||
/******/ var installedModules = {};
|
||||
/******/
|
||||
/******/ // objects to store loaded and loading chunks
|
||||
/******/ var installedChunks = {
|
||||
/******/ 3: 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] = {
|
||||
/******/ i: moduleId,
|
||||
/******/ l: false,
|
||||
/******/ exports: {}
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // Execute the module function
|
||||
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
||||
/******/
|
||||
/******/ // Flag the module as loaded
|
||||
/******/ module.l = 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) {
|
||||
/******/ var installedChunkData = installedChunks[chunkId];
|
||||
/******/ if(installedChunkData === 0) {
|
||||
/******/ return new Promise(function(resolve) { resolve(); });
|
||||
/******/ }
|
||||
/******/
|
||||
/******/ // a Promise means "currently loading".
|
||||
/******/ if(installedChunkData) {
|
||||
/******/ return installedChunkData[2];
|
||||
/******/ }
|
||||
/******/
|
||||
/******/ // setup Promise in chunk cache
|
||||
/******/ var promise = new Promise(function(resolve, reject) {
|
||||
/******/ installedChunkData = installedChunks[chunkId] = [resolve, reject];
|
||||
/******/ });
|
||||
/******/ installedChunkData[2] = promise;
|
||||
/******/
|
||||
/******/ // start chunk loading
|
||||
/******/ var head = document.getElementsByTagName('head')[0];
|
||||
/******/ var script = document.createElement('script');
|
||||
/******/ script.type = 'text/javascript';
|
||||
/******/ script.charset = 'utf-8';
|
||||
/******/ script.async = true;
|
||||
/******/ script.timeout = 120000;
|
||||
/******/
|
||||
/******/ if (__webpack_require__.nc) {
|
||||
/******/ script.setAttribute("nonce", __webpack_require__.nc);
|
||||
/******/ }
|
||||
/******/ script.src = __webpack_require__.p + "" + chunkId + ".output.js";
|
||||
/******/ var timeout = setTimeout(onScriptComplete, 120000);
|
||||
/******/ script.onerror = script.onload = onScriptComplete;
|
||||
/******/ function onScriptComplete() {
|
||||
/******/ // avoid mem leaks in IE.
|
||||
/******/ script.onerror = script.onload = null;
|
||||
/******/ clearTimeout(timeout);
|
||||
/******/ var chunk = installedChunks[chunkId];
|
||||
/******/ if(chunk !== 0) {
|
||||
/******/ if(chunk) {
|
||||
/******/ chunk[1](new Error('Loading chunk ' + chunkId + ' failed.'));
|
||||
/******/ }
|
||||
/******/ installedChunks[chunkId] = undefined;
|
||||
/******/ }
|
||||
/******/ };
|
||||
/******/ head.appendChild(script);
|
||||
/******/
|
||||
/******/ return promise;
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // expose the modules object (__webpack_modules__)
|
||||
/******/ __webpack_require__.m = modules;
|
||||
/******/
|
||||
/******/ // expose the module cache
|
||||
/******/ __webpack_require__.c = installedModules;
|
||||
/******/
|
||||
/******/ // define getter function for harmony exports
|
||||
/******/ __webpack_require__.d = function(exports, name, getter) {
|
||||
/******/ if(!__webpack_require__.o(exports, name)) {
|
||||
/******/ Object.defineProperty(exports, name, {
|
||||
/******/ configurable: false,
|
||||
/******/ enumerable: true,
|
||||
/******/ get: getter
|
||||
/******/ });
|
||||
/******/ }
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // getDefaultExport function for compatibility with non-harmony modules
|
||||
/******/ __webpack_require__.n = function(module) {
|
||||
/******/ var getter = module && module.__esModule ?
|
||||
/******/ function getDefault() { return module['default']; } :
|
||||
/******/ function getModuleExports() { return module; };
|
||||
/******/ __webpack_require__.d(getter, 'a', getter);
|
||||
/******/ return getter;
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // Object.prototype.hasOwnProperty.call
|
||||
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
|
||||
/******/
|
||||
/******/ // __webpack_public_path__
|
||||
/******/ __webpack_require__.p = "js/";
|
||||
/******/
|
||||
/******/ // on error function for async loading
|
||||
/******/ __webpack_require__.oe = function(err) { console.error(err); throw err; };
|
||||
/******/
|
||||
/******/ // Load entry module and return exports
|
||||
/******/ return __webpack_require__(__webpack_require__.s = 0);
|
||||
/******/ })
|
||||
/************************************************************************/
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
``` javascript
|
||||
/******/ ([
|
||||
/* 0 */
|
||||
/*!**************************!*\
|
||||
!*** multi ./example.js ***!
|
||||
\**************************/
|
||||
/*! no static exports found */
|
||||
/*! all exports used */
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
module.exports = __webpack_require__(/*! ./example.js */1);
|
||||
|
||||
|
||||
/***/ }),
|
||||
/* 1 */
|
||||
/*!********************!*\
|
||||
!*** ./example.js ***!
|
||||
\********************/
|
||||
/*! no static exports found */
|
||||
/*! all exports used */
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
var main = function() {
|
||||
console.log("Main class");
|
||||
__webpack_require__.e/* require.ensure */(2).then((() => {
|
||||
const page = __webpack_require__(/*! ./pageA */ 3);
|
||||
page();
|
||||
}).bind(null, __webpack_require__)).catch(__webpack_require__.oe);
|
||||
__webpack_require__.e/* require.ensure */(1).then((() => {
|
||||
const page = __webpack_require__(/*! ./pageB */ 4);
|
||||
page();
|
||||
}).bind(null, __webpack_require__)).catch(__webpack_require__.oe);
|
||||
};
|
||||
|
||||
main();
|
||||
|
||||
|
||||
/***/ }),
|
||||
/* 2 */
|
||||
/*!******************************!*\
|
||||
!*** ./reusableComponent.js ***!
|
||||
\******************************/
|
||||
/*! no static exports found */
|
||||
/*! all exports used */
|
||||
/***/ (function(module, exports) {
|
||||
|
||||
module.exports = function() {
|
||||
console.log("reusable Component");
|
||||
};
|
||||
|
||||
|
||||
/***/ })
|
||||
/******/ ]);
|
||||
```
|
||||
|
||||
# js/0.output.js
|
||||
|
||||
``` javascript
|
||||
webpackJsonp([0],{
|
||||
|
||||
/***/ 5:
|
||||
/*!******************!*\
|
||||
!*** ./pageC.js ***!
|
||||
\******************/
|
||||
/*! no static exports found */
|
||||
/*! all exports used */
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
var reusableComponent = __webpack_require__(/*! ./reusableComponent */ 2);
|
||||
|
||||
module.exports = function() {
|
||||
console.log("Page C");
|
||||
reusableComponent();
|
||||
};
|
||||
|
||||
|
||||
/***/ })
|
||||
|
||||
});
|
||||
```
|
||||
|
||||
# js/1.output.js
|
||||
|
||||
``` javascript
|
||||
webpackJsonp([1],{
|
||||
|
||||
/***/ 4:
|
||||
/*!******************!*\
|
||||
!*** ./pageB.js ***!
|
||||
\******************/
|
||||
/*! no static exports found */
|
||||
/*! all exports used */
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
module.exports = function() {
|
||||
console.log("Page B");
|
||||
__webpack_require__.e/* require.ensure */(0).then((()=>{
|
||||
const page = __webpack_require__(/*! ./pageC */ 5);
|
||||
page();
|
||||
}).bind(null, __webpack_require__)).catch(__webpack_require__.oe);
|
||||
};
|
||||
|
||||
|
||||
/***/ })
|
||||
|
||||
});
|
||||
```
|
||||
|
||||
# js/2.output.js
|
||||
|
||||
``` javascript
|
||||
webpackJsonp([2],{
|
||||
|
||||
/***/ 3:
|
||||
/*!******************!*\
|
||||
!*** ./pageA.js ***!
|
||||
\******************/
|
||||
/*! no static exports found */
|
||||
/*! all exports used */
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
var reusableComponent = __webpack_require__(/*! ./reusableComponent */ 2);
|
||||
|
||||
module.exports = function() {
|
||||
console.log("Page A");
|
||||
reusableComponent();
|
||||
};
|
||||
|
||||
|
||||
/***/ })
|
||||
|
||||
});
|
||||
```
|
||||
|
||||
# js/asyncoutput.js
|
||||
|
||||
``` javascript
|
||||
/******/ (function(modules) { // webpackBootstrap
|
||||
/******/ // install a JSONP callback for chunk loading
|
||||
/******/ var parentJsonpFunction = window["webpackJsonp"];
|
||||
/******/ window["webpackJsonp"] = function webpackJsonpCallback(chunkIds, moreModules, executeModules) {
|
||||
/******/ // add "moreModules" to the modules object,
|
||||
/******/ // then flag all "chunkIds" as loaded and fire callback
|
||||
/******/ var moduleId, chunkId, i = 0, resolves = [], result;
|
||||
/******/ for(;i < chunkIds.length; i++) {
|
||||
/******/ chunkId = chunkIds[i];
|
||||
/******/ if(installedChunks[chunkId]) {
|
||||
/******/ resolves.push(installedChunks[chunkId][0]);
|
||||
/******/ }
|
||||
/******/ installedChunks[chunkId] = 0;
|
||||
/******/ }
|
||||
/******/ for(moduleId in moreModules) {
|
||||
/******/ if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {
|
||||
/******/ modules[moduleId] = moreModules[moduleId];
|
||||
/******/ }
|
||||
/******/ }
|
||||
/******/ if(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules, executeModules);
|
||||
/******/ while(resolves.length) {
|
||||
/******/ resolves.shift()();
|
||||
/******/ }
|
||||
/******/
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // The module cache
|
||||
/******/ var installedModules = {};
|
||||
/******/
|
||||
/******/ // objects to store loaded and loading chunks
|
||||
/******/ var installedChunks = {
|
||||
/******/ 4: 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] = {
|
||||
/******/ i: moduleId,
|
||||
/******/ l: false,
|
||||
/******/ exports: {}
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // Execute the module function
|
||||
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
||||
/******/
|
||||
/******/ // Flag the module as loaded
|
||||
/******/ module.l = 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) {
|
||||
/******/ var installedChunkData = installedChunks[chunkId];
|
||||
/******/ if(installedChunkData === 0) {
|
||||
/******/ return new Promise(function(resolve) { resolve(); });
|
||||
/******/ }
|
||||
/******/
|
||||
/******/ // a Promise means "currently loading".
|
||||
/******/ if(installedChunkData) {
|
||||
/******/ return installedChunkData[2];
|
||||
/******/ }
|
||||
/******/
|
||||
/******/ // setup Promise in chunk cache
|
||||
/******/ var promise = new Promise(function(resolve, reject) {
|
||||
/******/ installedChunkData = installedChunks[chunkId] = [resolve, reject];
|
||||
/******/ });
|
||||
/******/ installedChunkData[2] = promise;
|
||||
/******/
|
||||
/******/ // start chunk loading
|
||||
/******/ var head = document.getElementsByTagName('head')[0];
|
||||
/******/ var script = document.createElement('script');
|
||||
/******/ script.type = 'text/javascript';
|
||||
/******/ script.charset = 'utf-8';
|
||||
/******/ script.async = true;
|
||||
/******/ script.timeout = 120000;
|
||||
/******/
|
||||
/******/ if (__webpack_require__.nc) {
|
||||
/******/ script.setAttribute("nonce", __webpack_require__.nc);
|
||||
/******/ }
|
||||
/******/ script.src = __webpack_require__.p + "" + chunkId + ".asyncoutput.js";
|
||||
/******/ var timeout = setTimeout(onScriptComplete, 120000);
|
||||
/******/ script.onerror = script.onload = onScriptComplete;
|
||||
/******/ function onScriptComplete() {
|
||||
/******/ // avoid mem leaks in IE.
|
||||
/******/ script.onerror = script.onload = null;
|
||||
/******/ clearTimeout(timeout);
|
||||
/******/ var chunk = installedChunks[chunkId];
|
||||
/******/ if(chunk !== 0) {
|
||||
/******/ if(chunk) {
|
||||
/******/ chunk[1](new Error('Loading chunk ' + chunkId + ' failed.'));
|
||||
/******/ }
|
||||
/******/ installedChunks[chunkId] = undefined;
|
||||
/******/ }
|
||||
/******/ };
|
||||
/******/ head.appendChild(script);
|
||||
/******/
|
||||
/******/ return promise;
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // expose the modules object (__webpack_modules__)
|
||||
/******/ __webpack_require__.m = modules;
|
||||
/******/
|
||||
/******/ // expose the module cache
|
||||
/******/ __webpack_require__.c = installedModules;
|
||||
/******/
|
||||
/******/ // define getter function for harmony exports
|
||||
/******/ __webpack_require__.d = function(exports, name, getter) {
|
||||
/******/ if(!__webpack_require__.o(exports, name)) {
|
||||
/******/ Object.defineProperty(exports, name, {
|
||||
/******/ configurable: false,
|
||||
/******/ enumerable: true,
|
||||
/******/ get: getter
|
||||
/******/ });
|
||||
/******/ }
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // getDefaultExport function for compatibility with non-harmony modules
|
||||
/******/ __webpack_require__.n = function(module) {
|
||||
/******/ var getter = module && module.__esModule ?
|
||||
/******/ function getDefault() { return module['default']; } :
|
||||
/******/ function getModuleExports() { return module; };
|
||||
/******/ __webpack_require__.d(getter, 'a', getter);
|
||||
/******/ return getter;
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // Object.prototype.hasOwnProperty.call
|
||||
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
|
||||
/******/
|
||||
/******/ // __webpack_public_path__
|
||||
/******/ __webpack_require__.p = "js/";
|
||||
/******/
|
||||
/******/ // on error function for async loading
|
||||
/******/ __webpack_require__.oe = function(err) { console.error(err); throw err; };
|
||||
/******/
|
||||
/******/ // Load entry module and return exports
|
||||
/******/ return __webpack_require__(__webpack_require__.s = 0);
|
||||
/******/ })
|
||||
/************************************************************************/
|
||||
/******/ ([
|
||||
/* 0 */
|
||||
/*!**************************!*\
|
||||
!*** multi ./example.js ***!
|
||||
\**************************/
|
||||
/*! no static exports found */
|
||||
/*! all exports used */
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
module.exports = __webpack_require__(/*! ./example.js */1);
|
||||
|
||||
|
||||
/***/ }),
|
||||
/* 1 */
|
||||
/*!********************!*\
|
||||
!*** ./example.js ***!
|
||||
\********************/
|
||||
/*! no static exports found */
|
||||
/*! all exports used */
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
var main = function() {
|
||||
console.log("Main class");
|
||||
Promise.all/* require.ensure */([__webpack_require__.e(0), __webpack_require__.e(2)]).then((() => {
|
||||
const page = __webpack_require__(/*! ./pageA */ 2);
|
||||
page();
|
||||
}).bind(null, __webpack_require__)).catch(__webpack_require__.oe);
|
||||
__webpack_require__.e/* require.ensure */(1).then((() => {
|
||||
const page = __webpack_require__(/*! ./pageB */ 3);
|
||||
page();
|
||||
}).bind(null, __webpack_require__)).catch(__webpack_require__.oe);
|
||||
};
|
||||
|
||||
main();
|
||||
|
||||
|
||||
/***/ })
|
||||
/******/ ]);
|
||||
```
|
||||
|
||||
# js/0.asyncoutput.js
|
||||
|
||||
``` javascript
|
||||
webpackJsonp([0],{
|
||||
|
||||
/***/ 4:
|
||||
/*!******************************!*\
|
||||
!*** ./reusableComponent.js ***!
|
||||
\******************************/
|
||||
/*! no static exports found */
|
||||
/*! all exports used */
|
||||
/***/ (function(module, exports) {
|
||||
|
||||
module.exports = function() {
|
||||
console.log("reusable Component");
|
||||
};
|
||||
|
||||
|
||||
/***/ })
|
||||
|
||||
});
|
||||
```
|
||||
|
||||
# js/1.asyncoutput.js
|
||||
|
||||
``` javascript
|
||||
webpackJsonp([1],{
|
||||
|
||||
/***/ 3:
|
||||
/*!******************!*\
|
||||
!*** ./pageB.js ***!
|
||||
\******************/
|
||||
/*! no static exports found */
|
||||
/*! all exports used */
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
module.exports = function() {
|
||||
console.log("Page B");
|
||||
Promise.all/* require.ensure */([__webpack_require__.e(0), __webpack_require__.e(3)]).then((()=>{
|
||||
const page = __webpack_require__(/*! ./pageC */ 5);
|
||||
page();
|
||||
}).bind(null, __webpack_require__)).catch(__webpack_require__.oe);
|
||||
};
|
||||
|
||||
|
||||
/***/ })
|
||||
|
||||
});
|
||||
```
|
||||
|
||||
# js/2.asyncoutput.js
|
||||
|
||||
``` javascript
|
||||
webpackJsonp([2],{
|
||||
|
||||
/***/ 2:
|
||||
/*!******************!*\
|
||||
!*** ./pageA.js ***!
|
||||
\******************/
|
||||
/*! no static exports found */
|
||||
/*! all exports used */
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
var reusableComponent = __webpack_require__(/*! ./reusableComponent */ 4);
|
||||
|
||||
module.exports = function() {
|
||||
console.log("Page A");
|
||||
reusableComponent();
|
||||
};
|
||||
|
||||
|
||||
/***/ })
|
||||
|
||||
});
|
||||
```
|
||||
|
||||
# js/3.asyncoutput.js
|
||||
|
||||
``` javascript
|
||||
webpackJsonp([3],{
|
||||
|
||||
/***/ 5:
|
||||
/*!******************!*\
|
||||
!*** ./pageC.js ***!
|
||||
\******************/
|
||||
/*! no static exports found */
|
||||
/*! all exports used */
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
var reusableComponent = __webpack_require__(/*! ./reusableComponent */ 4);
|
||||
|
||||
module.exports = function() {
|
||||
console.log("Page C");
|
||||
reusableComponent();
|
||||
};
|
||||
|
||||
|
||||
/***/ })
|
||||
|
||||
});
|
||||
```
|
||||
|
||||
# Info
|
||||
|
||||
## Uncompressed
|
||||
|
||||
```
|
||||
Hash: 777f989f517d7831d56f1d268f47bc8703ad9f73
|
||||
Version: webpack 3.6.0
|
||||
Child
|
||||
Hash: 777f989f517d7831d56f
|
||||
Asset Size Chunks Chunk Names
|
||||
0.output.js 388 bytes 0 [emitted]
|
||||
1.output.js 481 bytes 1 [emitted]
|
||||
2.output.js 388 bytes 2 [emitted]
|
||||
output.js 6.95 kB 3 [emitted] main
|
||||
Entrypoint main = output.js
|
||||
chunk {0} 0.output.js 142 bytes {3} [rendered]
|
||||
> [4] ./pageB.js 3:1-6:3
|
||||
[5] ./pageC.js 142 bytes {0} [built]
|
||||
cjs require ./pageC [4] ./pageB.js 4:15-33
|
||||
chunk {1} 1.output.js 140 bytes {3} [rendered]
|
||||
> [1] ./example.js 7:1-10:3
|
||||
[4] ./pageB.js 140 bytes {1} [built]
|
||||
cjs require ./pageB [1] ./example.js 8:15-33
|
||||
chunk {2} 2.output.js 142 bytes {3} [rendered]
|
||||
> [1] ./example.js 3:1-6:3
|
||||
[3] ./pageA.js 142 bytes {2} [built]
|
||||
cjs require ./pageA [1] ./example.js 4:15-33
|
||||
chunk {3} output.js (main) 333 bytes [entry] [rendered]
|
||||
> main [0] multi ./example.js
|
||||
[0] multi ./example.js 28 bytes {3} [built]
|
||||
[1] ./example.js 233 bytes {3} [built]
|
||||
single entry ./example.js [0] multi ./example.js main:100000
|
||||
[2] ./reusableComponent.js 72 bytes {3} [built]
|
||||
cjs require ./reusableComponent [3] ./pageA.js 1:24-54
|
||||
cjs require ./reusableComponent [5] ./pageC.js 1:24-54
|
||||
Child
|
||||
Hash: 1d268f47bc8703ad9f73
|
||||
Asset Size Chunks Chunk Names
|
||||
0.asyncoutput.js 314 bytes 0 [emitted]
|
||||
1.asyncoutput.js 522 bytes 1 [emitted]
|
||||
2.asyncoutput.js 388 bytes 2 [emitted]
|
||||
3.asyncoutput.js 388 bytes 3 [emitted]
|
||||
asyncoutput.js 6.7 kB 4 [emitted] main
|
||||
Entrypoint main = asyncoutput.js
|
||||
chunk {0} 0.asyncoutput.js 72 bytes {4} [rendered]
|
||||
> async commons [1] ./example.js 3:1-6:3
|
||||
> async commons [3] ./pageB.js 3:1-6:3
|
||||
[4] ./reusableComponent.js 72 bytes {0} [built]
|
||||
cjs require ./reusableComponent [2] ./pageA.js 1:24-54
|
||||
cjs require ./reusableComponent [5] ./pageC.js 1:24-54
|
||||
chunk {1} 1.asyncoutput.js 140 bytes {4} [rendered]
|
||||
> [1] ./example.js 7:1-10:3
|
||||
[3] ./pageB.js 140 bytes {1} [built]
|
||||
cjs require ./pageB [1] ./example.js 8:15-33
|
||||
chunk {2} 2.asyncoutput.js 142 bytes {4} [rendered]
|
||||
> [1] ./example.js 3:1-6:3
|
||||
[2] ./pageA.js 142 bytes {2} [built]
|
||||
cjs require ./pageA [1] ./example.js 4:15-33
|
||||
chunk {3} 3.asyncoutput.js 142 bytes {1} [rendered]
|
||||
> [3] ./pageB.js 3:1-6:3
|
||||
[5] ./pageC.js 142 bytes {3} [built]
|
||||
cjs require ./pageC [3] ./pageB.js 4:15-33
|
||||
chunk {4} asyncoutput.js (main) 261 bytes [entry] [rendered]
|
||||
> main [0] multi ./example.js
|
||||
[0] multi ./example.js 28 bytes {4} [built]
|
||||
[1] ./example.js 233 bytes {4} [built]
|
||||
single entry ./example.js [0] multi ./example.js main:100000
|
||||
```
|
||||
|
||||
## Minimized (uglify-js, no zip)
|
||||
|
||||
```
|
||||
Hash: 777f989f517d7831d56f1d268f47bc8703ad9f73
|
||||
Version: webpack 3.6.0
|
||||
Child
|
||||
Hash: 777f989f517d7831d56f
|
||||
Asset Size Chunks Chunk Names
|
||||
0.output.js 98 bytes 0 [emitted]
|
||||
1.output.js 340 bytes 1 [emitted]
|
||||
2.output.js 98 bytes 2 [emitted]
|
||||
output.js 6.46 kB 3 [emitted] main
|
||||
Entrypoint main = output.js
|
||||
chunk {0} 0.output.js 142 bytes {3} [rendered]
|
||||
> [4] ./pageB.js 3:1-6:3
|
||||
[5] ./pageC.js 142 bytes {0} [built]
|
||||
cjs require ./pageC [4] ./pageB.js 4:15-33
|
||||
chunk {1} 1.output.js 140 bytes {3} [rendered]
|
||||
> [1] ./example.js 7:1-10:3
|
||||
[4] ./pageB.js 140 bytes {1} [built]
|
||||
cjs require ./pageB [1] ./example.js 8:15-33
|
||||
chunk {2} 2.output.js 142 bytes {3} [rendered]
|
||||
> [1] ./example.js 3:1-6:3
|
||||
[3] ./pageA.js 142 bytes {2} [built]
|
||||
cjs require ./pageA [1] ./example.js 4:15-33
|
||||
chunk {3} output.js (main) 333 bytes [entry] [rendered]
|
||||
> main [0] multi ./example.js
|
||||
[0] multi ./example.js 28 bytes {3} [built]
|
||||
[1] ./example.js 233 bytes {3} [built]
|
||||
single entry ./example.js [0] multi ./example.js main:100000
|
||||
[2] ./reusableComponent.js 72 bytes {3} [built]
|
||||
cjs require ./reusableComponent [3] ./pageA.js 1:24-54
|
||||
cjs require ./reusableComponent [5] ./pageC.js 1:24-54
|
||||
|
||||
ERROR in 1.output.js from UglifyJs
|
||||
Unexpected token: punc ()) [1.output.js:8,53]
|
||||
|
||||
ERROR in output.js from UglifyJs
|
||||
Unexpected token: punc ()) [output.js:161,53]
|
||||
Child
|
||||
Hash: 1d268f47bc8703ad9f73
|
||||
Asset Size Chunks Chunk Names
|
||||
0.asyncoutput.js 93 bytes 0 [emitted]
|
||||
1.asyncoutput.js 381 bytes 1 [emitted]
|
||||
2.asyncoutput.js 98 bytes 2 [emitted]
|
||||
3.asyncoutput.js 98 bytes 3 [emitted]
|
||||
asyncoutput.js 6.37 kB 4 [emitted] main
|
||||
Entrypoint main = asyncoutput.js
|
||||
chunk {0} 0.asyncoutput.js 72 bytes {4} [rendered]
|
||||
> async commons [1] ./example.js 3:1-6:3
|
||||
> async commons [3] ./pageB.js 3:1-6:3
|
||||
[4] ./reusableComponent.js 72 bytes {0} [built]
|
||||
cjs require ./reusableComponent [2] ./pageA.js 1:24-54
|
||||
cjs require ./reusableComponent [5] ./pageC.js 1:24-54
|
||||
chunk {1} 1.asyncoutput.js 140 bytes {4} [rendered]
|
||||
> [1] ./example.js 7:1-10:3
|
||||
[3] ./pageB.js 140 bytes {1} [built]
|
||||
cjs require ./pageB [1] ./example.js 8:15-33
|
||||
chunk {2} 2.asyncoutput.js 142 bytes {4} [rendered]
|
||||
> [1] ./example.js 3:1-6:3
|
||||
[2] ./pageA.js 142 bytes {2} [built]
|
||||
cjs require ./pageA [1] ./example.js 4:15-33
|
||||
chunk {3} 3.asyncoutput.js 142 bytes {1} [rendered]
|
||||
> [3] ./pageB.js 3:1-6:3
|
||||
[5] ./pageC.js 142 bytes {3} [built]
|
||||
cjs require ./pageC [3] ./pageB.js 4:15-33
|
||||
chunk {4} asyncoutput.js (main) 261 bytes [entry] [rendered]
|
||||
> main [0] multi ./example.js
|
||||
[0] multi ./example.js 28 bytes {4} [built]
|
||||
[1] ./example.js 233 bytes {4} [built]
|
||||
single entry ./example.js [0] multi ./example.js main:100000
|
||||
|
||||
ERROR in 1.asyncoutput.js from UglifyJs
|
||||
Unexpected token: punc ()) [1.asyncoutput.js:8,94]
|
||||
|
||||
ERROR in asyncoutput.js from UglifyJs
|
||||
Unexpected token: punc ()) [asyncoutput.js:161,94]
|
||||
```
|
|
@ -0,0 +1,2 @@
|
|||
global.NO_TARGET_ARGS = true;
|
||||
require("../build-common");
|
|
@ -0,0 +1,13 @@
|
|||
var main = function() {
|
||||
console.log("Main class");
|
||||
require.ensure([], () => {
|
||||
const page = require("./pageA");
|
||||
page();
|
||||
});
|
||||
require.ensure([], () => {
|
||||
const page = require("./pageB");
|
||||
page();
|
||||
});
|
||||
};
|
||||
|
||||
main();
|
|
@ -0,0 +1,6 @@
|
|||
var reusableComponent = require("./reusableComponent");
|
||||
|
||||
module.exports = function() {
|
||||
console.log("Page A");
|
||||
reusableComponent();
|
||||
};
|
|
@ -0,0 +1,7 @@
|
|||
module.exports = function() {
|
||||
console.log("Page B");
|
||||
require.ensure([], ()=>{
|
||||
const page = require("./pageC");
|
||||
page();
|
||||
});
|
||||
};
|
|
@ -0,0 +1,6 @@
|
|||
var reusableComponent = require("./reusableComponent");
|
||||
|
||||
module.exports = function() {
|
||||
console.log("Page C");
|
||||
reusableComponent();
|
||||
};
|
|
@ -0,0 +1,3 @@
|
|||
module.exports = function() {
|
||||
console.log("reusable Component");
|
||||
};
|
|
@ -0,0 +1,124 @@
|
|||
This example illustrates how common modules from deep ancestors of an entry point can be split into a seperate common chunk
|
||||
|
||||
* `pageA` and `pageB` are dynamically required
|
||||
* `pageC` and `pageA` both require the `reusableComponent`
|
||||
* `pageB` dynamically requires `PageC`
|
||||
|
||||
You can see that webpack outputs four files/chunks:
|
||||
|
||||
* `output.js` is the entry chunk and contains
|
||||
* the module system
|
||||
* chunk loading logic
|
||||
* the entry point `example.js`
|
||||
* module `reusableComponent`
|
||||
* `0.output.js` is an additional chunk
|
||||
* module `pageC`
|
||||
* `1.output.js` is an additional chunk
|
||||
* module `pageB`
|
||||
* `2.output.js` is an additional chunk
|
||||
* module `pageA`
|
||||
|
||||
|
||||
# example.js
|
||||
|
||||
``` javascript
|
||||
{{example.js}}
|
||||
```
|
||||
|
||||
# pageA.js
|
||||
|
||||
``` javascript
|
||||
{{pageA.js}}
|
||||
```
|
||||
|
||||
# pageB.js
|
||||
|
||||
``` javascript
|
||||
{{pageB.js}}
|
||||
```
|
||||
|
||||
# pageC.js
|
||||
|
||||
``` javascript
|
||||
{{pageC.js}}
|
||||
```
|
||||
|
||||
# reusableComponent.js
|
||||
|
||||
``` javascript
|
||||
{{reusableComponent.js}}
|
||||
```
|
||||
|
||||
# webpack.config.js
|
||||
|
||||
``` javascript
|
||||
{{webpack.config.js}}
|
||||
```
|
||||
|
||||
# js/output.js
|
||||
|
||||
``` javascript
|
||||
{{js/output.js}}
|
||||
```
|
||||
|
||||
# js/0.output.js
|
||||
|
||||
``` javascript
|
||||
{{js/0.output.js}}
|
||||
```
|
||||
|
||||
# js/1.output.js
|
||||
|
||||
``` javascript
|
||||
{{js/1.output.js}}
|
||||
```
|
||||
|
||||
# js/2.output.js
|
||||
|
||||
``` javascript
|
||||
{{js/2.output.js}}
|
||||
```
|
||||
|
||||
# js/asyncoutput.js
|
||||
|
||||
``` javascript
|
||||
{{js/asyncoutput.js}}
|
||||
```
|
||||
|
||||
# js/0.asyncoutput.js
|
||||
|
||||
``` javascript
|
||||
{{js/0.asyncoutput.js}}
|
||||
```
|
||||
|
||||
# js/1.asyncoutput.js
|
||||
|
||||
``` javascript
|
||||
{{js/1.asyncoutput.js}}
|
||||
```
|
||||
|
||||
# js/2.asyncoutput.js
|
||||
|
||||
``` javascript
|
||||
{{js/2.asyncoutput.js}}
|
||||
```
|
||||
|
||||
# js/3.asyncoutput.js
|
||||
|
||||
``` javascript
|
||||
{{js/3.asyncoutput.js}}
|
||||
```
|
||||
|
||||
# Info
|
||||
|
||||
## Uncompressed
|
||||
|
||||
```
|
||||
{{stdout}}
|
||||
```
|
||||
|
||||
## Minimized (uglify-js, no zip)
|
||||
|
||||
```
|
||||
{{min:stdout}}
|
||||
```
|
|
@ -0,0 +1,41 @@
|
|||
"use strict";
|
||||
const webpack = require("../../");
|
||||
const path = require("path");
|
||||
|
||||
module.exports = [
|
||||
{
|
||||
entry: {
|
||||
main: ["./example.js"]
|
||||
},
|
||||
output: {
|
||||
path: path.resolve(__dirname, "js"),
|
||||
filename: "output.js"
|
||||
},
|
||||
plugins: [
|
||||
new webpack.optimize.CommonsChunkPlugin({
|
||||
name: "main",
|
||||
minChunks: 2,
|
||||
children: true,
|
||||
deepChildren: true,
|
||||
})
|
||||
]
|
||||
},
|
||||
{
|
||||
entry: {
|
||||
main: ["./example.js"]
|
||||
},
|
||||
output: {
|
||||
path: path.resolve(__dirname, "js"),
|
||||
filename: "asyncoutput.js"
|
||||
},
|
||||
plugins: [
|
||||
new webpack.optimize.CommonsChunkPlugin({
|
||||
name: "main",
|
||||
minChunks: 2,
|
||||
async: true,
|
||||
children: true,
|
||||
deepChildren: true,
|
||||
})
|
||||
]
|
||||
}
|
||||
];
|
|
@ -2,6 +2,7 @@
|
|||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
Author Tobias Koppers @sokra
|
||||
*/
|
||||
"use strict";
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
|
||||
|
|
|
@ -584,8 +584,8 @@ class Compilation extends Tapable {
|
|||
chunk.entryModule = module;
|
||||
self.assignIndex(module);
|
||||
self.assignDepth(module);
|
||||
self.processDependenciesBlockForChunk(module, chunk);
|
||||
});
|
||||
self.processDependenciesBlocksForChunks(self.chunks.slice());
|
||||
self.sortModules(self.modules);
|
||||
self.applyPlugins0("optimize");
|
||||
|
||||
|
@ -852,11 +852,16 @@ class Compilation extends Tapable {
|
|||
}
|
||||
}
|
||||
|
||||
processDependenciesBlockForChunk(module, chunk) {
|
||||
let block = module;
|
||||
const initialChunk = chunk;
|
||||
processDependenciesBlocksForChunks(inputChunks) {
|
||||
const chunkDependencies = new Map(); // Map<Chunk, Array<{Module, Chunk}>>
|
||||
|
||||
const queue = inputChunks.map(chunk => ({
|
||||
block: chunk.entryModule,
|
||||
module: chunk.entryModule,
|
||||
chunk: chunk
|
||||
}));
|
||||
|
||||
let block, module, chunk;
|
||||
const iteratorBlock = b => {
|
||||
let c;
|
||||
if(!b.chunks) {
|
||||
|
@ -901,12 +906,6 @@ class Compilation extends Tapable {
|
|||
}
|
||||
};
|
||||
|
||||
const queue = [{
|
||||
block,
|
||||
module,
|
||||
chunk
|
||||
}];
|
||||
|
||||
while(queue.length) {
|
||||
const queueItem = queue.pop();
|
||||
block = queueItem.block;
|
||||
|
@ -926,13 +925,12 @@ class Compilation extends Tapable {
|
|||
}
|
||||
}
|
||||
|
||||
chunk = initialChunk;
|
||||
let chunks = new Set();
|
||||
const queue2 = [{
|
||||
const queue2 = inputChunks.map(chunk => ({
|
||||
chunk,
|
||||
chunks
|
||||
}];
|
||||
chunks: new Set()
|
||||
}));
|
||||
|
||||
let chunks;
|
||||
const filterFn = dep => {
|
||||
if(chunks.has(dep.chunk)) return false;
|
||||
for(const chunk of chunks) {
|
||||
|
|
|
@ -42,7 +42,7 @@ class UmdMainTemplatePlugin {
|
|||
apply(compilation) {
|
||||
const mainTemplate = compilation.mainTemplate;
|
||||
compilation.templatesPlugin("render-with-entry", (source, chunk, hash) => {
|
||||
let externals = chunk.getModules().filter(m => m.external);
|
||||
let externals = chunk.getModules().filter(m => m.external && (m.type === "umd" || m.type === "umd2"));
|
||||
const optionalExternals = [];
|
||||
let requiredExternals = [];
|
||||
if(this.optionalAmdExternalAsGlobal) {
|
||||
|
|
|
@ -28,6 +28,10 @@ class AMDDefineDependencyParserPlugin {
|
|||
this.options = options;
|
||||
}
|
||||
|
||||
newDefineDependency(range, arrayRange, functionRange, objectRange, namedModule) {
|
||||
return new AMDDefineDependency(range, arrayRange, functionRange, objectRange, namedModule);
|
||||
}
|
||||
|
||||
apply(parser) {
|
||||
const options = this.options;
|
||||
parser.plugin("call define", (expr) => {
|
||||
|
@ -156,7 +160,7 @@ class AMDDefineDependencyParserPlugin {
|
|||
parser.walkExpression(fn || obj);
|
||||
}
|
||||
|
||||
const dep = new AMDDefineDependency(
|
||||
const dep = this.newDefineDependency(
|
||||
expr.range,
|
||||
array ? array.range : null,
|
||||
fn ? fn.range : null,
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
*/
|
||||
"use strict";
|
||||
let nextIdent = 0;
|
||||
|
||||
class CommonsChunkPlugin {
|
||||
constructor(options) {
|
||||
if(arguments.length > 1) {
|
||||
|
@ -31,6 +32,7 @@ The available options are:
|
|||
this.minChunks = normalizedOptions.minChunks;
|
||||
this.selectedChunks = normalizedOptions.selectedChunks;
|
||||
this.children = normalizedOptions.children;
|
||||
this.deepChildren = normalizedOptions.deepChildren;
|
||||
this.async = normalizedOptions.async;
|
||||
this.minSize = normalizedOptions.minSize;
|
||||
this.ident = __filename + (nextIdent++);
|
||||
|
@ -76,6 +78,7 @@ You can however specify the name of the async chunk by passing the desired strin
|
|||
minChunks: options.minChunks,
|
||||
selectedChunks: options.chunks,
|
||||
children: options.children,
|
||||
deepChildren: options.deepChildren,
|
||||
async: options.async,
|
||||
minSize: options.minSize
|
||||
};
|
||||
|
@ -104,7 +107,7 @@ You can however specify the name of the async chunk by passing the desired strin
|
|||
/**
|
||||
* These chunks are subject to get "common" modules extracted and moved to the common chunk
|
||||
*/
|
||||
const affectedChunks = this.getAffectedChunks(compilation, chunks, targetChunk, targetChunks, idx, this.selectedChunks, this.async, this.children);
|
||||
const affectedChunks = this.getAffectedChunks(compilation, chunks, targetChunk, targetChunks, idx, this.selectedChunks, this.async, this.deepChildren, this.children);
|
||||
|
||||
// bail if no chunk is affected
|
||||
if(!affectedChunks) {
|
||||
|
@ -211,7 +214,37 @@ You can however specify the name of the async chunk by passing the desired strin
|
|||
Take a look at the "name"/"names" or async/children option.`);
|
||||
}
|
||||
|
||||
getAffectedChunks(compilation, allChunks, targetChunk, targetChunks, currentIndex, selectedChunks, asyncOption, children) {
|
||||
getAffectedUnnamedChunks(affectedChunks, targetChunk, asyncOption, deepChildrenOption) {
|
||||
for(const chunk of targetChunk.chunksIterable) {
|
||||
if(chunk.isInitial()) {
|
||||
continue;
|
||||
}
|
||||
// If all the parents of a chunk are either
|
||||
// a) the target chunk we started with
|
||||
// b) themselves affected chunks
|
||||
// we can assume that this chunk is an affected chunk too, as there is no way a chunk that
|
||||
// isn't only depending on the target chunk is a parent of the chunk tested
|
||||
if(asyncOption || chunk.parents.every((parentChunk) => parentChunk === targetChunk || affectedChunks.has(parentChunk))) {
|
||||
// This check not only dedupes the affectedChunks but also guarantees we avoid endless loops
|
||||
if(!affectedChunks.has(chunk) || affectedChunks.values().next().value === chunk) {
|
||||
// We mutate the affected chunks before going deeper, so the deeper levels and other branches
|
||||
// Have the information of this chunk being affected for their assertion if a chunk should
|
||||
// not be affected
|
||||
affectedChunks.add(chunk);
|
||||
|
||||
// We recurse down to all the children of the chunk, applying the same assumption.
|
||||
// This guarantees that if a chunk should be an affected chunk,
|
||||
// at the latest the last connection to the same chunk meets the
|
||||
// condition to add it to the affected chunks.
|
||||
if(deepChildrenOption === true) {
|
||||
this.getAffectedUnnamedChunks(affectedChunks, chunk, asyncOption, deepChildrenOption);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getAffectedChunks(compilation, allChunks, targetChunk, targetChunks, currentIndex, selectedChunks, asyncOption, deepChildrenOption, children) {
|
||||
const asyncOrNoSelectedChunk = children || asyncOption;
|
||||
|
||||
if(Array.isArray(selectedChunks)) {
|
||||
|
@ -223,17 +256,9 @@ Take a look at the "name"/"names" or async/children option.`);
|
|||
}
|
||||
|
||||
if(asyncOrNoSelectedChunk) {
|
||||
return targetChunk.getChunks().filter((chunk) => {
|
||||
// we only are interested in on-demand chunks
|
||||
if(chunk.isInitial())
|
||||
return false;
|
||||
|
||||
// we can only move modules from this chunk if the "commonChunk" is the only parent
|
||||
if(!asyncOption)
|
||||
return chunk.getNumberOfParents() === 1;
|
||||
|
||||
return true;
|
||||
});
|
||||
let affectedChunks = new Set();
|
||||
this.getAffectedUnnamedChunks(affectedChunks, targetChunk, asyncOption, deepChildrenOption);
|
||||
return Array.from(affectedChunks);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
it("should handle circular chunks correctly", function(done) {
|
||||
import(/* webpackChunkName: "a" */"./module-a").then(function(result) {
|
||||
return result.default();
|
||||
}).then(function(result2) {
|
||||
result2.default().should.be.eql("x");
|
||||
done();
|
||||
}).catch(function(e) {
|
||||
done(e);
|
||||
});
|
||||
const couldBe = function() {
|
||||
return import(/* webpackChunkName: "b" */"./module-b");
|
||||
};
|
||||
});
|
|
@ -0,0 +1,3 @@
|
|||
export default function() {
|
||||
return import(/* webpackChunkName: "c" */"./module-c");
|
||||
};
|
|
@ -0,0 +1 @@
|
|||
export default "a2";
|
|
@ -0,0 +1,5 @@
|
|||
import "./module-x";
|
||||
|
||||
export default function() {
|
||||
return import(/* webpackChunkName: "c" */"./module-c");
|
||||
};
|
|
@ -0,0 +1 @@
|
|||
export default "b2";
|
|
@ -0,0 +1,9 @@
|
|||
import x from "./module-x";
|
||||
|
||||
export default function() {
|
||||
if(Math.random() < -1) {
|
||||
import(/* webpackChunkName: "a" */"./module-a");
|
||||
import(/* webpackChunkName: "b" */"./module-b");
|
||||
}
|
||||
return x;
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
export default "x";
|
|
@ -0,0 +1,12 @@
|
|||
it("should correctly include indirect children in common chunk", function(done) {
|
||||
Promise.all([
|
||||
import('./pageA'),
|
||||
import('./pageB')
|
||||
]).then((imports) => {
|
||||
imports[0].default.should.be.eql("reuse");
|
||||
imports[1].default.should.be.eql("reuse");
|
||||
done();
|
||||
}).catch(e => {
|
||||
done(e);
|
||||
})
|
||||
});
|
|
@ -0,0 +1,3 @@
|
|||
var reusableComponent = require("./reusableComponent");
|
||||
|
||||
export default reusableComponent.default;
|
|
@ -0,0 +1 @@
|
|||
module.exports = import('./pageC')
|
|
@ -0,0 +1,3 @@
|
|||
var reusableComponent = require("./reusableComponent");
|
||||
|
||||
export default reusableComponent.default;
|
|
@ -0,0 +1,3 @@
|
|||
const reuse = "reuse";
|
||||
|
||||
export default reuse;
|
|
@ -0,0 +1,8 @@
|
|||
it("should handle indirect children with multiple parents correctly", function(done) {
|
||||
import('./pageB').then(b => {
|
||||
b.default.should.be.eql("reuse");
|
||||
done()
|
||||
}).catch(e => {
|
||||
done();
|
||||
})
|
||||
})
|
|
@ -0,0 +1,8 @@
|
|||
module.exports = {
|
||||
findBundle: function(i, options) {
|
||||
return [
|
||||
"./main.js",
|
||||
"./misc.js",
|
||||
];
|
||||
}
|
||||
};
|
|
@ -0,0 +1,19 @@
|
|||
var CommonsChunkPlugin = require("../../../../lib/optimize/CommonsChunkPlugin");
|
||||
|
||||
module.exports = {
|
||||
entry: {
|
||||
main: "./index",
|
||||
misc: "./second",
|
||||
},
|
||||
output: {
|
||||
filename: "[name].js"
|
||||
},
|
||||
plugins: [
|
||||
new CommonsChunkPlugin({
|
||||
name: "main",
|
||||
minChunks: 2,
|
||||
children: true,
|
||||
deepChildren: true,
|
||||
})
|
||||
]
|
||||
};
|
|
@ -0,0 +1,23 @@
|
|||
require("should");
|
||||
var fs = require("fs");
|
||||
var path = require("path");
|
||||
|
||||
it("should correctly import a UMD external", function() {
|
||||
var external = require("external0");
|
||||
external.should.be.eql("module 0");
|
||||
});
|
||||
|
||||
it("should contain `require()` statements for the UMD external", function() {
|
||||
var source = fs.readFileSync(path.join(__dirname, "bundle0.js"), "utf-8");
|
||||
source.should.containEql("require(\"external0\")");
|
||||
});
|
||||
|
||||
it("should correctly import a non-UMD external", function() {
|
||||
var external = require("external1");
|
||||
external.should.be.eql("abc");
|
||||
});
|
||||
|
||||
it("should not contain `require()` statements for the non-UMD external", function() {
|
||||
var source = fs.readFileSync(path.join(__dirname, "bundle0.js"), "utf-8");
|
||||
source.should.not.containEql("require(\"'abc'\")");
|
||||
});
|
|
@ -0,0 +1,5 @@
|
|||
module.exports = {
|
||||
modules: {
|
||||
external0: "module 0"
|
||||
}
|
||||
};
|
|
@ -0,0 +1,13 @@
|
|||
module.exports = {
|
||||
output: {
|
||||
libraryTarget: "umd"
|
||||
},
|
||||
externals: {
|
||||
external0: "external0",
|
||||
external1: "var 'abc'"
|
||||
},
|
||||
node: {
|
||||
__dirname: false,
|
||||
__filename: false
|
||||
}
|
||||
};
|
|
@ -0,0 +1,23 @@
|
|||
require("should");
|
||||
var fs = require("fs");
|
||||
var path = require("path");
|
||||
|
||||
it("should correctly import a UMD2 external", function() {
|
||||
var external = require("external0");
|
||||
external.should.be.eql("module 0");
|
||||
});
|
||||
|
||||
it("should contain `require()` statements for the UMD2 external", function() {
|
||||
var source = fs.readFileSync(path.join(__dirname, "bundle0.js"), "utf-8");
|
||||
source.should.containEql("require(\"external0\")");
|
||||
});
|
||||
|
||||
it("should correctly import a non-UMD2 external", function() {
|
||||
var external = require("external1");
|
||||
external.should.be.eql("abc");
|
||||
});
|
||||
|
||||
it("should not contain `require()` statements for the non-UMD2 external", function() {
|
||||
var source = fs.readFileSync(path.join(__dirname, "bundle0.js"), "utf-8");
|
||||
source.should.not.containEql("require(\"'abc'\")");
|
||||
});
|
|
@ -0,0 +1,5 @@
|
|||
module.exports = {
|
||||
modules: {
|
||||
external0: "module 0"
|
||||
}
|
||||
};
|
|
@ -0,0 +1,13 @@
|
|||
module.exports = {
|
||||
output: {
|
||||
libraryTarget: "umd2"
|
||||
},
|
||||
externals: {
|
||||
external0: "external0",
|
||||
external1: "var 'abc'"
|
||||
},
|
||||
node: {
|
||||
__dirname: false,
|
||||
__filename: false
|
||||
}
|
||||
};
|
|
@ -0,0 +1,8 @@
|
|||
chunk {0} 0.bundle.js (b) 49 bytes {2} {3} [rendered]
|
||||
[2] (webpack)/test/statsCases/circular-correctness/module-b.js 49 bytes {0} [built]
|
||||
chunk {1} 1.bundle.js (a) 49 bytes {2} {3} [rendered]
|
||||
[0] (webpack)/test/statsCases/circular-correctness/module-a.js 49 bytes {1} [built]
|
||||
chunk {2} 2.bundle.js (c) 98 bytes {0} {1} [rendered]
|
||||
[1] (webpack)/test/statsCases/circular-correctness/module-c.js 98 bytes {2} [built]
|
||||
chunk {3} bundle.js (main) 98 bytes [entry] [rendered]
|
||||
[3] (webpack)/test/statsCases/circular-correctness/index.js 98 bytes {3} [built]
|
|
@ -0,0 +1,2 @@
|
|||
import(/* webpackChunkName: "a" */"./module-a");
|
||||
import(/* webpackChunkName: "b" */"./module-b");
|
|
@ -0,0 +1 @@
|
|||
import(/* webpackChunkName: "c" */"./module-c");
|
|
@ -0,0 +1 @@
|
|||
import(/* webpackChunkName: "c" */"./module-c");
|
|
@ -0,0 +1,2 @@
|
|||
import(/* webpackChunkName: "a" */"./module-a");
|
||||
import(/* webpackChunkName: "b" */"./module-b");
|
|
@ -0,0 +1,14 @@
|
|||
module.exports = {
|
||||
entry: "./index",
|
||||
output: {
|
||||
filename: "bundle.js"
|
||||
},
|
||||
stats: {
|
||||
hash: false,
|
||||
timings: false,
|
||||
assets: false,
|
||||
chunks: true,
|
||||
chunkModules: true,
|
||||
modules: false
|
||||
}
|
||||
};
|
|
@ -0,0 +1 @@
|
|||
import(/* webpackChunkName: "a" */"./module-a");
|
|
@ -0,0 +1 @@
|
|||
import(/* webpackChunkName: "c" */"./module-c");
|
|
@ -0,0 +1,15 @@
|
|||
chunk {0} 0.js (c) 49 bytes {2} {3} [rendered]
|
||||
[1] (webpack)/test/statsCases/graph-correctness-entries/module-c.js 49 bytes {0} [built]
|
||||
import() ./module-c [3] (webpack)/test/statsCases/graph-correctness-entries/module-b.js 1:0-47
|
||||
import() ./module-c [4] (webpack)/test/statsCases/graph-correctness-entries/e2.js 1:0-47
|
||||
chunk {1} 1.js (a) 49 bytes {0} {4} [rendered]
|
||||
[0] (webpack)/test/statsCases/graph-correctness-entries/module-a.js 49 bytes {1} [built]
|
||||
import() ./module-a [1] (webpack)/test/statsCases/graph-correctness-entries/module-c.js 1:0-47
|
||||
import() ./module-a [2] (webpack)/test/statsCases/graph-correctness-entries/e1.js 1:0-47
|
||||
chunk {2} 2.js (b) 49 bytes {1} [rendered]
|
||||
[3] (webpack)/test/statsCases/graph-correctness-entries/module-b.js 49 bytes {2} [built]
|
||||
import() ./module-b [0] (webpack)/test/statsCases/graph-correctness-entries/module-a.js 1:0-47
|
||||
chunk {3} e2.js (e2) 49 bytes [entry] [rendered]
|
||||
[4] (webpack)/test/statsCases/graph-correctness-entries/e2.js 49 bytes {3} [built]
|
||||
chunk {4} e1.js (e1) 49 bytes [entry] [rendered]
|
||||
[2] (webpack)/test/statsCases/graph-correctness-entries/e1.js 49 bytes {4} [built]
|
|
@ -0,0 +1 @@
|
|||
import(/* webpackChunkName: "b" */"./module-b");
|
|
@ -0,0 +1 @@
|
|||
import(/* webpackChunkName: "c" */"./module-c");
|
|
@ -0,0 +1 @@
|
|||
import(/* webpackChunkName: "a" */"./module-a");
|
|
@ -0,0 +1,18 @@
|
|||
module.exports = {
|
||||
entry: {
|
||||
e1: "./e1",
|
||||
e2: "./e2"
|
||||
},
|
||||
output: {
|
||||
filename: "[name].js"
|
||||
},
|
||||
stats: {
|
||||
hash: false,
|
||||
timings: false,
|
||||
assets: false,
|
||||
chunks: true,
|
||||
chunkModules: true,
|
||||
modules: false,
|
||||
reasons: true
|
||||
}
|
||||
};
|
|
@ -0,0 +1,2 @@
|
|||
import "./module-x";
|
||||
import(/* webpackChunkName: "a" */"./module-a");
|
|
@ -0,0 +1,2 @@
|
|||
import "./module-x";
|
||||
import(/* webpackChunkName: "c" */"./module-c");
|
|
@ -0,0 +1,26 @@
|
|||
chunk {0} 0.js (y) 0 bytes {4} {5} [rendered]
|
||||
[1] (webpack)/test/statsCases/graph-correctness-modules/module-y.js 0 bytes {0} [built]
|
||||
import() ./module-y [0] (webpack)/test/statsCases/graph-correctness-modules/module-x.js 1:0-47
|
||||
chunk {1} 1.js (c) 49 bytes {3} {4} [rendered]
|
||||
[3] (webpack)/test/statsCases/graph-correctness-modules/module-c.js 49 bytes {1} [built]
|
||||
import() ./module-c [5] (webpack)/test/statsCases/graph-correctness-modules/module-b.js 1:0-47
|
||||
import() ./module-c [6] (webpack)/test/statsCases/graph-correctness-modules/e2.js 2:0-47
|
||||
chunk {2} 2.js (a) 49 bytes {1} {5} [rendered]
|
||||
[2] (webpack)/test/statsCases/graph-correctness-modules/module-a.js 49 bytes {2} [built]
|
||||
import() ./module-a [3] (webpack)/test/statsCases/graph-correctness-modules/module-c.js 1:0-47
|
||||
import() ./module-a [4] (webpack)/test/statsCases/graph-correctness-modules/e1.js 2:0-47
|
||||
chunk {3} 3.js (b) 179 bytes {2} [rendered]
|
||||
[5] (webpack)/test/statsCases/graph-correctness-modules/module-b.js 179 bytes {3} [built]
|
||||
import() ./module-b [2] (webpack)/test/statsCases/graph-correctness-modules/module-a.js 1:0-47
|
||||
chunk {4} e2.js (e2) 119 bytes [entry] [rendered]
|
||||
[0] (webpack)/test/statsCases/graph-correctness-modules/module-x.js 49 bytes {4} {5} [built]
|
||||
harmony import ./module-x [4] (webpack)/test/statsCases/graph-correctness-modules/e1.js 1:0-20
|
||||
import() ./module-x [5] (webpack)/test/statsCases/graph-correctness-modules/module-b.js 2:0-20
|
||||
harmony import ./module-x [6] (webpack)/test/statsCases/graph-correctness-modules/e2.js 1:0-20
|
||||
[6] (webpack)/test/statsCases/graph-correctness-modules/e2.js 70 bytes {4} [built]
|
||||
chunk {5} e1.js (e1) 119 bytes [entry] [rendered]
|
||||
[0] (webpack)/test/statsCases/graph-correctness-modules/module-x.js 49 bytes {4} {5} [built]
|
||||
harmony import ./module-x [4] (webpack)/test/statsCases/graph-correctness-modules/e1.js 1:0-20
|
||||
import() ./module-x [5] (webpack)/test/statsCases/graph-correctness-modules/module-b.js 2:0-20
|
||||
harmony import ./module-x [6] (webpack)/test/statsCases/graph-correctness-modules/e2.js 1:0-20
|
||||
[4] (webpack)/test/statsCases/graph-correctness-modules/e1.js 70 bytes {5} [built]
|
|
@ -0,0 +1 @@
|
|||
import(/* webpackChunkName: "b" */"./module-b");
|
|
@ -0,0 +1,2 @@
|
|||
import(/* webpackChunkName: "c" */"./module-c");
|
||||
import("./module-x"); // This should not create a chunk, because module-x is in both entrypoints (in every path to this module-b)
|
|
@ -0,0 +1 @@
|
|||
import(/* webpackChunkName: "a" */"./module-a");
|
|
@ -0,0 +1 @@
|
|||
import(/* webpackChunkName: "y" */"./module-y");
|
|
@ -0,0 +1,18 @@
|
|||
module.exports = {
|
||||
entry: {
|
||||
e1: "./e1",
|
||||
e2: "./e2"
|
||||
},
|
||||
output: {
|
||||
filename: "[name].js"
|
||||
},
|
||||
stats: {
|
||||
hash: false,
|
||||
timings: false,
|
||||
assets: false,
|
||||
chunks: true,
|
||||
chunkModules: true,
|
||||
modules: false,
|
||||
reasons: true
|
||||
}
|
||||
};
|
Loading…
Reference in New Issue