diff --git a/.travis.yml b/.travis.yml index c0a808d03..fd031f70f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,7 @@ language: node_js branches: only: - master + - next cache: directories: diff --git a/appveyor.yml b/appveyor.yml index 1f53b2ff4..a203061e1 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -4,6 +4,7 @@ branches: only: - master + - next init: - git config --global core.autocrlf input diff --git a/bin/webpack.js b/bin/webpack.js old mode 100755 new mode 100644 index 37125533c..3c41d5b6e --- a/bin/webpack.js +++ b/bin/webpack.js @@ -124,11 +124,21 @@ yargs.options({ group: DISPLAY_GROUP, describe: "Display information about exports provided from modules" }, + "display-optimization-bailout": { + type: "boolean", + group: DISPLAY_GROUP, + describe: "Display information about why optimization bailed out for modules" + }, "display-error-details": { type: "boolean", group: DISPLAY_GROUP, describe: "Display details about errors" }, + "display": { + type: "string", + group: DISPLAY_GROUP, + describe: "Select display preset (verbose, detailed, normal, minimal, errors-only, none)" + }, "verbose": { type: "boolean", group: DISPLAY_GROUP, @@ -139,15 +149,7 @@ yargs.options({ var argv = yargs.argv; if(argv.verbose) { - argv["display-reasons"] = true; - argv["display-depth"] = true; - argv["display-entrypoints"] = true; - argv["display-used-exports"] = true; - argv["display-provided-exports"] = true; - argv["display-error-details"] = true; - argv["display-modules"] = true; - argv["display-cached"] = true; - argv["display-cached-assets"] = true; + argv["display"] = "verbose"; } var options = require("./convert-argv")(yargs, argv); @@ -181,6 +183,11 @@ function processOptions(options) { } else if(!outputOptions) { outputOptions = {}; } + + ifArg("display", function(preset) { + outputOptions = statsPresetToOptions(preset); + }); + outputOptions = Object.create(outputOptions); if(Array.isArray(options) && !outputOptions.children) { outputOptions.children = options.map(o => o.stats); @@ -219,36 +226,50 @@ function processOptions(options) { outputOptions.cachedAssets = false; ifArg("display-chunks", function(bool) { - outputOptions.modules = !bool; - outputOptions.chunks = bool; + if(bool) { + outputOptions.modules = false; + outputOptions.chunks = true; + outputOptions.chunkModules = true; + } }); ifArg("display-entrypoints", function(bool) { - outputOptions.entrypoints = bool; + if(bool) + outputOptions.entrypoints = true; }); ifArg("display-reasons", function(bool) { - outputOptions.reasons = bool; + if(bool) + outputOptions.reasons = true; }); ifArg("display-depth", function(bool) { - outputOptions.depth = bool; + if(bool) + outputOptions.depth = true; }); ifArg("display-used-exports", function(bool) { - outputOptions.usedExports = bool; + if(bool) + outputOptions.usedExports = true; }); ifArg("display-provided-exports", function(bool) { - outputOptions.providedExports = bool; + if(bool) + outputOptions.providedExports = true; + }); + + ifArg("display-optimization-bailout", function(bool) { + outputOptions.optimizationBailout = bool; }); ifArg("display-error-details", function(bool) { - outputOptions.errorDetails = bool; + if(bool) + outputOptions.errorDetails = true; }); ifArg("display-origins", function(bool) { - outputOptions.chunkOrigins = bool; + if(bool) + outputOptions.chunkOrigins = true; }); ifArg("display-max-modules", function(value) { @@ -272,21 +293,6 @@ function processOptions(options) { outputOptions.maxModules = Infinity; outputOptions.exclude = undefined; } - } else { - if(typeof outputOptions.chunks === "undefined") - outputOptions.chunks = true; - if(typeof outputOptions.entrypoints === "undefined") - outputOptions.entrypoints = true; - if(typeof outputOptions.modules === "undefined") - outputOptions.modules = true; - if(typeof outputOptions.chunkModules === "undefined") - outputOptions.chunkModules = true; - if(typeof outputOptions.reasons === "undefined") - outputOptions.reasons = true; - if(typeof outputOptions.cached === "undefined") - outputOptions.cached = true; - if(typeof outputOptions.cachedAssets === "undefined") - outputOptions.cachedAssets = true; } ifArg("hide-modules", function(bool) { @@ -337,7 +343,9 @@ function processOptions(options) { process.stdout.write(JSON.stringify(stats.toJson(outputOptions), null, 2) + "\n"); } else if(stats.hash !== lastHash) { lastHash = stats.hash; - process.stdout.write(stats.toString(outputOptions) + "\n"); + var statsString = stats.toString(outputOptions); + if(statsString) + process.stdout.write(statsString + "\n"); } if(!options.watch && stats.hasErrors()) { process.on("exit", function() { diff --git a/examples/scope-hoisting/README.md b/examples/scope-hoisting/README.md new file mode 100644 index 000000000..e3e9dad86 --- /dev/null +++ b/examples/scope-hoisting/README.md @@ -0,0 +1,459 @@ +This example demonstrates Scope Hoisting in combination with Code Splitting. + +This is the dependency graph for the example: (solid lines express sync imports, dashed lines async imports) + +![](graph.png) + +All modules except `cjs` are EcmaScript modules. `cjs` is a CommonJs module. + +The interesting thing here is that putting all modules in single scope won't work, because of multiple reasons: + +* Modules `lazy`, `c`, `d` and `cjs` need to be in a separate chunk +* Module `shared` is accessed by two chunks (different scopes) +* Module `cjs` is a CommonJs module + +![](graph2.png) + +webpack therefore uses a approach called **"Partial Scope Hoisting"** or "Module concatenation", which chooses the largest possible subsets of ES modules which can be scope hoisted and combines them with the default webpack primitives. + +![](graph3.png) + +While module concatentation identifiers in modules are renamed to avoid conflicts and internal imports are simplified. External imports and exports from the root module use the existing ESM constructs. + +# example.js + +``` javascript +import { a, x, y } from "a"; +import * as b from "b"; + +import("./lazy").then(function(lazy) { + console.log(a, b.a(), x, y, lazy.c, lazy.d.a, lazy.x, lazy.y); +}); +``` + +# lazy.js + +``` javascript +export * from "c"; +import * as d from "d"; +export { d }; +``` + +# a.js + +``` javascript +// module a +export var a = "a"; +export * from "shared"; +``` + +# b.js + +``` javascript +// module b +export function a() { + return "b"; +}; +``` + +# c.js + +``` javascript +// module c +import { c as e } from "cjs"; + +export var c = String.fromCharCode(e.charCodeAt(0) - 2); + +export { x, y } from "shared"; +``` + +# d.js + +``` javascript +// module d +export var a = "d"; +``` + +# cjs.js + +``` javascript +// module cjs (commonjs) +exports.c = "e"; +``` + +# shared.js + +``` javascript +// shared module +export var x = "x"; +export * from "shared2"; +``` + +# shared2.js + +``` javascript +// shared2 module +export var y = "y"; +``` + + + +# webpack.config.js + +``` javascript +var webpack = require("../../"); + +module.exports = { + plugins: [ + new webpack.optimize.ModuleConcatenationPlugin() + ] +}; +``` + + + + +# js/output.js + +
/******/ (function(modules) { /* webpackBootstrap */ }) + +``` 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 = { +/******/ 1: 0 +/******/ }; +/******/ +/******/ var resolvedPromise = new Promise(function(resolve) { resolve(); }); +/******/ +/******/ // 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) { +/******/ if(installedChunks[chunkId] === 0) { +/******/ return resolvedPromise; +/******/ } +/******/ +/******/ // a Promise means "currently loading". +/******/ if(installedChunks[chunkId]) { +/******/ return installedChunks[chunkId][2]; +/******/ } +/******/ +/******/ // setup Promise in chunk cache +/******/ var promise = new Promise(function(resolve, reject) { +/******/ installedChunks[chunkId] = [resolve, reject]; +/******/ }); +/******/ installedChunks[chunkId][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; +/******/ +/******/ // identity function for calling harmony imports with the correct context +/******/ __webpack_require__.i = function(value) { return value; }; +/******/ +/******/ // 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); +/******/ }) +/************************************************************************/ +``` + +
+ +``` javascript +/******/ ([ +/* 0 */ +/* unknown exports provided */ +/* all exports used */ +/*!********************************!*\ + !*** ./example.js + 2 modules ***! + \********************************/ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); + +// CONCATENAMED MODULE: ./node_modules/a.js +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_shared__ = __webpack_require__(/*! shared */ 1); +// module a +var a = "a"; + + +// CONCATENAMED MODULE: ./node_modules/b.js +// module b +function b_js_a() { + return "b"; +}; + +// CONCATENAMED MODULE: ./example.js + + + +__webpack_require__.e/* import() */(0).then(__webpack_require__.bind(null, /*! ./lazy */ 2)).then(function(lazy) { + console.log(a, b_js_a(), __WEBPACK_IMPORTED_MODULE_0_shared__["a"], __WEBPACK_IMPORTED_MODULE_0_shared__["b"], lazy.c, lazy.d.a, lazy.x, lazy.y); +}); + + +/***/ }), +/* 1 */ +/* exports provided: x, y */ +/* exports used: x, y */ +/*!********************************************!*\ + !*** ./node_modules/shared.js + 1 modules ***! + \********************************************/ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); + +// CONCATENAMED MODULE: ./node_modules/shared2.js +// shared2 module +var y = "y"; + +// CONCATENAMED MODULE: ./node_modules/shared.js +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return x; }); +/* concated harmony reexport */__webpack_require__.d(__webpack_exports__, "b", function() { return y; }); +// shared module +var x = "x"; + + + +/***/ }) +/******/ ]); +``` + +# js/0.output.js + +``` javascript +webpackJsonp([0],[ +/* 0 */, +/* 1 */, +/* 2 */ +/* exports provided: d, c, x, y */ +/* all exports used */ +/*!*****************************!*\ + !*** ./lazy.js + 2 modules ***! + \*****************************/ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); + +// CONCATENAMED MODULE: ./node_modules/c.js +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_cjs__ = __webpack_require__(/*! cjs */ 3); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_cjs___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_cjs__); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_shared__ = __webpack_require__(/*! shared */ 1); +// module c + + +var c = String.fromCharCode(__WEBPACK_IMPORTED_MODULE_0_cjs__["c"].charCodeAt(0) - 2); + + + +// CONCATENAMED MODULE: ./node_modules/d.js +var d_js_namespaceObject = {}; +__webpack_require__.d(d_js_namespaceObject, "a", function() { return a; }); +// module d +var a = "d"; + +// CONCATENAMED MODULE: ./lazy.js +/* concated harmony reexport */__webpack_require__.d(__webpack_exports__, "c", function() { return c; }); +/* concated harmony reexport */__webpack_require__.d(__webpack_exports__, "x", function() { return __WEBPACK_IMPORTED_MODULE_1_shared__["a"]; }); +/* concated harmony reexport */__webpack_require__.d(__webpack_exports__, "y", function() { return __WEBPACK_IMPORTED_MODULE_1_shared__["b"]; }); +/* concated harmony reexport */__webpack_require__.d(__webpack_exports__, "d", function() { return d_js_namespaceObject; }); + + + + + +/***/ }), +/* 3 */ +/* unknown exports provided */ +/* exports used: c */ +/*!*****************************!*\ + !*** ./node_modules/cjs.js ***! + \*****************************/ +/***/ (function(module, exports) { + +// module cjs (commonjs) +exports.c = "e"; + + +/***/ }) +]); +``` + +Minimized + +``` javascript +webpackJsonp([0],[,,function(n,r,t){"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=t(3),u=(t.n(e),t(1)),c=String.fromCharCode(e.c.charCodeAt(0)-2),o={};t.d(o,"a",function(){return d});var d="d";t.d(r,"c",function(){return c}),t.d(r,"x",function(){return u.a}),t.d(r,"y",function(){return u.b}),t.d(r,"d",function(){return o})},function(n,r){r.c="e"}]); +``` + +# Info + +## Uncompressed + +``` +Hash: 4091e96718e53f8b98fd +Version: webpack 2.5.1 + Asset Size Chunks Chunk Names +0.output.js 1.85 kB 0 [emitted] + output.js 7.53 kB 1 [emitted] main +Entrypoint main = output.js +chunk {0} 0.output.js 276 bytes {1} [rendered] + > [4] 4:0-16 + [2] ./lazy.js + 2 modules 232 bytes {0} [built] + [exports: d, c, x, y] + import() ./lazy [4] ./example.js 4:0-16 + [3] ./node_modules/cjs.js 44 bytes {0} [built] + [only some exports used: c] + harmony import cjs [8] ./node_modules/c.js 2:0-29 +chunk {1} output.js (main) 385 bytes [entry] [rendered] + > main [4] + [0] ./example.js + 2 modules 280 bytes {1} [built] + [1] ./node_modules/shared.js + 1 modules 105 bytes {1} [built] + [exports: x, y] + [only some exports used: x, y] + harmony import shared [6] ./node_modules/a.js 3:0-23 + harmony import shared [8] ./node_modules/c.js 6:0-30 +``` + +## Minimized (uglify-js, no zip) + +``` +Hash: 4091e96718e53f8b98fd +Version: webpack 2.5.1 + Asset Size Chunks Chunk Names +0.output.js 379 bytes 0 [emitted] + output.js 1.73 kB 1 [emitted] main +Entrypoint main = output.js +chunk {0} 0.output.js 276 bytes {1} [rendered] + > [4] 4:0-16 + [2] ./lazy.js + 2 modules 232 bytes {0} [built] + [exports: d, c, x, y] + import() ./lazy [4] ./example.js 4:0-16 + [3] ./node_modules/cjs.js 44 bytes {0} [built] + [only some exports used: c] + harmony import cjs [8] ./node_modules/c.js 2:0-29 +chunk {1} output.js (main) 385 bytes [entry] [rendered] + > main [4] + [0] ./example.js + 2 modules 280 bytes {1} [built] + [1] ./node_modules/shared.js + 1 modules 105 bytes {1} [built] + [exports: x, y] + [only some exports used: x, y] + harmony import shared [6] ./node_modules/a.js 3:0-23 + harmony import shared [8] ./node_modules/c.js 6:0-30 +``` diff --git a/examples/scope-hoisting/build.js b/examples/scope-hoisting/build.js new file mode 100644 index 000000000..41c29c9d1 --- /dev/null +++ b/examples/scope-hoisting/build.js @@ -0,0 +1 @@ +require("../build-common"); \ No newline at end of file diff --git a/examples/scope-hoisting/example.js b/examples/scope-hoisting/example.js new file mode 100644 index 000000000..1db9365cf --- /dev/null +++ b/examples/scope-hoisting/example.js @@ -0,0 +1,6 @@ +import { a, x, y } from "a"; +import * as b from "b"; + +import("./lazy").then(function(lazy) { + console.log(a, b.a(), x, y, lazy.c, lazy.d.a, lazy.x, lazy.y); +}); diff --git a/examples/scope-hoisting/graph.png b/examples/scope-hoisting/graph.png new file mode 100644 index 000000000..46c6fbf9f Binary files /dev/null and b/examples/scope-hoisting/graph.png differ diff --git a/examples/scope-hoisting/graph.svg b/examples/scope-hoisting/graph.svg new file mode 100644 index 000000000..c18b625de --- /dev/null +++ b/examples/scope-hoisting/graph.svg @@ -0,0 +1,23 @@ +exampleabsharedshared2lazycdcjs \ No newline at end of file diff --git a/examples/scope-hoisting/graph2.png b/examples/scope-hoisting/graph2.png new file mode 100644 index 000000000..d8e410d5a Binary files /dev/null and b/examples/scope-hoisting/graph2.png differ diff --git a/examples/scope-hoisting/graph2.svg b/examples/scope-hoisting/graph2.svg new file mode 100644 index 000000000..bda1a325b --- /dev/null +++ b/examples/scope-hoisting/graph2.svg @@ -0,0 +1,40 @@ +Chunk AChunk Bexampleabsharedshared2lazycdcjs \ No newline at end of file diff --git a/examples/scope-hoisting/graph3.png b/examples/scope-hoisting/graph3.png new file mode 100644 index 000000000..d7075f910 Binary files /dev/null and b/examples/scope-hoisting/graph3.png differ diff --git a/examples/scope-hoisting/graph3.svg b/examples/scope-hoisting/graph3.svg new file mode 100644 index 000000000..c7f81ae7b --- /dev/null +++ b/examples/scope-hoisting/graph3.svg @@ -0,0 +1,46 @@ +Chunk AScope 1Scope 2Chunk BScope 3exampleabsharedshared2cjslazycd \ No newline at end of file diff --git a/examples/scope-hoisting/lazy.js b/examples/scope-hoisting/lazy.js new file mode 100644 index 000000000..f79a25dbb --- /dev/null +++ b/examples/scope-hoisting/lazy.js @@ -0,0 +1,3 @@ +export * from "c"; +import * as d from "d"; +export { d }; diff --git a/examples/scope-hoisting/node_modules/a.js b/examples/scope-hoisting/node_modules/a.js new file mode 100644 index 000000000..589bfadc4 --- /dev/null +++ b/examples/scope-hoisting/node_modules/a.js @@ -0,0 +1,3 @@ +// module a +export var a = "a"; +export * from "shared"; diff --git a/examples/scope-hoisting/node_modules/b.js b/examples/scope-hoisting/node_modules/b.js new file mode 100644 index 000000000..3b7c9a0c6 --- /dev/null +++ b/examples/scope-hoisting/node_modules/b.js @@ -0,0 +1,4 @@ +// module b +export function a() { + return "b"; +}; diff --git a/examples/scope-hoisting/node_modules/c.js b/examples/scope-hoisting/node_modules/c.js new file mode 100644 index 000000000..5db6ace1f --- /dev/null +++ b/examples/scope-hoisting/node_modules/c.js @@ -0,0 +1,6 @@ +// module c +import { c as e } from "cjs"; + +export var c = String.fromCharCode(e.charCodeAt(0) - 2); + +export { x, y } from "shared"; diff --git a/examples/scope-hoisting/node_modules/cjs.js b/examples/scope-hoisting/node_modules/cjs.js new file mode 100644 index 000000000..8a001e65b --- /dev/null +++ b/examples/scope-hoisting/node_modules/cjs.js @@ -0,0 +1,2 @@ +// module cjs (commonjs) +exports.c = "e"; diff --git a/examples/scope-hoisting/node_modules/d.js b/examples/scope-hoisting/node_modules/d.js new file mode 100644 index 000000000..f4e177035 --- /dev/null +++ b/examples/scope-hoisting/node_modules/d.js @@ -0,0 +1,2 @@ +// module d +export var a = "d"; diff --git a/examples/scope-hoisting/node_modules/shared.js b/examples/scope-hoisting/node_modules/shared.js new file mode 100644 index 000000000..2600e2340 --- /dev/null +++ b/examples/scope-hoisting/node_modules/shared.js @@ -0,0 +1,3 @@ +// shared module +export var x = "x"; +export * from "shared2"; diff --git a/examples/scope-hoisting/node_modules/shared2.js b/examples/scope-hoisting/node_modules/shared2.js new file mode 100644 index 000000000..38ea5bd24 --- /dev/null +++ b/examples/scope-hoisting/node_modules/shared2.js @@ -0,0 +1,2 @@ +// shared2 module +export var y = "y"; diff --git a/examples/scope-hoisting/template.md b/examples/scope-hoisting/template.md new file mode 100644 index 000000000..ff01791a1 --- /dev/null +++ b/examples/scope-hoisting/template.md @@ -0,0 +1,118 @@ +This example demonstrates Scope Hoisting in combination with Code Splitting. + +This is the dependency graph for the example: (solid lines express sync imports, dashed lines async imports) + +![](graph.png) + +All modules except `cjs` are EcmaScript modules. `cjs` is a CommonJs module. + +The interesting thing here is that putting all modules in single scope won't work, because of multiple reasons: + +* Modules `lazy`, `c`, `d` and `cjs` need to be in a separate chunk +* Module `shared` is accessed by two chunks (different scopes) +* Module `cjs` is a CommonJs module + +![](graph2.png) + +webpack therefore uses a approach called **"Partial Scope Hoisting"** or "Module concatenation", which chooses the largest possible subsets of ES modules which can be scope hoisted and combines them with the default webpack primitives. + +![](graph3.png) + +While module concatentation identifiers in modules are renamed to avoid conflicts and internal imports are simplified. External imports and exports from the root module use the existing ESM constructs. + +# example.js + +``` javascript +{{example.js}} +``` + +# lazy.js + +``` javascript +{{lazy.js}} +``` + +# a.js + +``` javascript +{{node_modules/a.js}} +``` + +# b.js + +``` javascript +{{node_modules/b.js}} +``` + +# c.js + +``` javascript +{{node_modules/c.js}} +``` + +# d.js + +``` javascript +{{node_modules/d.js}} +``` + +# cjs.js + +``` javascript +{{node_modules/cjs.js}} +``` + +# shared.js + +``` javascript +{{node_modules/shared.js}} +``` + +# shared2.js + +``` javascript +{{node_modules/shared2.js}} +``` + + + +# webpack.config.js + +``` javascript +{{webpack.config.js}} +``` + + + + +# js/output.js + +``` javascript +{{js/output.js}} +``` + +# js/0.output.js + +``` javascript +{{js/0.output.js}} +``` + +Minimized + +``` javascript +{{min:js/0.output.js}} +``` + +# Info + +## Uncompressed + +``` +{{stdout}} +``` + +## Minimized (uglify-js, no zip) + +``` +{{min:stdout}} +``` diff --git a/examples/scope-hoisting/webpack.config.js b/examples/scope-hoisting/webpack.config.js new file mode 100644 index 000000000..da883a7c1 --- /dev/null +++ b/examples/scope-hoisting/webpack.config.js @@ -0,0 +1,7 @@ +var webpack = require("../../"); + +module.exports = { + plugins: [ + new webpack.optimize.ModuleConcatenationPlugin() + ] +}; diff --git a/lib/AsyncDependenciesBlock.js b/lib/AsyncDependenciesBlock.js index d21218895..e8ff2daae 100644 --- a/lib/AsyncDependenciesBlock.js +++ b/lib/AsyncDependenciesBlock.js @@ -37,17 +37,7 @@ module.exports = class AsyncDependenciesBlock extends DependenciesBlock { sortItems() { super.sortItems(); if(this.chunks) { - this.chunks.sort((a, b) => { - let i = 0; - while(true) { // eslint-disable-line no-constant-condition - if(!a.modules[i] && !b.modules[i]) return 0; - if(!a.modules[i]) return -1; - if(!b.modules[i]) return 1; - if(a.modules[i].id > b.modules[i].id) return 1; - if(a.modules[i].id < b.modules[i].id) return -1; - i++; - } - }); + this.chunks.sort((a, b) => a.compareTo(b)); } } }; diff --git a/lib/Chunk.js b/lib/Chunk.js index 5bfb2910e..a7939b050 100644 --- a/lib/Chunk.js +++ b/lib/Chunk.js @@ -4,6 +4,7 @@ */ "use strict"; +const util = require("util"); const compareLocations = require("./compareLocations"); let debugId = 1000; @@ -20,7 +21,8 @@ class Chunk { this.ids = null; this.debugId = debugId++; this.name = name; - this.modules = []; + this._modules = new Set(); + this._modulesIsSorted = true; this.entrypoints = []; this.chunks = []; this.parents = []; @@ -88,7 +90,12 @@ class Chunk { } addModule(module) { - return this.addToCollection(this.modules, module); + if(!this._modules.has(module)) { + this._modules.add(module); + this._modulesIsSorted = false; + return true; + } + return false; } addBlock(block) { @@ -96,9 +103,7 @@ class Chunk { } removeModule(module) { - const idx = this.modules.indexOf(module); - if(idx >= 0) { - this.modules.splice(idx, 1); + if(this._modules.delete(module)) { module.removeChunk(this); return true; } @@ -133,9 +138,76 @@ class Chunk { }); } + setModules(modules) { + this._modules = new Set(modules); + this._modulesIsSorted = false; + } + + getNumberOfModules() { + return this._modules.size; + } + + get modulesIterable() { + return this._modules; + } + + forEachModule(fn) { + this._modules.forEach(fn); + } + + mapModules(fn) { + return Array.from(this._modules, fn); + } + + _ensureModulesSorted() { + if(this._modulesIsSorted) return; + this._modules = new Set(Array.from(this._modules).sort((a, b) => { + if(a.identifier() > b.identifier()) return 1; + if(a.identifier() < b.identifier()) return -1; + return 0; + })); + this._modulesIsSorted = true; + } + + compareTo(otherChunk) { + this._ensureModulesSorted(); + otherChunk._ensureModulesSorted(); + if(this._modules.size > otherChunk._modules.size) return -1; + if(this._modules.size < otherChunk._modules.size) return 1; + const a = this._modules[Symbol.iterator](); + const b = otherChunk._modules[Symbol.iterator](); + while(true) { // eslint-disable-line + const aItem = a.next(); + const bItem = b.next(); + if(aItem.done) return 0; + const aModuleIdentifier = aItem.value.identifier(); + const bModuleIdentifier = bItem.value.identifier(); + if(aModuleIdentifier > bModuleIdentifier) return -1; + if(aModuleIdentifier < bModuleIdentifier) return 1; + } + } + + containsModule(module) { + return this._modules.has(module); + } + + getModules() { + return Array.from(this._modules); + } + + getModulesIdent() { + this._ensureModulesSorted(); + let str = ""; + this._modules.forEach(m => { + str += m.identifier() + "#"; + }); + return str; + } + remove(reason) { // cleanup modules - this.modules.slice().forEach(module => { + // Array.from is used here to create a clone, because removeChunk modifies this._modules + Array.from(this._modules).forEach(module => { module.removeChunk(this); }); @@ -219,9 +291,10 @@ class Chunk { return false; } - const otherChunkModules = otherChunk.modules.slice(); + // Array.from is used here to create a clone, because moveModule modifies otherChunk._modules + const otherChunkModules = Array.from(otherChunk._modules); otherChunkModules.forEach(module => otherChunk.moveModule(module, this)); - otherChunk.modules.length = 0; + otherChunk._modules.clear(); otherChunk.parents.forEach(parentChunk => parentChunk.replaceChunk(otherChunk, this)); otherChunk.parents.length = 0; @@ -276,14 +349,14 @@ class Chunk { } isEmpty() { - return this.modules.length === 0; + return this._modules.size === 0; } updateHash(hash) { hash.update(`${this.id} `); hash.update(this.ids ? this.ids.join(",") : ""); hash.update(`${this.name || ""} `); - this.modules.forEach(m => m.updateHash(hash)); + this._modules.forEach(m => m.updateHash(hash)); } canBeIntegrated(otherChunk) { @@ -307,8 +380,8 @@ class Chunk { modulesSize() { let count = 0; - for(let i = 0; i < this.modules.length; i++) { - count += this.modules[i].size(); + for(const module of this._modules) { + count += module.size(); } return count; } @@ -325,9 +398,8 @@ class Chunk { let integratedModulesSize = this.modulesSize(); // only count modules that do not exist in this chunk! - for(let i = 0; i < otherChunk.modules.length; i++) { - const otherModule = otherChunk.modules[i]; - if(this.modules.indexOf(otherModule) === -1) { + for(const otherModule of otherChunk._modules) { + if(!this._modules.has(otherModule)) { integratedModulesSize += otherModule.size(); } } @@ -356,7 +428,7 @@ class Chunk { } sortItems() { - this.modules.sort(byId); + this._modules = new Set(Array.from(this._modules).sort(byId)); this.origins.sort((a, b) => { const aIdent = a.module.identifier(); const bIdent = b.module.identifier(); @@ -373,7 +445,7 @@ class Chunk { } toString() { - return `Chunk[${this.modules.join()}]`; + return `Chunk[${Array.from(this._modules).join()}]`; } checkConstraints() { @@ -393,4 +465,14 @@ class Chunk { } } +Object.defineProperty(Chunk.prototype, "modules", { + configurable: false, + get: util.deprecate(function() { + return Array.from(this._modules); + }, "Chunk.modules is deprecated. Use Chunk.getNumberOfModules/mapModules/forEachModule/containsModule instead."), + set: util.deprecate(function(value) { + this.setModules(value); + }, "Chunk.modules is deprecated. Use Chunk.addModule/removeModule instead.") +}); + module.exports = Chunk; diff --git a/lib/Compilation.js b/lib/Compilation.js index bdc4f0368..16d0dfdc6 100644 --- a/lib/Compilation.js +++ b/lib/Compilation.js @@ -80,6 +80,7 @@ class Compilation extends Tapable { this.children = []; this.dependencyFactories = new Map(); this.dependencyTemplates = new Map(); + this.childrenCounters = {}; } getStats() { @@ -511,7 +512,7 @@ class Compilation extends Tapable { if(err) return callback(err); deps.forEach(d => { if(d.module && d.module.removeReason(module, d)) { - module.chunks.forEach(chunk => { + module.forEachChunk(chunk => { if(!d.module.hasReasonForChunk(chunk)) { if(d.module.removeChunk(chunk)) { this.removeChunkFromDependencies(d.module, chunk); @@ -568,12 +569,12 @@ class Compilation extends Tapable { while(self.applyPluginsBailResult1("optimize-modules-basic", self.modules) || self.applyPluginsBailResult1("optimize-modules", self.modules) || - self.applyPluginsBailResult1("optimize-modules-advanced", self.modules)); // eslint-disable-line no-extra-semi + self.applyPluginsBailResult1("optimize-modules-advanced", self.modules)) { /* empty */ } self.applyPlugins1("after-optimize-modules", self.modules); while(self.applyPluginsBailResult1("optimize-chunks-basic", self.chunks) || self.applyPluginsBailResult1("optimize-chunks", self.chunks) || - self.applyPluginsBailResult1("optimize-chunks-advanced", self.chunks)); // eslint-disable-line no-extra-semi + self.applyPluginsBailResult1("optimize-chunks-advanced", self.chunks)) { /* empty */ } self.applyPlugins1("after-optimize-chunks", self.chunks); self.applyPluginsAsyncSeries("optimize-tree", self.chunks, self.modules, function sealPart2(err) { @@ -583,6 +584,11 @@ class Compilation extends Tapable { self.applyPlugins2("after-optimize-tree", self.chunks, self.modules); + while(self.applyPluginsBailResult("optimize-chunk-modules-basic", self.chunks, self.modules) || + self.applyPluginsBailResult("optimize-chunk-modules", self.chunks, self.modules) || + self.applyPluginsBailResult("optimize-chunk-modules-advanced", self.chunks, self.modules)) { /* empty */ } + self.applyPlugins2("after-optimize-chunk-modules", self.chunks, self.modules); + const shouldRecord = self.applyPluginsBailResult("should-record") !== false; self.applyPlugins2("revive-modules", self.modules, self.records); @@ -1017,7 +1023,7 @@ class Compilation extends Tapable { const modules = this.modules; for(let indexModule = 0; indexModule < modules.length; indexModule++) { - modules[indexModule].sortItems(); + modules[indexModule].sortItems(false); } const chunks = this.chunks; @@ -1031,7 +1037,7 @@ class Compilation extends Tapable { const modules = this.modules; for(let indexModule = 0; indexModule < modules.length; indexModule++) { - modules[indexModule].sortItems(); + modules[indexModule].sortItems(true); } const chunks = this.chunks; @@ -1218,8 +1224,10 @@ class Compilation extends Tapable { return this.mainTemplate.applyPluginsWaterfall("asset-path", filename, data); } - createChildCompiler(name, outputOptions) { - return this.compiler.createChildCompiler(this, name, outputOptions); + createChildCompiler(name, outputOptions, plugins) { + var idx = (this.childrenCounters[name] || 0); + this.childrenCounters[name] = idx + 1; + return this.compiler.createChildCompiler(this, name, idx, outputOptions, plugins); } checkConstraints() { diff --git a/lib/Compiler.js b/lib/Compiler.js index 5b1132cad..3bccde6f4 100644 --- a/lib/Compiler.js +++ b/lib/Compiler.js @@ -10,6 +10,8 @@ var Stats = require("./Stats"); var NormalModuleFactory = require("./NormalModuleFactory"); var ContextModuleFactory = require("./ContextModuleFactory"); +var makePathsRelative = require("./util/identifier").makePathsRelative; + function Watching(compiler, watchOptions, handler) { this.startTime = null; this.invalid = false; @@ -407,7 +409,7 @@ Compiler.prototype.readRecords = function readRecords(callback) { }); }; -Compiler.prototype.createChildCompiler = function(compilation, compilerName, outputOptions, plugins) { +Compiler.prototype.createChildCompiler = function(compilation, compilerName, compilerIndex, outputOptions, plugins) { var childCompiler = new Compiler(); if(Array.isArray(plugins)) { plugins.forEach(plugin => childCompiler.apply(plugin)); @@ -423,8 +425,23 @@ Compiler.prototype.createChildCompiler = function(compilation, compilerName, out childCompiler.resolvers = this.resolvers; childCompiler.fileTimestamps = this.fileTimestamps; childCompiler.contextTimestamps = this.contextTimestamps; - if(!this.records[compilerName]) this.records[compilerName] = []; - this.records[compilerName].push(childCompiler.records = {}); + + var relativeCompilerName = makePathsRelative(this.context, compilerName); + if(!this.records[relativeCompilerName]) this.records[relativeCompilerName] = []; + if(this.records[relativeCompilerName][compilerIndex]) + childCompiler.records = this.records[relativeCompilerName][compilerIndex]; + else + this.records[relativeCompilerName].push(childCompiler.records = {}); + + if(this.cache) { + if(!this.cache.children) this.cache.children = {}; + if(!this.cache.children[compilerName]) this.cache.children[compilerName] = []; + if(this.cache.children[compilerName][compilerIndex]) + childCompiler.cache = this.cache.children[compilerName][compilerIndex]; + else + this.cache.children[compilerName].push(childCompiler.cache = {}); + } + childCompiler.options = Object.create(this.options); childCompiler.options.output = Object.create(childCompiler.options.output); for(name in outputOptions) { diff --git a/lib/DefinePlugin.js b/lib/DefinePlugin.js index c3a810c62..6b4362d76 100644 --- a/lib/DefinePlugin.js +++ b/lib/DefinePlugin.js @@ -35,7 +35,7 @@ class DefinePlugin { }(definitions, "")); function stringifyObj(obj) { - return "__webpack_require__.i({" + Object.keys(obj).map((key) => { + return "Object({" + Object.keys(obj).map((key) => { const code = obj[key]; return JSON.stringify(key) + ":" + toCode(code); }).join(",") + "})"; diff --git a/lib/FlagInitialModulesAsUsedPlugin.js b/lib/FlagInitialModulesAsUsedPlugin.js index 64d084270..ae81f8b9b 100644 --- a/lib/FlagInitialModulesAsUsedPlugin.js +++ b/lib/FlagInitialModulesAsUsedPlugin.js @@ -12,7 +12,7 @@ class FlagInitialModulesAsUsedPlugin { if(!chunk.isInitial()) { return; } - chunk.modules.forEach((module) => { + chunk.forEachModule((module) => { module.usedExports = true; }); }); diff --git a/lib/FunctionModuleTemplatePlugin.js b/lib/FunctionModuleTemplatePlugin.js index 00d7a6bc0..344943c0b 100644 --- a/lib/FunctionModuleTemplatePlugin.js +++ b/lib/FunctionModuleTemplatePlugin.js @@ -25,17 +25,23 @@ class FunctionModuleTemplatePlugin { if(this.outputOptions.pathinfo) { const source = new ConcatSource(); const req = module.readableIdentifier(this.requestShortener); - if(Array.isArray(module.providedExports)) - source.add("/* exports provided: " + module.providedExports.join(", ") + " */\n"); - else if(module.providedExports) - source.add("/* no static exports found */\n"); - if(Array.isArray(module.usedExports)) - source.add("/* exports used: " + module.usedExports.join(", ") + " */\n"); - else if(module.usedExports) - source.add("/* all exports used */\n"); source.add("/*!****" + req.replace(/./g, "*") + "****!*\\\n"); source.add(" !*** " + req.replace(/\*\//g, "*_/") + " ***!\n"); source.add(" \\****" + req.replace(/./g, "*") + "****/\n"); + if(Array.isArray(module.providedExports)) + source.add("/*! exports provided: " + module.providedExports.join(", ") + " */\n"); + else if(module.providedExports) + source.add("/*! no static exports found */\n"); + if(Array.isArray(module.usedExports)) + source.add("/*! exports used: " + module.usedExports.join(", ") + " */\n"); + else if(module.usedExports) + source.add("/*! all exports used */\n"); + if(module.optimizationBailout) { + module.optimizationBailout.forEach(text => { + if(typeof text === "function") text = text(this.requestShortener); + source.add(`/*! ${text} */\n`); + }); + } source.add(moduleSource); return source; } diff --git a/lib/HotModuleReplacementPlugin.js b/lib/HotModuleReplacementPlugin.js index ea9b77068..8cab661c7 100644 --- a/lib/HotModuleReplacementPlugin.js +++ b/lib/HotModuleReplacementPlugin.js @@ -56,7 +56,7 @@ HotModuleReplacementPlugin.prototype.apply = function(compiler) { }); records.chunkModuleIds = {}; this.chunks.forEach(function(chunk) { - records.chunkModuleIds[chunk.id] = chunk.modules.map(function(m) { + records.chunkModuleIds[chunk.id] = chunk.mapModules(function(m) { return m.id; }); }); @@ -114,11 +114,11 @@ HotModuleReplacementPlugin.prototype.apply = function(compiler) { chunkId = isNaN(+chunkId) ? chunkId : +chunkId; var currentChunk = this.chunks.find(chunk => chunk.id === chunkId); if(currentChunk) { - var newModules = currentChunk.modules.filter(function(module) { + var newModules = currentChunk.getModules().filter(function(module) { return module.hotUpdate; }); var allModules = {}; - currentChunk.modules.forEach(function(module) { + currentChunk.forEachModule(function(module) { allModules[module.id] = true; }); var removedModules = records.chunkModuleIds[chunkId].filter(function(id) { diff --git a/lib/HotUpdateChunkTemplate.js b/lib/HotUpdateChunkTemplate.js index e32e5cccb..84b366a08 100644 --- a/lib/HotUpdateChunkTemplate.js +++ b/lib/HotUpdateChunkTemplate.js @@ -5,6 +5,7 @@ "use strict"; const Template = require("./Template"); +const Chunk = require("./Chunk"); module.exports = class HotUpdateChunkTemplate extends Template { constructor(outputOptions) { @@ -12,11 +13,11 @@ module.exports = class HotUpdateChunkTemplate extends Template { } render(id, modules, removedModules, hash, moduleTemplate, dependencyTemplates) { - const modulesSource = this.renderChunkModules({ - id: id, - modules: modules, - removedModules: removedModules - }, moduleTemplate, dependencyTemplates); + const hotUpdateChunk = new Chunk(); + hotUpdateChunk.id = id; + hotUpdateChunk.setModules(modules); + hotUpdateChunk.removedModules = removedModules; + const modulesSource = this.renderChunkModules(hotUpdateChunk, moduleTemplate, dependencyTemplates); const core = this.applyPluginsWaterfall("modules", modulesSource, modules, removedModules, moduleTemplate, dependencyTemplates); const source = this.applyPluginsWaterfall("render", core, modules, removedModules, hash, id, moduleTemplate, dependencyTemplates); return source; diff --git a/lib/LibManifestPlugin.js b/lib/LibManifestPlugin.js index c72fd3e6d..db6877978 100644 --- a/lib/LibManifestPlugin.js +++ b/lib/LibManifestPlugin.js @@ -30,21 +30,26 @@ class LibManifestPlugin { const manifest = { name, type: this.options.type, - content: chunk.modules.reduce((obj, module) => { + content: chunk.mapModules(module => { if(module.libIdent) { const ident = module.libIdent({ context: this.options.context || compiler.options.context }); if(ident) { - obj[ident] = { - id: module.id, - meta: module.meta, - exports: Array.isArray(module.providedExports) ? module.providedExports : undefined + return { + ident, + data: { + id: module.id, + meta: module.meta, + exports: Array.isArray(module.providedExports) ? module.providedExports : undefined + } }; } } + }).filter(Boolean).reduce((obj, item) => { + obj[item.ident] = item.data; return obj; - }, {}) + }, Object.create(null)) }; const content = new Buffer(JSON.stringify(manifest), "utf8"); //eslint-disable-line compiler.outputFileSystem.mkdirp(path.dirname(targetPath), err => { diff --git a/lib/MainTemplate.js b/lib/MainTemplate.js index c76cff5e0..8eacc004a 100644 --- a/lib/MainTemplate.js +++ b/lib/MainTemplate.js @@ -114,10 +114,6 @@ module.exports = class MainTemplate extends Template { buf.push("// expose the module cache"); buf.push(`${this.requireFn}.c = installedModules;`); - buf.push(""); - buf.push("// identity function for calling harmony imports with the correct context"); - buf.push(`${this.requireFn}.i = function(value) { return value; };`); - buf.push(""); buf.push("// define getter function for harmony exports"); buf.push(`${this.requireFn}.d = function(exports, name, getter) {`); diff --git a/lib/Module.js b/lib/Module.js index befe47b47..7592ba263 100644 --- a/lib/Module.js +++ b/lib/Module.js @@ -4,12 +4,13 @@ */ "use strict"; +const util = require("util"); const DependenciesBlock = require("./DependenciesBlock"); const ModuleReason = require("./ModuleReason"); const Template = require("./Template"); function addToSet(set, items) { - for(let item of items) { + for(const item of items) { if(set.indexOf(item) < 0) set.push(item); } @@ -19,6 +20,10 @@ function byId(a, b) { return a.id - b.id; } +function byDebugId(a, b) { + return a.debugId - b.debugId; +} + let debugId = 1000; class Module extends DependenciesBlock { @@ -36,13 +41,17 @@ class Module extends DependenciesBlock { this.used = null; this.usedExports = null; this.providedExports = null; - this.chunks = []; + this._chunks = new Set(); + this._chunksIsSorted = true; + this._chunksIsSortedByDebugId = true; + this._chunksDebugIdent = undefined; this.warnings = []; this.dependenciesWarnings = []; this.errors = []; this.dependenciesErrors = []; this.strict = false; this.meta = {}; + this.optimizationBailout = []; } disconnect() { @@ -55,7 +64,9 @@ class Module extends DependenciesBlock { this.used = null; this.usedExports = null; this.providedExports = null; - this.chunks.length = 0; + this._chunks.clear(); + this._chunksDebugIdent = undefined; + this._chunksIsSorted = this._chunksIsSortedByDebugId = false; super.disconnect(); } @@ -65,26 +76,75 @@ class Module extends DependenciesBlock { this.index = null; this.index2 = null; this.depth = null; - this.chunks.length = 0; + this._chunks.clear(); + this._chunksDebugIdent = undefined; + this._chunksIsSorted = this._chunksIsSortedByDebugId = false; super.unseal(); } addChunk(chunk) { - let idx = this.chunks.indexOf(chunk); - if(idx < 0) - this.chunks.push(chunk); + this._chunks.add(chunk); + this._chunksDebugIdent = undefined; + this._chunksIsSorted = this._chunksIsSortedByDebugId = false; } removeChunk(chunk) { - let idx = this.chunks.indexOf(chunk); - if(idx >= 0) { - this.chunks.splice(idx, 1); + if(this._chunks.delete(chunk)) { + this._chunksDebugIdent = undefined; chunk.removeModule(this); return true; } return false; } + isInChunk(chunk) { + return this._chunks.has(chunk); + } + + getChunkIdsIdent() { + if(this._chunksDebugIdent !== undefined) return this._chunksDebugIdent; + this._ensureChunksSortedByDebugId(); + const chunks = this._chunks; + const list = []; + for(const chunk of chunks) { + const debugId = chunk.debugId; + + if(typeof debugId !== "number") { + return this._chunksDebugIdent = null; + } + + list.push(debugId); + } + + return this._chunksDebugIdent = list.join(","); + } + + forEachChunk(fn) { + this._chunks.forEach(fn); + } + + mapChunks(fn) { + return Array.from(this._chunks, fn); + } + + getNumberOfChunks() { + return this._chunks.size; + } + + _ensureChunksSorted() { + if(this._chunksIsSorted) return; + this._chunks = new Set(Array.from(this._chunks).sort(byId)); + this._chunksIsSortedByDebugId = false; + this._chunksIsSorted = true; + } + + _ensureChunksSortedByDebugId() { + if(this._chunksIsSortedByDebugId) return; + this._chunks = new Set(Array.from(this._chunks).sort(byDebugId)); + this._chunksIsSorted = false; + this._chunksIsSortedByDebugId = true; + } + addReason(module, dependency) { this.reasons.push(new ModuleReason(module, dependency)); } @@ -101,11 +161,11 @@ class Module extends DependenciesBlock { } hasReasonForChunk(chunk) { - for(let r of this.reasons) { + for(const r of this.reasons) { if(r.chunks) { if(r.chunks.indexOf(chunk) >= 0) return true; - } else if(r.module.chunks.indexOf(chunk) >= 0) + } else if(r.module._chunks.has(chunk)) return true; } return false; @@ -114,9 +174,9 @@ class Module extends DependenciesBlock { rewriteChunkInReasons(oldChunk, newChunks) { this.reasons.forEach(r => { if(!r.chunks) { - if(r.module.chunks.indexOf(oldChunk) < 0) + if(!r.module._chunks.has(oldChunk)) return; - r.chunks = r.module.chunks; + r.chunks = Array.from(r.module._chunks); } r.chunks = r.chunks.reduce((arr, c) => { addToSet(arr, c !== oldChunk ? [c] : newChunks); @@ -158,9 +218,10 @@ class Module extends DependenciesBlock { super.updateHash(hash); } - sortItems() { + sortItems(sortChunks) { super.sortItems(); - this.chunks.sort(byId); + if(sortChunks) + this._ensureChunksSorted(); this.reasons.sort((a, b) => byId(a.module, b.module)); if(Array.isArray(this.usedExports)) { this.usedExports.sort(); @@ -181,6 +242,17 @@ Object.defineProperty(Module.prototype, "entry", { throw new Error("Module.entry was removed. Use Chunk.entryModule"); } }); + +Object.defineProperty(Module.prototype, "chunks", { + configurable: false, + get: util.deprecate(() => { + return Array.from(this._chunks); + }, "Module.chunks: Use Module.forEachChunk/mapChunks/getNumberOfChunks/isInChunk/addChunk/removeChunk instead"), + set() { + throw new Error("Readonly. Use Module.addChunk/removeChunk to modify chunks."); + } +}); + Module.prototype.identifier = null; Module.prototype.readableIdentifier = null; Module.prototype.build = null; diff --git a/lib/ModuleFilenameHelpers.js b/lib/ModuleFilenameHelpers.js index 9fe569847..59010dee5 100644 --- a/lib/ModuleFilenameHelpers.js +++ b/lib/ModuleFilenameHelpers.js @@ -112,7 +112,7 @@ ModuleFilenameHelpers.createFooter = function createFooter(module, requestShorte "// WEBPACK FOOTER", `// ${module.readableIdentifier(requestShortener)}`, `// module id = ${module.id}`, - `// module chunks = ${module.chunks.map(c => c.id).join(" ")}` + `// module chunks = ${module.mapChunks(c => c.id).join(" ")}` ].join("\n"); } }; diff --git a/lib/NormalModule.js b/lib/NormalModule.js index 3f36ba1dd..cf6160c35 100644 --- a/lib/NormalModule.js +++ b/lib/NormalModule.js @@ -74,6 +74,7 @@ class NormalModule extends Module { this.assets = {}; this.built = false; this._cachedSource = null; + this._dependencyTemplatesHashMap = new Map(); } identifier() { @@ -305,9 +306,13 @@ class NormalModule extends Module { }); } - getHashDigest() { + getHashDigest(dependencyTemplates) { + let dtId = this._dependencyTemplatesHashMap.get(dependencyTemplates); + if(dtId === undefined) + this._dependencyTemplatesHashMap.set(dependencyTemplates, dtId = this._dependencyTemplatesHashMap.size + 1); const hash = crypto.createHash("md5"); this.updateHash(hash); + hash.update(`${dtId}`); return hash.digest("hex"); } @@ -441,7 +446,7 @@ class NormalModule extends Module { } source(dependencyTemplates, outputOptions, requestShortener) { - const hashDigest = this.getHashDigest(); + const hashDigest = this.getHashDigest(dependencyTemplates); if(this._cachedSource && this._cachedSource.hash === hashDigest) { return this._cachedSource.source; } diff --git a/lib/Parser.js b/lib/Parser.js index 11f72412d..1bfcc7c7c 100644 --- a/lib/Parser.js +++ b/lib/Parser.js @@ -17,10 +17,12 @@ function joinRanges(startRange, endRange) { return [startRange[0], endRange[1]]; } +const ECMA_VERSION = 2017; + const POSSIBLE_AST_OPTIONS = [{ ranges: true, locations: true, - ecmaVersion: 2017, + ecmaVersion: ECMA_VERSION, sourceType: "module", plugins: { dynamicImport: true @@ -28,7 +30,7 @@ const POSSIBLE_AST_OPTIONS = [{ }, { ranges: true, locations: true, - ecmaVersion: 2017, + ecmaVersion: ECMA_VERSION, sourceType: "script", plugins: { dynamicImport: true @@ -1110,6 +1112,12 @@ class Parser extends Tapable { result = this.applyPluginsBailResult1("call " + callee.identifier, expression); if(result === true) return; + let identifier = callee.identifier.replace(/\.[^\.]+$/, ".*"); + if(identifier !== callee.identifier) { + result = this.applyPluginsBailResult1("call " + identifier, expression); + if(result === true) + return; + } } if(expression.callee) @@ -1335,7 +1343,7 @@ class Parser extends Tapable { ast = acorn.parse(source, { ranges: true, locations: true, - ecmaVersion: 2017, + ecmaVersion: ECMA_VERSION, sourceType: "module", plugins: { dynamicImport: true @@ -1369,7 +1377,7 @@ class Parser extends Tapable { const ast = acorn.parse("(" + source + ")", { ranges: true, locations: true, - ecmaVersion: 2017, + ecmaVersion: ECMA_VERSION, sourceType: "module", plugins: { dynamicImport: true @@ -1401,4 +1409,6 @@ class Parser extends Tapable { } +Parser.ECMA_VERSION = ECMA_VERSION; + module.exports = Parser; diff --git a/lib/ProgressPlugin.js b/lib/ProgressPlugin.js index 19ded4690..f0bad2fad 100644 --- a/lib/ProgressPlugin.js +++ b/lib/ProgressPlugin.js @@ -82,17 +82,19 @@ class ProgressPlugin { "optimize-chunks": [0.77, "chunk optimization"], "optimize-chunks-advanced": [0.78, "advanced chunk optimization"], // optimize-tree - "revive-modules": [0.80, "module reviving"], - "optimize-module-order": [0.81, "module order optimization"], - "optimize-module-ids": [0.82, "module id optimization"], - "revive-chunks": [0.83, "chunk reviving"], - "optimize-chunk-order": [0.84, "chunk order optimization"], - "optimize-chunk-ids": [0.85, "chunk id optimization"], - "before-hash": [0.86, "hashing"], - "before-module-assets": [0.87, "module assets processing"], - "before-chunk-assets": [0.88, "chunk assets processing"], - "additional-chunk-assets": [0.89, "additional chunk assets processing"], - "record": [0.90, "recording"] + "optimize-chunk-modules": [0.80, "chunk modules optimization"], + "optimize-chunk-modules-advanced": [0.81, "advanced chunk modules optimization"], + "revive-modules": [0.82, "module reviving"], + "optimize-module-order": [0.83, "module order optimization"], + "optimize-module-ids": [0.84, "module id optimization"], + "revive-chunks": [0.85, "chunk reviving"], + "optimize-chunk-order": [0.86, "chunk order optimization"], + "optimize-chunk-ids": [0.87, "chunk id optimization"], + "before-hash": [0.88, "hashing"], + "before-module-assets": [0.89, "module assets processing"], + "before-chunk-assets": [0.90, "chunk assets processing"], + "additional-chunk-assets": [0.91, "additional chunk assets processing"], + "record": [0.92, "recording"] }; Object.keys(syncHooks).forEach(name => { let pass = 0; diff --git a/lib/RequestShortener.js b/lib/RequestShortener.js index 6423c21ae..b704031b2 100644 --- a/lib/RequestShortener.js +++ b/lib/RequestShortener.js @@ -32,7 +32,6 @@ class RequestShortener { this.buildinsRegExp = new RegExp("^" + buildinsRegExpString + "|(!)" + buildinsRegExpString, "g"); } - this.nodeModulesRegExp = /\/node_modules\//g; this.indexJsRegExp = /\/index.js(!|\?|\(query\))/g; } @@ -47,7 +46,6 @@ class RequestShortener { request = request.replace(this.parentDirectoryRegExp, "!.."); if(!this.buildinsAsModule && this.buildinsRegExp) request = request.replace(this.buildinsRegExp, "!(webpack)"); - request = request.replace(this.nodeModulesRegExp, "/~/"); request = request.replace(this.indexJsRegExp, "$1"); return request.replace(/^!|!$/, ""); } diff --git a/lib/Stats.js b/lib/Stats.js index 7e869a0cf..75ec6bd4f 100644 --- a/lib/Stats.js +++ b/lib/Stats.js @@ -8,7 +8,7 @@ const RequestShortener = require("./RequestShortener"); const SizeFormatHelpers = require("./SizeFormatHelpers"); const formatLocation = require("./formatLocation"); -const optionOrFallback = (optionValue, fallbackValue) => optionValue !== undefined ? optionValue : fallbackValue; +const optionOrFallback = (optionValue, fallbackValue) => typeof optionValue !== "undefined" ? optionValue : fallbackValue; class Stats { constructor(compilation) { @@ -75,50 +75,62 @@ class Stats { options = {}; } + const optionOrLocalFallback = (v, def) => + typeof v !== "undefined" ? v : + typeof options.all !== "undefined" ? options.all : def; + const compilation = this.compilation; const requestShortener = new RequestShortener(optionOrFallback(options.context, process.cwd())); - const showPerformance = optionOrFallback(options.performance, true); - const showHash = optionOrFallback(options.hash, true); - const showVersion = optionOrFallback(options.version, true); - const showTimings = optionOrFallback(options.timings, true); - const showAssets = optionOrFallback(options.assets, true); - const showEntrypoints = optionOrFallback(options.entrypoints, !forToString); - const showChunks = optionOrFallback(options.chunks, true); - const showChunkModules = optionOrFallback(options.chunkModules, !!forToString); - const showChunkOrigins = optionOrFallback(options.chunkOrigins, !forToString); - const showModules = optionOrFallback(options.modules, !forToString); - const showDepth = optionOrFallback(options.depth, !forToString); - const showCachedModules = optionOrFallback(options.cached, true); - const showCachedAssets = optionOrFallback(options.cachedAssets, true); - const showReasons = optionOrFallback(options.reasons, !forToString); - const showUsedExports = optionOrFallback(options.usedExports, !forToString); - const showProvidedExports = optionOrFallback(options.providedExports, !forToString); - const showChildren = optionOrFallback(options.children, true); - const showSource = optionOrFallback(options.source, !forToString); - const showModuleTrace = optionOrFallback(options.moduleTrace, true); - const showErrors = optionOrFallback(options.errors, true); - const showErrorDetails = optionOrFallback(options.errorDetails, !forToString); - const showWarnings = optionOrFallback(options.warnings, true); + const showPerformance = optionOrLocalFallback(options.performance, true); + const showHash = optionOrLocalFallback(options.hash, true); + const showVersion = optionOrLocalFallback(options.version, true); + const showTimings = optionOrLocalFallback(options.timings, true); + const showAssets = optionOrLocalFallback(options.assets, true); + const showEntrypoints = optionOrLocalFallback(options.entrypoints, !forToString); + const showChunks = optionOrLocalFallback(options.chunks, !forToString); + const showChunkModules = optionOrLocalFallback(options.chunkModules, !!forToString); + const showChunkOrigins = optionOrLocalFallback(options.chunkOrigins, !forToString); + const showModules = optionOrLocalFallback(options.modules, true); + const showDepth = optionOrLocalFallback(options.depth, !forToString); + const showCachedModules = optionOrLocalFallback(options.cached, true); + const showCachedAssets = optionOrLocalFallback(options.cachedAssets, true); + const showReasons = optionOrLocalFallback(options.reasons, !forToString); + const showUsedExports = optionOrLocalFallback(options.usedExports, !forToString); + const showProvidedExports = optionOrLocalFallback(options.providedExports, !forToString); + const showOptimizationBailout = optionOrLocalFallback(options.optimizationBailout, !forToString); + const showChildren = optionOrLocalFallback(options.children, true); + const showSource = optionOrLocalFallback(options.source, !forToString); + const showModuleTrace = optionOrLocalFallback(options.moduleTrace, true); + const showErrors = optionOrLocalFallback(options.errors, true); + const showErrorDetails = optionOrLocalFallback(options.errorDetails, !forToString); + const showWarnings = optionOrLocalFallback(options.warnings, true); const warningsFilter = optionOrFallback(options.warningsFilter, null); - const showPublicPath = optionOrFallback(options.publicPath, !forToString); - const excludeModules = [].concat(optionOrFallback(options.exclude, [])).map(str => { - if(typeof str !== "string") return str; - return new RegExp(`[\\\\/]${str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&")}([\\\\/]|$|!|\\?)`); + const showPublicPath = optionOrLocalFallback(options.publicPath, !forToString); + const excludeModules = [].concat(optionOrFallback(options.exclude, [])).map(item => { + if(typeof item === "string") { + const regExp = new RegExp(`[\\\\/]${item.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&")}([\\\\/]|$|!|\\?)`); + return ident => regExp.test(ident); + } + if(item && typeof item === "object" && typeof item.test === "function") + return ident => item.test(ident); + if(typeof item === "function") + return item; }); const maxModules = optionOrFallback(options.maxModules, forToString ? 15 : Infinity); const sortModules = optionOrFallback(options.modulesSort, "id"); const sortChunks = optionOrFallback(options.chunksSort, "id"); const sortAssets = optionOrFallback(options.assetsSort, ""); + if(!showCachedModules) { + excludeModules.push((ident, module) => !module.built); + } + const createModuleFilter = () => { let i = 0; return module => { - if(!showCachedModules && !module.built) { - return false; - } if(excludeModules.length > 0) { const ident = requestShortener.shorten(module.resource); - const excluded = excludeModules.some(regExp => regExp.test(ident)); + const excluded = excludeModules.some(fn => fn(ident, module)); if(excluded) return false; } @@ -280,7 +292,7 @@ class Stats { built: !!module.built, optional: !!module.optional, prefetched: !!module.prefetched, - chunks: module.chunks.map(chunk => chunk.id), + chunks: module.mapChunks(chunk => chunk.id), assets: Object.keys(module.assets || {}), issuer: module.issuer && module.issuer.identifier(), issuerId: module.issuer && module.issuer.id, @@ -311,6 +323,12 @@ class Stats { if(showProvidedExports) { obj.providedExports = Array.isArray(module.providedExports) ? module.providedExports : null; } + if(showOptimizationBailout) { + obj.optimizationBailout = module.optimizationBailout.map(item => { + if(typeof item === "function") return item(requestShortener); + return item; + }); + } if(showDepth) { obj.depth = module.depth; } @@ -328,19 +346,19 @@ class Stats { entry: chunk.hasRuntime(), recorded: chunk.recorded, extraAsync: !!chunk.extraAsync, - size: chunk.modules.reduce((size, module) => size + module.size(), 0), + size: chunk.mapModules(m => m.size()).reduce((size, moduleSize) => size + moduleSize, 0), names: chunk.name ? [chunk.name] : [], files: chunk.files.slice(), hash: chunk.renderedHash, parents: chunk.parents.map(c => c.id) }; if(showChunkModules) { - obj.modules = chunk.modules - .slice() + obj.modules = chunk + .getModules() .sort(sortByField("depth")) .filter(createModuleFilter()) .map(fnModule); - obj.filteredModules = chunk.modules.length - obj.modules.length; + obj.filteredModules = chunk.getNumberOfModules() - obj.modules.length; obj.modules.sort(sortByField(sortModules)); } if(showChunkOrigins) { @@ -636,6 +654,13 @@ class Stats { newline(); } } + if(Array.isArray(module.optimizationBailout)) { + module.optimizationBailout.forEach(item => { + colors.normal(prefix); + colors.yellow(item); + newline(); + }); + } if(module.reasons) { module.reasons.forEach(reason => { colors.normal(prefix); @@ -685,6 +710,35 @@ class Stats { } }; + const processModulesList = (obj, prefix) => { + if(obj.modules) { + obj.modules.forEach(module => { + colors.normal(prefix); + if(module.id < 1000) colors.normal(" "); + if(module.id < 100) colors.normal(" "); + if(module.id < 10) colors.normal(" "); + colors.normal("["); + colors.normal(module.id); + colors.normal("] "); + colors.bold(module.name || module.identifier); + processModuleAttributes(module); + newline(); + processModuleContent(module, prefix + " "); + }); + if(obj.filteredModules > 0) { + colors.normal(prefix); + colors.normal(" "); + if(obj.modules.length > 0) + colors.normal(" + "); + colors.normal(obj.filteredModules); + if(obj.modules.length > 0) + colors.normal(" hidden"); + colors.normal(obj.filteredModules !== 1 ? " modules" : " module"); + newline(); + } + } + }; + if(obj.chunks) { obj.chunks.forEach(chunk => { colors.normal("chunk "); @@ -746,45 +800,11 @@ class Stats { newline(); }); } - if(chunk.modules) { - chunk.modules.forEach(module => { - colors.normal(" "); - if(module.id < 1000) colors.normal(" "); - if(module.id < 100) colors.normal(" "); - if(module.id < 10) colors.normal(" "); - colors.normal("["); - colors.normal(module.id); - colors.normal("] "); - colors.bold(module.name); - processModuleAttributes(module); - newline(); - processModuleContent(module, " "); - }); - if(chunk.filteredModules > 0) { - colors.normal(` + ${chunk.filteredModules} hidden modules`); - newline(); - } - } + processModulesList(chunk, " "); }); } - if(obj.modules) { - obj.modules.forEach(module => { - if(module.id < 1000) colors.normal(" "); - if(module.id < 100) colors.normal(" "); - if(module.id < 10) colors.normal(" "); - colors.normal("["); - colors.normal(module.id); - colors.normal("] "); - colors.bold(module.name || module.identifier); - processModuleAttributes(module); - newline(); - processModuleContent(module, " "); - }); - if(obj.filteredModules > 0) { - colors.normal(` + ${obj.filteredModules} hidden modules`); - newline(); - } - } + + processModulesList(obj, ""); if(obj._showWarnings && obj.warnings) { obj.warnings.forEach(warning => { @@ -827,51 +847,63 @@ class Stats { } static presetToOptions(name) { - //Accepted values: none, errors-only, minimal, normal, verbose - //Any other falsy value will behave as 'none', truthy values as 'normal' - const pn = (typeof name === "string") && name.toLowerCase() || name; - if(pn === "none" || !pn) { - return { - hash: false, - version: false, - timings: false, - assets: false, - entrypoints: false, - chunks: false, - chunkModules: false, - modules: false, - reasons: false, - depth: false, - usedExports: false, - providedExports: false, - children: false, - source: false, - errors: false, - errorDetails: false, - warnings: false, - publicPath: false, - performance: false - }; - } else { - return { - hash: pn !== "errors-only" && pn !== "minimal", - version: pn === "verbose", - timings: pn !== "errors-only" && pn !== "minimal", - assets: pn === "verbose", - entrypoints: pn === "verbose", - chunks: pn !== "errors-only", - chunkModules: pn === "verbose", - //warnings: pn !== "errors-only", - errorDetails: pn !== "errors-only" && pn !== "minimal", - reasons: pn === "verbose", - depth: pn === "verbose", - usedExports: pn === "verbose", - providedExports: pn === "verbose", - colors: true, - performance: true - }; + // Accepted values: none, errors-only, minimal, normal, detailed, verbose + // Any other falsy value will behave as 'none', truthy values as 'normal' + const pn = (typeof name === "string") && name.toLowerCase() || name || "none"; + switch(pn) { + case "none": + return { + all: false + }; + case "verbose": + return { + entrypoints: true, + modules: false, + chunks: true, + chunkModules: true, + chunkOrigins: true, + depth: true, + reasons: true, + usedExports: true, + providedExports: true, + optimizationBailout: true, + errorDetails: true, + publicPath: true, + exclude: () => false, + maxModules: Infinity, + }; + case "detailed": + return { + entrypoints: true, + chunks: true, + chunkModules: false, + chunkOrigins: true, + depth: true, + usedExports: true, + providedExports: true, + optimizationBailout: true, + errorDetails: true, + publicPath: true, + exclude: () => false, + maxModules: Infinity, + }; + case "minimal": + return { + all: false, + modules: true, + maxModules: 0, + errors: true, + warnings: true, + }; + case "errors-only": + return { + all: false, + errors: true, + moduleTrace: true, + }; + default: + return {}; } - } static getChildOptions(options, idx) { diff --git a/lib/Template.js b/lib/Template.js index 0c11f5934..d7ee6e85b 100644 --- a/lib/Template.js +++ b/lib/Template.js @@ -99,12 +99,12 @@ module.exports = class Template extends Tapable { renderChunkModules(chunk, moduleTemplate, dependencyTemplates, prefix) { if(!prefix) prefix = ""; var source = new ConcatSource(); - if(chunk.modules.length === 0) { + if(chunk.getNumberOfModules() === 0) { source.add("[]"); return source; } var removedModules = chunk.removedModules; - var allModules = chunk.modules.map(function(module) { + var allModules = chunk.mapModules(function(module) { return { id: module.id, source: moduleTemplate.render(module, dependencyTemplates, chunk) @@ -118,7 +118,7 @@ module.exports = class Template extends Tapable { }); }); } - var bounds = this.getModulesArrayBounds(chunk.modules); + var bounds = this.getModulesArrayBounds(allModules); if(bounds) { // Render a spare array diff --git a/lib/UmdMainTemplatePlugin.js b/lib/UmdMainTemplatePlugin.js index 3b3838e5e..ac37dd588 100644 --- a/lib/UmdMainTemplatePlugin.js +++ b/lib/UmdMainTemplatePlugin.js @@ -32,7 +32,7 @@ class UmdMainTemplatePlugin { apply(compilation) { const mainTemplate = compilation.mainTemplate; compilation.templatesPlugin("render-with-entry", function(source, chunk, hash) { - let externals = chunk.modules.filter(m => m.external); + let externals = chunk.getModules().filter(m => m.external); const optionalExternals = []; let requiredExternals = []; if(this.optionalAmdExternalAsGlobal) { diff --git a/lib/WebpackOptionsDefaulter.js b/lib/WebpackOptionsDefaulter.js index cee9bd229..dcaf641df 100644 --- a/lib/WebpackOptionsDefaulter.js +++ b/lib/WebpackOptionsDefaulter.js @@ -28,6 +28,7 @@ class WebpackOptionsDefaulter extends OptionsDefaulter { this.set("module.wrappedContextRecursive", true); this.set("module.wrappedContextCritical", false); this.set("module.strictExportPresence", false); + this.set("module.strictThisContextOnImports", false); this.set("module.unsafeCache", true); diff --git a/lib/dependencies/HarmonyImportDependencyParserPlugin.js b/lib/dependencies/HarmonyImportDependencyParserPlugin.js index 88ed4b141..5551882ac 100644 --- a/lib/dependencies/HarmonyImportDependencyParserPlugin.js +++ b/lib/dependencies/HarmonyImportDependencyParserPlugin.js @@ -13,6 +13,7 @@ const HarmonyModulesHelpers = require("./HarmonyModulesHelpers"); module.exports = class HarmonyImportDependencyParserPlugin { constructor(moduleOptions) { this.strictExportPresence = moduleOptions.strictExportPresence; + this.strictThisContextOnImports = moduleOptions.strictThisContextOnImports; } apply(parser) { @@ -52,22 +53,38 @@ module.exports = class HarmonyImportDependencyParserPlugin { parser.state.current.addDependency(dep); return true; }); - parser.plugin("call imported var", (expr) => { - const args = expr.arguments; - const fullExpr = expr; - expr = expr.callee; - const name = expr.name; - const settings = parser.state.harmonySpecifier[`$${name}`]; - const dep = new HarmonyImportSpecifierDependency(settings[0], settings[1], settings[2], name, expr.range, this.strictExportPresence); - dep.directImport = true; - dep.callArgs = args; - dep.call = fullExpr; - dep.loc = expr.loc; - parser.state.current.addDependency(dep); - if(args) - parser.walkExpressions(args); - return true; - }); + if(this.strictThisContextOnImports) { + // only in case when we strictly follow the spec we need a special case here + parser.plugin("call imported var.*", (expr) => { + const name = expr.callee.object.name; + const settings = parser.state.harmonySpecifier[`$${name}`]; + if(settings[2] !== null) + return false; + const dep = new HarmonyImportSpecifierDependency(settings[0], settings[1], expr.callee.property.name || expr.callee.property.value, name, expr.callee.range, this.strictExportPresence); + dep.shorthand = parser.scope.inShorthand; + dep.directImport = false; + dep.namespaceObjectAsContext = true; + dep.loc = expr.callee.loc; + parser.state.current.addDependency(dep); + return true; + }); + parser.plugin("call imported var", (expr) => { + const args = expr.arguments; + const fullExpr = expr; + expr = expr.callee; + const name = expr.name; + const settings = parser.state.harmonySpecifier[`$${name}`]; + const dep = new HarmonyImportSpecifierDependency(settings[0], settings[1], settings[2], name, expr.range, this.strictExportPresence); + dep.directImport = true; + dep.callArgs = args; + dep.call = fullExpr; + dep.loc = expr.loc; + parser.state.current.addDependency(dep); + if(args) + parser.walkExpressions(args); + return true; + }); + } parser.plugin("hot accept callback", (expr, requests) => { const dependencies = requests .filter(request => HarmonyModulesHelpers.checkModuleVar(parser.state, request)) diff --git a/lib/dependencies/HarmonyImportSpecifierDependency.js b/lib/dependencies/HarmonyImportSpecifierDependency.js index b2a42151e..1e7ceb6c7 100644 --- a/lib/dependencies/HarmonyImportSpecifierDependency.js +++ b/lib/dependencies/HarmonyImportSpecifierDependency.js @@ -14,6 +14,10 @@ class HarmonyImportSpecifierDependency extends NullDependency { this.name = name; this.range = range; this.strictExportPresence = strictExportPresence; + this.namespaceObjectAsContext = false; + this.callArgs = undefined; + this.call = undefined; + this.directImport = undefined; } get type() { @@ -24,7 +28,7 @@ class HarmonyImportSpecifierDependency extends NullDependency { if(!this.importDependency.module) return null; return { module: this.importDependency.module, - importedNames: this.id ? [this.id] : true + importedNames: this.id && !this.namespaceObjectAsContext ? [this.id] : true }; } @@ -93,7 +97,7 @@ HarmonyImportSpecifierDependency.Template = class HarmonyImportSpecifierDependen } if(dep.call && dep.id) { - return `${shortHandPrefix}__webpack_require__.i(${importedVar}${importedVarSuffix})`; + return `${shortHandPrefix}Object(${importedVar}${importedVarSuffix})`; } return `${shortHandPrefix}${importedVar}${importedVarSuffix}`; diff --git a/lib/optimize/AggressiveSplittingPlugin.js b/lib/optimize/AggressiveSplittingPlugin.js index 9b2bf10d7..033598bba 100644 --- a/lib/optimize/AggressiveSplittingPlugin.js +++ b/lib/optimize/AggressiveSplittingPlugin.js @@ -6,18 +6,6 @@ const identifierUtils = require("../util/identifier"); -function toIndexOf(list) { - return function(item) { - return list.indexOf(item); - }; -} - -function toChunkModuleIndices(modules) { - return function(idx) { - return modules[idx]; - }; -} - function moveModuleBetween(oldChunk, newChunk) { return function(module) { oldChunk.moveModule(module, newChunk); @@ -62,17 +50,19 @@ class AggressiveSplittingPlugin { const splitData = usedSplits[j]; for(let i = 0; i < chunks.length; i++) { const chunk = chunks[i]; - const chunkModuleNames = chunk.modules.map(m => identifierUtils.makePathsRelative(compiler.context, m.identifier())); - if(chunkModuleNames.length < splitData.modules.length) + if(chunk.getNumberOfModules() < splitData.modules.length) continue; - const moduleIndicies = splitData.modules.map(toIndexOf(chunkModuleNames)); - const hasAllModules = moduleIndicies.every((idx) => { - return idx >= 0; + + const nameToModuleMap = new Map(); + chunk.forEachModule(m => { + const name = identifierUtils.makePathsRelative(compiler.context, m.identifier()); + nameToModuleMap.set(name, m); }); - if(hasAllModules) { - if(chunkModuleNames.length > splitData.modules.length) { - const selectedModules = moduleIndicies.map(toChunkModuleIndices(chunk.modules)); + + const selectedModules = splitData.modules.map(name => nameToModuleMap.get(name)); + if(selectedModules.every(Boolean)) { + if(chunk.getNumberOfModules() > splitData.modules.length) { const newChunk = compilation.addChunk(); selectedModules.forEach(moveModuleBetween(chunk, newChunk)); chunk.split(newChunk); @@ -101,9 +91,9 @@ class AggressiveSplittingPlugin { for(let i = 0; i < chunks.length; i++) { const chunk = chunks[i]; const size = chunk.size(this.options); - if(size > maxSize && chunk.modules.length > 1) { + if(size > maxSize && chunk.getNumberOfModules() > 1) { const newChunk = compilation.addChunk(); - const modules = chunk.modules + const modules = chunk.getModules() .filter(isNotAEntryModule(chunk.entryModule)) .sort((a, b) => { a = a.identifier(); @@ -131,13 +121,13 @@ class AggressiveSplittingPlugin { break; } } - if(newChunk.modules.length > 0) { + if(newChunk.getNumberOfModules() > 0) { chunk.split(newChunk); chunk.name = null; newChunk.origins = chunk.origins.map(copyWithReason); chunk.origins = chunk.origins.map(copyWithReason); compilation._aggressiveSplittingSplits = (compilation._aggressiveSplittingSplits || []).concat({ - modules: newChunk.modules.map(m => identifierUtils.makePathsRelative(compiler.context, m.identifier())) + modules: newChunk.mapModules(m => identifierUtils.makePathsRelative(compiler.context, m.identifier())) }); return true; } else { @@ -154,7 +144,7 @@ class AggressiveSplittingPlugin { if(chunk.hasEntryModule()) return; const size = chunk.size(this.options); const incorrectSize = size < minSize; - const modules = chunk.modules.map(m => identifierUtils.makePathsRelative(compiler.context, m.identifier())); + const modules = chunk.mapModules(m => identifierUtils.makePathsRelative(compiler.context, m.identifier())); if(typeof chunk._fromAggressiveSplittingIndex === "undefined") { if(incorrectSize) return; chunk.recorded = true; diff --git a/lib/optimize/CommonsChunkPlugin.js b/lib/optimize/CommonsChunkPlugin.js index 99bb1aebb..9585ca7b5 100644 --- a/lib/optimize/CommonsChunkPlugin.js +++ b/lib/optimize/CommonsChunkPlugin.js @@ -275,7 +275,7 @@ Take a look at the "name"/"names" or async/children option.`); // count how many chunks contain a module const commonModulesToCountMap = usedChunks.reduce((map, chunk) => { - for(let module of chunk.modules) { + for(const module of chunk.modulesIterable) { const count = map.has(module) ? map.get(module) : 0; map.set(module, count + 1); } diff --git a/lib/optimize/ConcatenatedModule.js b/lib/optimize/ConcatenatedModule.js new file mode 100644 index 000000000..e11aaefdb --- /dev/null +++ b/lib/optimize/ConcatenatedModule.js @@ -0,0 +1,517 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ +"use strict"; + +const Module = require("../Module"); +const Template = require("../Template"); +const Parser = require("../Parser"); +const acorn = require("acorn"); +const escope = require("escope"); +const ReplaceSource = require("webpack-sources/lib/ReplaceSource"); +const ConcatSource = require("webpack-sources/lib/ConcatSource"); +const HarmonyImportDependency = require("../dependencies/HarmonyImportDependency"); +const HarmonyImportSpecifierDependency = require("../dependencies/HarmonyImportSpecifierDependency"); +const HarmonyExportSpecifierDependency = require("../dependencies/HarmonyExportSpecifierDependency"); +const HarmonyExportExpressionDependency = require("../dependencies/HarmonyExportExpressionDependency"); +const HarmonyExportImportedSpecifierDependency = require("../dependencies/HarmonyExportImportedSpecifierDependency"); +const HarmonyCompatibilityDependency = require("../dependencies/HarmonyCompatibilityDependency"); +const HarmonyModulesHelpers = require("../dependencies/HarmonyModulesHelpers"); + +function getFinalName(info, exportName, moduleToInfoMap, requestShortener) { + const directExport = info.exportMap.get(exportName); + if(directExport) { + if(exportName === true) + info.needNamespaceObject = true; + return info.internalNames.get(directExport); + } + const reexport = info.reexportMap.get(exportName); + if(reexport) { + const refInfo = moduleToInfoMap.get(reexport.module); + if(refInfo) { + // module is in the concatenation + return getFinalName(refInfo, reexport.exportName, moduleToInfoMap, requestShortener); + } else { + const dep = reexport.dependency; + const importedModule = reexport.module; + const exportName = reexport.exportName; + const isHarmonyModule = importedModule && (!importedModule.meta || importedModule.meta.harmonyModule); + const importedVar = dep.importedVar; + const used = importedModule.isUsed(exportName); + if(!used) return "/* unused reexport */undefined"; + if(!isHarmonyModule && exportName === "default") { + return `${importedVar}_default.a`; + } + return `${importedVar}[${JSON.stringify(used)}]`; + } + } + throw new Error(`Cannot get final name for export "${exportName}" in "${info.module.readableIdentifier(requestShortener)}"` + + ` (known exports: ${Array.from(info.exportMap.keys()).join(" ")}, ` + + `known reexports: ${Array.from(info.reexportMap.keys()).join(" ")})`); +} + +function getSymbolsFromScope(s, untilScope) { + const allUsedNames = new Set(); + let scope = s; + while(scope) { + if(untilScope === scope) break; + scope.variables.forEach(variable => allUsedNames.add(variable.name)); + scope = scope.upper; + } + return allUsedNames; +} + +function reduceSet(a, b) { + for(const item of b) + a.add(item); + return a; +} + +class ConcatenatedModule extends Module { + constructor(rootModule, modules) { + super(); + this.rootModule = rootModule; + this.modules = modules; + this.usedExports = rootModule.usedExports; + this.providedExports = rootModule.providedExports; + this.optimizationBailout = rootModule.optimizationBailout; + this.used = rootModule.used; + this._chunks = new Set(rootModule._chunks); + this.index = rootModule.index; + this.index2 = rootModule.index2; + this.depth = rootModule.depth; + this.built = modules.some(m => m.built); + this.cacheable = modules.every(m => m.cacheable); + const modulesSet = new Set(modules); + this.reasons = rootModule.reasons.filter(reason => !modulesSet.has(reason.module)); + this.dependencies = [].concat.apply([], modules.map(m => m.dependencies.filter(dep => !modulesSet.has(dep.module)))); + this.meta = rootModule.meta; + this.dependenciesWarnings = modules.reduce((w, m) => m.dependenciesWarnings.forEach(x => w.push(x)), []); + this.dependenciesErrors = modules.reduce((w, m) => m.dependenciesErrors.forEach(x => w.push(x)), []); + this.warnings = modules.reduce((w, m) => m.warnings.forEach(x => w.push(x)), []); + this.errors = modules.reduce((w, m) => m.errors.forEach(x => w.push(x)), []); + this.moduleArgument = rootModule.moduleArgument; + this.exportsArgument = rootModule.exportsArgument; + this.strict = true; + modules.forEach((m, idx) => { + for(const dep of m.dependencies.filter(dep => !modulesSet.has(dep.module))) { + this.dependencies.push(dep); + } + }); + } + + identifier() { + return this.modules.map(m => m.identifier()).join(" "); + } + + readableIdentifier(requestShortener) { + return this.rootModule.readableIdentifier(requestShortener) + ` + ${this.modules.length - 1} modules`; + } + + libIdent(options) { + return this.rootModule.libIdent(options); + } + + nameForCondition() { + return this.rootModule.nameForCondition(); + } + + build(options, compilation, resolver, fs, callback) { + throw new Error("Cannot build this module. It should be already built."); + } + + size() { + // Guess size from embedded modules + return this.modules.reduce((sum, m) => sum + m.size(), 0); + } + + source(dependencyTemplates, outputOptions, requestShortener) { + const modulesSet = new Set(); + this.modules.forEach(m => modulesSet.add(m)); + + // Metainfo for each module + const modulesWithInfo = this.modules.map((m, idx) => { + const exportMap = new Map(); + const reexportMap = new Map(); + m.dependencies.forEach(dep => { + if(dep instanceof HarmonyExportSpecifierDependency) { + exportMap.set(dep.name, dep.id); + } else if(dep instanceof HarmonyExportExpressionDependency) { + exportMap.set("default", "__WEBPACK_MODULE_DEFAULT_EXPORT__"); + } else if(dep instanceof HarmonyExportImportedSpecifierDependency) { + const exportName = dep.name; + const importName = dep.id; + const importModule = dep.importDependency.module; + const innerReexport = modulesSet.has(importModule); + if(exportName && importName) { + reexportMap.set(exportName, { + module: importModule, + exportName: importName, + dependency: dep + }); + } else if(exportName) { + reexportMap.set(exportName, { + module: importModule, + exportName: true, + dependency: dep + }); + } else if(Array.isArray(importModule.providedExports)) { + var activeExports = new Set(HarmonyModulesHelpers.getActiveExports(dep.originModule, dep)); + importModule.providedExports.forEach(name => { + if(activeExports.has(name) || name === "default") + return; + reexportMap.set(name, { + module: importModule, + exportName: name, + dependency: dep + }); + }); + } else if(innerReexport) { + throw new Error(`Module "${importModule.readableIdentifier(requestShortener)}" doesn't provide static exports for "export *" in ${m.readableIdentifier(requestShortener)}`); + } + } + }); + return { + module: m, + index: idx, + source: undefined, + globalScope: undefined, + moduleScope: undefined, + internalNames: new Map(), + exportMap: exportMap, + reexportMap: reexportMap, + needCompatibilityFlag: false, + needNamespaceObject: false + }; + }); + + // Create mapping from module to info + const moduleToInfoMap = new Map(); + modulesWithInfo.forEach(m => moduleToInfoMap.set(m.module, m)); + + // Configure template decorators for dependencies + const innerDependencyTemplates = new Map(dependencyTemplates); + + innerDependencyTemplates.set(HarmonyImportSpecifierDependency, new HarmonyImportSpecifierDependencyConcatenatedTemplate( + dependencyTemplates.get(HarmonyImportSpecifierDependency), + moduleToInfoMap + )); + innerDependencyTemplates.set(HarmonyImportDependency, new HarmonyImportDependencyConcatenatedTemplate( + dependencyTemplates.get(HarmonyImportDependency), + moduleToInfoMap + )); + innerDependencyTemplates.set(HarmonyExportSpecifierDependency, new HarmonyExportSpecifierDependencyConcatenatedTemplate( + dependencyTemplates.get(HarmonyExportSpecifierDependency), + this.rootModule + )); + innerDependencyTemplates.set(HarmonyExportExpressionDependency, new HarmonyExportExpressionDependencyConcatenatedTemplate( + dependencyTemplates.get(HarmonyExportExpressionDependency), + this.rootModule, + moduleToInfoMap + )); + innerDependencyTemplates.set(HarmonyExportImportedSpecifierDependency, new HarmonyExportImportedSpecifierDependencyConcatenatedTemplate( + dependencyTemplates.get(HarmonyExportImportedSpecifierDependency), + this.rootModule, + moduleToInfoMap + )); + innerDependencyTemplates.set(HarmonyCompatibilityDependency, new HarmonyCompatibilityDependencyConcatenatedTemplate( + dependencyTemplates.get(HarmonyCompatibilityDependency), + this.rootModule, + moduleToInfoMap + )); + + // Generate source code and analyse scopes + // Prepare a ReplaceSource for the final source + modulesWithInfo.forEach(info => { + const m = info.module; + const source = m.source(innerDependencyTemplates, outputOptions, requestShortener); + const code = source.source(); + const ast = acorn.parse(code, { + ranges: true, + locations: true, + ecmaVersion: Parser.ECMA_VERSION, + sourceType: "module" + }); + const scopeManager = escope.analyze(ast, { + ecmaVersion: 6, + sourceType: "module", + optimistic: true, + ignoreEval: true, + impliedStrict: true + }); + const globalScope = scopeManager.acquire(ast); + const moduleScope = globalScope.childScopes[0]; + const resultSource = new ReplaceSource(m.source(innerDependencyTemplates, outputOptions, requestShortener)); + info.source = resultSource; + info.globalScope = globalScope; + info.moduleScope = moduleScope; + }); + + // List of all used names to avoid conflicts + const allUsedNames = new Set(["__WEBPACK_MODULE_DEFAULT_EXPORT__", "defaultExport", "Object"]); + + // get all global names + modulesWithInfo.forEach(info => { + info.globalScope.through.forEach(reference => { + const name = reference.identifier.name; + if(/^__WEBPACK_MODULE_REFERENCE__\d+_(\d+|ns)__$/.test(name)) { + for(const s of getSymbolsFromScope(reference.from, info.moduleScope)) { + allUsedNames.add(s); + } + } else { + allUsedNames.add(name); + } + }); + }); + + modulesWithInfo.forEach(info => { + const namespaceObjectName = this.findNewName("namespaceObject", allUsedNames, null, info.module.readableIdentifier(requestShortener)); + info.internalNames.set(namespaceObjectName, namespaceObjectName); + info.exportMap.set(true, namespaceObjectName); + info.moduleScope.variables.forEach(variable => { + const name = variable.name; + if(allUsedNames.has(name)) { + const symbolsInReferences = variable.references.map(ref => getSymbolsFromScope(ref.from, info.moduleScope)).reduce(reduceSet, new Set()); + const newName = this.findNewName(name, allUsedNames, symbolsInReferences, info.module.readableIdentifier(requestShortener)); + allUsedNames.add(newName); + info.internalNames.set(name, newName); + const source = info.source; + const allIdentifiers = new Set(variable.references.map(r => r.identifier).concat(variable.identifiers)); + for(const identifier of allIdentifiers) { + const r = identifier.range; + source.replace(r[0], r[1] - 1, newName); + } + } else { + allUsedNames.add(name); + info.internalNames.set(name, name); + } + }); + }); + + modulesWithInfo.forEach(info => { + info.globalScope.through.forEach(reference => { + const name = reference.identifier.name; + const match = /^__WEBPACK_MODULE_REFERENCE__(\d+)_(\d+|ns)__$/.exec(name); + if(match) { + const referencedModule = modulesWithInfo[+match[1]]; + let exportName; + if(match[2] === "ns") { + exportName = true; + } else { + const exportIdx = +match[2]; + exportName = referencedModule.module.providedExports[exportIdx]; + } + const finalName = getFinalName(referencedModule, exportName, moduleToInfoMap, requestShortener); + if(!finalName) + throw new Error(`Cannot map to variable name in module ${info.module.resource} (export '${exportName}')`); + const r = reference.identifier.range; + const source = info.source; + source.replace(r[0], r[1] - 1, finalName); + } + }); + }); + + const result = new ConcatSource(); + if(moduleToInfoMap.get(this.rootModule).needCompatibilityFlag) { + result.add(`Object.defineProperty(${this.rootModule.exportsArgument || "exports"}, "__esModule", { value: true });\n`); + } + modulesWithInfo.forEach(info => { + result.add(`\n// CONCATENATED MODULE: ${info.module.readableIdentifier(requestShortener)}\n`); + if(info.needNamespaceObject) { + const name = info.exportMap.get(true); + const nsObj = [`var ${name} = {};`]; + for(const exportName of info.module.providedExports) { + const finalName = getFinalName(info, exportName, moduleToInfoMap, requestShortener); + nsObj.push(`__webpack_require__.d(${name}, ${JSON.stringify(exportName)}, function() { return ${finalName}; });`); + } + result.add(nsObj.join("\n") + "\n"); + } + result.add(info.source); + }); + + return result; + } + + findNewName(oldName, usedNamed1, usedNamed2, extraInfo) { + let name = oldName; + + if(name === "__WEBPACK_MODULE_DEFAULT_EXPORT__") + name = "defaultExport"; + + const splittedInfo = extraInfo.split("/"); + while(splittedInfo.length) { + name = splittedInfo.pop() + "_" + name; + const nameIdent = Template.toIdentifier(name); + if(!usedNamed1.has(nameIdent) && (!usedNamed2 || !usedNamed2.has(nameIdent))) return nameIdent; + } + + while(usedNamed1.has(name = name + "_") || (usedNamed2 && usedNamed2.has(name))) { /* do nothing */ } + return name; + } + +} + +class HarmonyImportSpecifierDependencyConcatenatedTemplate { + constructor(originalTemplate, modulesMap) { + this.originalTemplate = originalTemplate; + this.modulesMap = modulesMap; + } + + apply(dep, source, outputOptions, requestShortener, dependencyTemplates) { + const module = dep.importDependency.module; + const info = this.modulesMap.get(module); + if(!info) { + this.originalTemplate.apply(dep, source, outputOptions, requestShortener, dependencyTemplates); + return; + } + if(!Array.isArray(module.providedExports)) + throw new Error(`Module ${module.resource} has no static exports ${module.providedExports}`); + let content; + if(dep.id === null) { + content = `__WEBPACK_MODULE_REFERENCE__${info.index}_ns__`; + } else { + const exportIdx = (module.providedExports).indexOf(dep.id); + content = exportIdx === -1 ? "undefined" : `__WEBPACK_MODULE_REFERENCE__${info.index}_${exportIdx}__`; + } + if(dep.shorthand) { + content = dep.name + ": " + content; + } + source.replace(dep.range[0], dep.range[1] - 1, content); + } +} + +class HarmonyImportDependencyConcatenatedTemplate { + constructor(originalTemplate, modulesMap) { + this.originalTemplate = originalTemplate; + this.modulesMap = modulesMap; + } + + apply(dep, source, outputOptions, requestShortener, dependencyTemplates) { + const module = dep.module; + const info = this.modulesMap.get(module); + if(!info) { + this.originalTemplate.apply(dep, source, outputOptions, requestShortener, dependencyTemplates); + return; + } + source.replace(dep.range[0], dep.range[1] - 1, ""); + } +} + +class HarmonyExportSpecifierDependencyConcatenatedTemplate { + constructor(originalTemplate, rootModule) { + this.originalTemplate = originalTemplate; + this.rootModule = rootModule; + } + + apply(dep, source, outputOptions, requestShortener, dependencyTemplates) { + if(dep.originModule === this.rootModule) { + this.originalTemplate.apply(dep, source, outputOptions, requestShortener, dependencyTemplates); + } + } +} + +class HarmonyExportExpressionDependencyConcatenatedTemplate { + constructor(originalTemplate, rootModule) { + this.originalTemplate = originalTemplate; + this.rootModule = rootModule; + } + + apply(dep, source, outputOptions, requestShortener, dependencyTemplates) { + if(dep.originModule === this.rootModule) { + this.originalTemplate.apply(dep, source, outputOptions, requestShortener, dependencyTemplates); + } else { + const content = "/* harmony default export */ var __WEBPACK_MODULE_DEFAULT_EXPORT__ = "; + + if(dep.range) { + source.replace(dep.rangeStatement[0], dep.range[0] - 1, content + "("); + source.replace(dep.range[1], dep.rangeStatement[1] - 1, ");"); + return; + } + + source.replace(dep.rangeStatement[0], dep.rangeStatement[1] - 1, content); + } + } +} + +class HarmonyExportImportedSpecifierDependencyConcatenatedTemplate { + constructor(originalTemplate, rootModule, modulesMap) { + this.originalTemplate = originalTemplate; + this.rootModule = rootModule; + this.modulesMap = modulesMap; + } + + getExports(dep) { + const active = HarmonyModulesHelpers.isActive(dep.originModule, dep); + if(!active) return []; + const importModule = dep.importDependency.module; + if(dep.id) { + // export { named } from "module" + return [{ + name: dep.name, + id: dep.id, + module: importModule + }]; + } + if(dep.name) { + // export * as abc from "module" + return [{ + name: dep.name, + id: true, + module: importModule + }]; + } + // export * from "module" + const activeExports = new Set(HarmonyModulesHelpers.getActiveExports(dep.originModule, dep)); + return importModule.providedExports.filter(exp => exp !== "default" && !activeExports.has(exp)).map(exp => { + return { + name: exp, + id: exp, + module: importModule + }; + }); + } + + apply(dep, source, outputOptions, requestShortener, dependencyTemplates) { + if(dep.originModule === this.rootModule) { + if(this.modulesMap.get(dep.importDependency.module)) { + const exportDefs = this.getExports(dep); + exportDefs.forEach(def => { + const info = this.modulesMap.get(def.module); + const used = dep.originModule.isUsed(def.name); + if(!used) { + source.insert(-1, `/* unused concated harmony import ${dep.name} */\n`); + } + let finalName; + if(def.id === true) { + finalName = `__WEBPACK_MODULE_REFERENCE__${info.index}_ns__`; + } else { + const exportIdx = def.module.providedExports.indexOf(def.id); + finalName = exportIdx < 0 ? "undefined" : `__WEBPACK_MODULE_REFERENCE__${info.index}_${exportIdx}__`; + } + const exportsName = this.rootModule.exportsArgument || "exports"; + const content = `/* concated harmony reexport */__webpack_require__.d(${exportsName}, ${JSON.stringify(used)}, function() { return ${finalName}; });\n`; + source.insert(-1, content); + }); + } else { + this.originalTemplate.apply(dep, source, outputOptions, requestShortener, dependencyTemplates); + } + } + } +} + +class HarmonyCompatibilityDependencyConcatenatedTemplate { + constructor(originalTemplate, rootModule, modulesMap) { + this.originalTemplate = originalTemplate; + this.rootModule = rootModule; + this.modulesMap = modulesMap; + } + + apply(dep, source, outputOptions, requestShortener, dependencyTemplates) { + if(dep.originModule === this.rootModule) { + this.modulesMap.get(this.rootModule).needCompatibilityFlag = true; + } + } +} + +module.exports = ConcatenatedModule; diff --git a/lib/optimize/EnsureChunkConditionsPlugin.js b/lib/optimize/EnsureChunkConditionsPlugin.js index 590adc6e5..07b9756b8 100644 --- a/lib/optimize/EnsureChunkConditionsPlugin.js +++ b/lib/optimize/EnsureChunkConditionsPlugin.js @@ -8,16 +8,19 @@ class EnsureChunkConditionsPlugin { apply(compiler) { compiler.plugin("compilation", (compilation) => { + const triesMap = new Map(); compilation.plugin(["optimize-chunks-basic", "optimize-extracted-chunks-basic"], (chunks) => { let changed = false; chunks.forEach((chunk) => { - chunk.modules.slice().forEach((module) => { + chunk.forEachModule((module) => { if(!module.chunkCondition) return; if(!module.chunkCondition(chunk)) { - const usedChunks = module._EnsureChunkConditionsPlugin_usedChunks = (module._EnsureChunkConditionsPlugin_usedChunks || []).concat(chunk); + let usedChunks = triesMap.get(module); + if(!usedChunks) triesMap.set(module, usedChunks = new Set()); + usedChunks.add(chunk); const newChunks = []; chunk.parents.forEach((parent) => { - if(usedChunks.indexOf(parent) < 0) { + if(!usedChunks.has(parent)) { parent.addModule(module); newChunks.push(parent); } diff --git a/lib/optimize/FlagIncludedChunksPlugin.js b/lib/optimize/FlagIncludedChunksPlugin.js index 4fa9b1f9d..f23eec6e5 100644 --- a/lib/optimize/FlagIncludedChunksPlugin.js +++ b/lib/optimize/FlagIncludedChunksPlugin.js @@ -17,13 +17,13 @@ class FlagIncludedChunksPlugin { // instead of swapping A and B just bail // as we loop twice the current A will be B and B then A - if(chunkA.modules.length < chunkB.modules.length) return; + if(chunkA.getNumberOfModules() < chunkB.getNumberOfModules()) return; - if(chunkB.modules.length === 0) return; + if(chunkB.getNumberOfModules() === 0) return; // is chunkB in chunkA? - for(let i = 0; i < chunkB.modules.length; i++) { - if(chunkA.modules.indexOf(chunkB.modules[i]) < 0) return; + for(const m of chunkB.modulesIterable) { + if(!chunkA.containsModule(m)) return; } chunkA.ids.push(chunkB.id); }); diff --git a/lib/optimize/MergeDuplicateChunksPlugin.js b/lib/optimize/MergeDuplicateChunksPlugin.js index 104cd6d6c..a37ab3c2e 100644 --- a/lib/optimize/MergeDuplicateChunksPlugin.js +++ b/lib/optimize/MergeDuplicateChunksPlugin.js @@ -4,23 +4,18 @@ */ "use strict"; -function getChunkIdentifier(chunk) { - return chunk.modules.map((m) => { - return m.identifier(); - }).sort().join(", "); -} - class MergeDuplicateChunksPlugin { apply(compiler) { compiler.plugin("compilation", (compilation) => { compilation.plugin("optimize-chunks-basic", (chunks) => { - const map = {}; + const map = Object.create(null); chunks.slice().forEach((chunk) => { if(chunk.hasRuntime() || chunk.hasEntryModule()) return; - const ident = getChunkIdentifier(chunk); - if(map[ident]) { - if(map[ident].integrate(chunk, "duplicate")) + const ident = chunk.getModulesIdent(); + const otherChunk = map[ident]; + if(otherChunk) { + if(otherChunk.integrate(chunk, "duplicate")) chunks.splice(chunks.indexOf(chunk), 1); return; } diff --git a/lib/optimize/ModuleConcatenationPlugin.js b/lib/optimize/ModuleConcatenationPlugin.js new file mode 100644 index 000000000..7e1759353 --- /dev/null +++ b/lib/optimize/ModuleConcatenationPlugin.js @@ -0,0 +1,292 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ +"use strict"; + +const HarmonyImportDependency = require("../dependencies/HarmonyImportDependency"); +const ConcatenatedModule = require("./ConcatenatedModule"); +const HarmonyExportImportedSpecifierDependency = require("../dependencies/HarmonyExportImportedSpecifierDependency"); + +class ModuleConcatenationPlugin { + constructor(options) { + if(typeof options !== "object") options = {}; + this.options = options; + } + + apply(compiler) { + compiler.plugin("compilation", (compilation, params) => { + params.normalModuleFactory.plugin("parser", (parser, parserOptions) => { + parser.plugin("call eval", () => { + parser.state.module.meta.hasEval = true; + }); + }); + const bailoutReasonMap = new Map(); + + function setBailoutReason(module, reason) { + bailoutReasonMap.set(module, reason); + module.optimizationBailout.push(reason); + } + + function getBailoutReason(module, requestShortener) { + const reason = bailoutReasonMap.get(module); + if(typeof reason === "function") return reason(requestShortener); + return reason; + } + + compilation.plugin("optimize-chunk-modules", (chunks, modules) => { + chunks.forEach(chunk => { + const relevantModules = []; + const possibleInners = new Set(); + for(const module of chunk.modulesIterable) { + // Only harmony modules are valid for optimization + if(!module.meta || !module.meta.harmonyModule) { + continue; + } + + // Module must not be in other chunks + // TODO add an option to allow module to be in other entry points + if(module.getNumberOfChunks() !== 1) { + setBailoutReason(module, "ModuleConcatenation: module is in multiple chunks"); + continue; + } + + // Because of variable renaming we can't use modules with eval + if(module.meta && module.meta.hasEval) { + setBailoutReason(module, "ModuleConcatenation: eval is used in the module"); + continue; + } + + relevantModules.push(module); + + // Module must not be the entry points + if(chunk.entryModule === module) { + setBailoutReason(module, "ModuleConcatenation (inner): module is an entrypoint"); + continue; + } + + // Exports must be known (and not dynamic) + if(!Array.isArray(module.providedExports)) { + setBailoutReason(module, "ModuleConcatenation (inner): exports are not known"); + continue; + } + + // Using dependency variables is not possible as this wraps the code in a function + if(module.variables.length > 0) { + setBailoutReason(module, "ModuleConcatenation (inner): dependency variables are used (i. e. ProvidePlugin)"); + continue; + } + + // Module must only be used by Harmony Imports + const nonHarmonyReasons = module.reasons.filter(reason => !(reason.dependency instanceof HarmonyImportDependency)); + if(nonHarmonyReasons.length > 0) { + const importingModules = new Set(nonHarmonyReasons.map(r => r.module)); + setBailoutReason(module, (requestShortener) => { + const names = Array.from(importingModules).map(m => m.readableIdentifier(requestShortener)); + return `ModuleConcatenation (inner): module is used with non-harmony imports from ${names.join(", ")}`; + }); + continue; + } + + possibleInners.add(module); + } + // sort by depth + // modules with lower depth are more likly suited as roots + // this improves performance, because modules already selected as inner are skipped + relevantModules.sort((a, b) => { + return a.depth - b.depth; + }); + const concatConfigurations = []; + const usedAsInner = new Set(); + for(const currentRoot of relevantModules) { + // when used by another configuration as inner: + // the other configuration is better and we can skip this one + if(usedAsInner.has(currentRoot)) + continue; + + // create a configuration with the root + const currentConfiguration = new ConcatConfiguration(currentRoot); + + // cache failures to add modules + const failureCache = new Map(); + + // try to add all imports + for(const imp of this.getImports(currentRoot)) { + const problem = this.tryToAdd(currentConfiguration, imp, possibleInners, failureCache); + if(problem) { + failureCache.set(imp, problem); + currentConfiguration.addWarning(imp, problem); + } + } + if(!currentConfiguration.isEmpty()) { + concatConfigurations.push(currentConfiguration); + for(const module of currentConfiguration.modules) { + if(module !== currentConfiguration.rootModule) + usedAsInner.add(module); + } + } + } + // HACK: Sort configurations by length and start with the longest one + // to get the biggers groups possible. Used modules are marked with usedModules + // TODO: Allow to reuse existing configuration while trying to add dependencies. + // This would improve performance. O(n^2) -> O(n) + concatConfigurations.sort((a, b) => { + return b.modules.size - a.modules.size; + }); + const usedModules = new Set(); + for(const concatConfiguration of concatConfigurations) { + if(usedModules.has(concatConfiguration.rootModule)) + continue; + const orderedModules = new Set(); + this.addInOrder(concatConfiguration.rootModule, concatConfiguration.modules, orderedModules); + const newModule = new ConcatenatedModule(concatConfiguration.rootModule, Array.from(orderedModules)); + for(const warning of concatConfiguration.warnings) { + newModule.optimizationBailout.push((requestShortener) => { + const reason = getBailoutReason(warning[0], requestShortener); + const reasonPrefix = reason ? `: ${reason}` : ""; + if(warning[0] === warning[1]) + return `ModuleConcatenation: Cannot concat with ${warning[0].readableIdentifier(requestShortener)}${reasonPrefix}`; + else + return `ModuleConcatenation: Cannot concat with ${warning[0].readableIdentifier(requestShortener)} because of ${warning[1].readableIdentifier(requestShortener)}${reasonPrefix}`; + }); + } + for(const m of orderedModules) { + usedModules.add(m); + chunk.removeModule(m); + } + chunk.addModule(newModule); + compilation.modules.push(newModule); + if(chunk.entryModule === concatConfiguration.rootModule) + chunk.entryModule = newModule; + newModule.reasons.forEach(reason => reason.dependency.module = newModule); + newModule.dependencies.forEach(dep => { + if(dep.module) { + dep.module.reasons.forEach(reason => { + if(reason.dependency === dep) + reason.module = newModule; + }); + } + }); + } + compilation.modules = compilation.modules.filter(m => !usedModules.has(m)); + }); + }); + }); + } + + getImports(module) { + return Array.from(new Set(module.dependencies + + // Only harmony Dependencies + .filter(dep => dep instanceof HarmonyImportDependency && dep.module) + + // Dependencies are simple enough to concat them + .filter(dep => { + return !module.dependencies.some(d => + d instanceof HarmonyExportImportedSpecifierDependency && + d.importDependency === dep && + !d.id && + !Array.isArray(dep.module.providedExports) + ); + }) + + // Take the imported module + .map(dep => dep.module) + )); + } + + tryToAdd(config, module, possibleModules, failureCache) { + const cacheEntry = failureCache.get(module); + if(cacheEntry) { + return cacheEntry; + } + + // Already added? + if(config.has(module)) { + return null; + } + + // Not possible to add? + if(!possibleModules.has(module)) { + return module; + } + + // Clone config to make experimental changes + const testConfig = config.clone(); + + // Add the module + testConfig.add(module); + + // Every module which depends on the added module must be in the configuration too. + for(const reason of module.reasons) { + const problem = this.tryToAdd(testConfig, reason.module, possibleModules, failureCache); + if(problem) { + failureCache.set(module, problem); // cache failures for performance + return problem; + } + } + + // Eagerly try to add imports too if possible + for(const imp of this.getImports(module)) { + const problem = this.tryToAdd(testConfig, imp, possibleModules, failureCache); + if(problem) { + config.addWarning(module, problem); + } + } + + // Commit experimental changes + config.set(testConfig); + return null; + } + + addInOrder(module, unorderedSet, orderedSet) { + if(orderedSet.has(module)) return; + if(!unorderedSet.has(module)) return; + orderedSet.add(module); + for(const imp of this.getImports(module)) + this.addInOrder(imp, unorderedSet, orderedSet); + orderedSet.delete(module); + orderedSet.add(module); + } +} + +class ConcatConfiguration { + constructor(rootModule) { + this.rootModule = rootModule; + this.modules = new Set([rootModule]); + this.warnings = new Map(); + } + + add(module) { + this.modules.add(module); + } + + has(module) { + return this.modules.has(module); + } + + isEmpty() { + return this.modules.size === 1; + } + + addWarning(module, problem) { + this.warnings.set(module, problem); + } + + clone() { + const clone = new ConcatConfiguration(this.rootModule); + for(const module of this.modules) + clone.add(module); + for(const pair of this.warnings) + clone.addWarning(pair[0], pair[1]); + return clone; + } + + set(config) { + this.rootModule = config.rootModule; + this.modules = new Set(config.modules); + this.warnings = new Map(config.warnings); + } +} + +module.exports = ModuleConcatenationPlugin; diff --git a/lib/optimize/OccurrenceOrderPlugin.js b/lib/optimize/OccurrenceOrderPlugin.js index dc86b11e3..66d650a00 100644 --- a/lib/optimize/OccurrenceOrderPlugin.js +++ b/lib/optimize/OccurrenceOrderPlugin.js @@ -15,98 +15,84 @@ class OccurrenceOrderPlugin { const preferEntry = this.preferEntry; compiler.plugin("compilation", (compilation) => { compilation.plugin("optimize-module-order", (modules) => { - function entryChunks(m) { - return m.chunks.map((c) => { - const sum = (c.isInitial() ? 1 : 0) + (c.entryModule === m ? 1 : 0); - return sum; - }).reduce((a, b) => { - return a + b; - }, 0); + const occursInInitialChunksMap = new Map(); + const occursInAllChunksMap = new Map(); + + const initialChunkChunkMap = new Map(); + const entryCountMap = new Map(); + modules.forEach(m => { + let initial = 0; + let entry = 0; + m.forEachChunk(c => { + if(c.isInitial()) initial++; + if(c.entryModule === m) entry++; + }); + initialChunkChunkMap.set(m, initial); + entryCountMap.set(m, entry); + }); + + const countOccursInEntry = (sum, r) => { + if(!r.module) return sum; + return sum + initialChunkChunkMap.get(r.module); + }; + const countOccurs = (sum, r) => { + if(!r.module) return sum; + return sum + r.module.getNumberOfChunks(); + }; + + if(preferEntry) { + modules.forEach(m => { + const result = m.reasons.reduce(countOccursInEntry, 0) + initialChunkChunkMap.get(m) + entryCountMap.get(m); + occursInInitialChunksMap.set(m, result); + }); } - function occursInEntry(m) { - if(typeof m.__OccurenceOrderPlugin_occursInEntry === "number") return m.__OccurenceOrderPlugin_occursInEntry; - const result = m.reasons.map((r) => { - if(!r.module) return 0; - return entryChunks(r.module); - }).reduce((a, b) => { - return a + b; - }, 0) + entryChunks(m); - return m.__OccurenceOrderPlugin_occursInEntry = result; - } + modules.forEach(m => { + const result = m.reasons.reduce(countOccurs, 0) + m.getNumberOfChunks() + entryCountMap.get(m); + occursInAllChunksMap.set(m, result); + }); - function occurs(m) { - if(typeof m.__OccurenceOrderPlugin_occurs === "number") return m.__OccurenceOrderPlugin_occurs; - const result = m.reasons.map((r) => { - if(!r.module) return 0; - return r.module.chunks.length; - }).reduce((a, b) => { - return a + b; - }, 0) + m.chunks.length + m.chunks.filter((c) => { - return c.entryModule === m; - }).length; - return m.__OccurenceOrderPlugin_occurs = result; - } modules.sort((a, b) => { if(preferEntry) { - const aEntryOccurs = occursInEntry(a); - const bEntryOccurs = occursInEntry(b); + const aEntryOccurs = occursInInitialChunksMap.get(a); + const bEntryOccurs = occursInInitialChunksMap.get(b); if(aEntryOccurs > bEntryOccurs) return -1; if(aEntryOccurs < bEntryOccurs) return 1; } - const aOccurs = occurs(a); - const bOccurs = occurs(b); + const aOccurs = occursInAllChunksMap.get(a); + const bOccurs = occursInAllChunksMap.get(b); if(aOccurs > bOccurs) return -1; if(aOccurs < bOccurs) return 1; - if(a.identifier() > b.identifier()) return 1; - if(a.identifier() < b.identifier()) return -1; + if(a.index > b.index) return 1; + if(a.index < b.index) return -1; return 0; }); - // TODO refactor to Map - modules.forEach((m) => { - m.__OccurenceOrderPlugin_occursInEntry = undefined; - m.__OccurenceOrderPlugin_occurs = undefined; - }); }); compilation.plugin("optimize-chunk-order", (chunks) => { - function occursInEntry(c) { - if(typeof c.__OccurenceOrderPlugin_occursInEntry === "number") return c.__OccurenceOrderPlugin_occursInEntry; - const result = c.parents.filter((p) => { - return p.isInitial(); - }).length; - return c.__OccurenceOrderPlugin_occursInEntry = result; - } + const occursInInitialChunksMap = new Map(); + + chunks.forEach(c => { + const result = c.parents.reduce((sum, p) => { + if(p.isInitial()) return sum + 1; + return sum; + }, 0); + return occursInInitialChunksMap.set(c, result); + }); function occurs(c) { return c.blocks.length; } - chunks.forEach((c) => { - c.modules.sort((a, b) => { - if(a.identifier() > b.identifier()) return 1; - if(a.identifier() < b.identifier()) return -1; - return 0; - }); - }); + chunks.sort((a, b) => { - const aEntryOccurs = occursInEntry(a); - const bEntryOccurs = occursInEntry(b); + const aEntryOccurs = occursInInitialChunksMap.get(a); + const bEntryOccurs = occursInInitialChunksMap.get(b); if(aEntryOccurs > bEntryOccurs) return -1; if(aEntryOccurs < bEntryOccurs) return 1; const aOccurs = occurs(a); const bOccurs = occurs(b); if(aOccurs > bOccurs) return -1; if(aOccurs < bOccurs) return 1; - if(a.modules.length > b.modules.length) return -1; - if(a.modules.length < b.modules.length) return 1; - for(let i = 0; i < a.modules.length; i++) { - if(a.modules[i].identifier() > b.modules[i].identifier()) return -1; - if(a.modules[i].identifier() < b.modules[i].identifier()) return 1; - } - return 0; - }); - // TODO refactor to Map - chunks.forEach((c) => { - c.__OccurenceOrderPlugin_occursInEntry = undefined; + return a.compareTo(b); }); }); }); diff --git a/lib/optimize/RemoveParentModulesPlugin.js b/lib/optimize/RemoveParentModulesPlugin.js index af4b42dfb..a9deb18de 100644 --- a/lib/optimize/RemoveParentModulesPlugin.js +++ b/lib/optimize/RemoveParentModulesPlugin.js @@ -4,59 +4,31 @@ */ "use strict"; -function chunkContainsModule(chunk, module) { - const chunks = module.chunks; - const modules = chunk.modules; - if(chunks.length < modules.length) { - return chunks.indexOf(chunk) >= 0; - } else { - return modules.indexOf(module) >= 0; - } -} - function hasModule(chunk, module, checkedChunks) { - if(chunkContainsModule(chunk, module)) return [chunk]; + if(chunk.containsModule(module)) return [chunk]; if(chunk.parents.length === 0) return false; return allHaveModule(chunk.parents.filter((c) => { - return checkedChunks.indexOf(c) < 0; + return !checkedChunks.has(c); }), module, checkedChunks); } function allHaveModule(someChunks, module, checkedChunks) { - if(!checkedChunks) checkedChunks = []; - var chunks = []; + if(!checkedChunks) checkedChunks = new Set(); + var chunks = new Set(); for(var i = 0; i < someChunks.length; i++) { - checkedChunks.push(someChunks[i]); + checkedChunks.add(someChunks[i]); var subChunks = hasModule(someChunks[i], module, checkedChunks); if(!subChunks) return false; for(var index = 0; index < subChunks.length; index++) { var item = subChunks[index]; - if(!chunks.length || chunks.indexOf(item) < 0) { - chunks.push(item); - } + chunks.add(item); } } return chunks; } -function debugIds(chunks) { - var list = []; - for(var i = 0; i < chunks.length; i++) { - var debugId = chunks[i].debugId; - - if(typeof debugId !== "number") { - return "no"; - } - - list.push(debugId); - } - - list.sort(); - return list.join(","); -} - class RemoveParentModulesPlugin { apply(compiler) { compiler.plugin("compilation", (compilation) => { @@ -67,19 +39,21 @@ class RemoveParentModulesPlugin { // TODO consider Map when performance has improved https://gist.github.com/sokra/b36098368da7b8f6792fd7c85fca6311 var cache = Object.create(null); - var modules = chunk.modules.slice(); + var modules = chunk.getModules(); for(var i = 0; i < modules.length; i++) { var module = modules[i]; - var dId = debugIds(module.chunks); + var dId = module.getChunkIdsIdent(); var parentChunksWithModule; - if((dId in cache) && dId !== "no") { + if(dId === null) { + parentChunksWithModule = allHaveModule(chunk.parents, module); + } else if(dId in cache) { parentChunksWithModule = cache[dId]; } else { parentChunksWithModule = cache[dId] = allHaveModule(chunk.parents, module); } if(parentChunksWithModule) { - module.rewriteChunkInReasons(chunk, parentChunksWithModule); + module.rewriteChunkInReasons(chunk, Array.from(parentChunksWithModule)); chunk.removeModule(module); } } diff --git a/lib/webpack.js b/lib/webpack.js index b20150800..7964f65da 100644 --- a/lib/webpack.js +++ b/lib/webpack.js @@ -114,6 +114,7 @@ exportPlugins(exports.optimize = {}, "./optimize", [ "DedupePlugin", "LimitChunkCountPlugin", "MinChunkSizePlugin", + "ModuleConcatenationPlugin", "OccurrenceOrderPlugin", "UglifyJsPlugin" ]); diff --git a/package.json b/package.json index 9e8c14c9c..0ffa592bd 100644 --- a/package.json +++ b/package.json @@ -10,11 +10,12 @@ "ajv-keywords": "^2.0.0", "async": "^2.1.2", "enhanced-resolve": "^3.0.0", + "escope": "^3.6.0", "interpret": "^1.0.0", "json-loader": "^0.5.4", "json5": "^0.5.1", "loader-runner": "^2.3.0", - "loader-utils": "^0.2.16", + "loader-utils": "^1.1.0", "memory-fs": "~0.4.1", "mkdirp": "~0.5.0", "node-libs-browser": "^2.0.0", @@ -23,7 +24,7 @@ "tapable": "~0.2.5", "uglify-js": "^2.8.27", "watchpack": "^1.3.1", - "webpack-sources": "^0.2.3", + "webpack-sources": "^1.0.1", "yargs": "^6.0.0" }, "license": "MIT", @@ -36,20 +37,20 @@ "coffee-loader": "~0.7.1", "coffee-script": "^1.10.0", "coveralls": "^2.11.2", - "css-loader": "~0.25.0", + "css-loader": "^0.28.3", "es6-promise-polyfill": "^1.1.1", "eslint": "3.12.2", "eslint-plugin-node": "^3.0.5", "express": "~4.13.1", "extract-text-webpack-plugin": "^2.0.0-beta", - "file-loader": "~0.9.0", + "file-loader": "^0.11.1", "i18n-webpack-plugin": "^0.3.0", "istanbul": "^0.4.5", "jade": "^1.11.0", "jade-loader": "~0.8.0", "js-beautify": "^1.5.10", "less": "^2.5.1", - "less-loader": "^2.0.0", + "less-loader": "^4.0.3", "lodash": "^4.17.4", "mocha": "^3.2.0", "mocha-lcov-reporter": "^1.0.0", @@ -61,12 +62,12 @@ "should": "^11.1.1", "simple-git": "^1.65.0", "sinon": "^2.3.2", - "style-loader": "~0.13.0", + "style-loader": "^0.18.1", "url-loader": "~0.5.0", - "val-loader": "~0.5.0", + "val-loader": "^1.0.2", "vm-browserify": "~0.0.0", "webpack-dev-middleware": "^1.9.0", - "worker-loader": "~0.7.0" + "worker-loader": "^0.8.0" }, "engines": { "node": ">=4.3.0 <5.0.0 || >=5.10" diff --git a/schemas/webpackOptionsSchema.json b/schemas/webpackOptionsSchema.json index c6bcedfe4..cf4b148ff 100644 --- a/schemas/webpackOptionsSchema.json +++ b/schemas/webpackOptionsSchema.json @@ -224,6 +224,9 @@ }, "strictExportPresence": { "type": "boolean" + }, + "strictThisContextOnImports": { + "type": "boolean" } }, "type": "object" @@ -1030,6 +1033,18 @@ "assetsSort": { "type": "string", "description": "sort the assets by that field" + }, + "providedExports": { + "type": "boolean", + "description": "show exports provided by modules" + }, + "usedExports": { + "type": "boolean", + "description": "show exports used by modules" + }, + "optimizationBailout": { + "type": "boolean", + "description": "show reasons why optimization bailed out for modules" } } }, @@ -1042,6 +1057,7 @@ "errors-only", "minimal", "normal", + "detailed", "verbose" ] } diff --git a/test/BinTestCases.test.js b/test/BinTestCases.test.js index 7457edf10..98fff9fe0 100644 --- a/test/BinTestCases.test.js +++ b/test/BinTestCases.test.js @@ -22,7 +22,7 @@ function getTestSpecificArguments(testDirectory) { try { return loadOptsFile(path.join(testDirectory, "test.opts")); } catch(e) { - return []; + return null; } } @@ -51,7 +51,7 @@ describe("BinTestCases", function() { category.tests.forEach(function(testName) { const testDirectory = path.join(casesPath, category.name, testName); - const testArgs = defaultArgs.concat(getTestSpecificArguments(testDirectory)); + const testArgs = getTestSpecificArguments(testDirectory) || defaultArgs; const testAssertions = require(path.join(testDirectory, "test.js")); const outputPath = path.join(path.resolve(casesPath, "../js/bin"), category.name, testName); diff --git a/test/Chunk.test.js b/test/Chunk.test.js index d096dbbfb..0105dae1e 100644 --- a/test/Chunk.test.js +++ b/test/Chunk.test.js @@ -102,7 +102,7 @@ describe("Chunk", () => { }); describe("and the chunk does contain this module", function() { beforeEach(function() { - ChunkInstance.modules = [module]; + ChunkInstance._modules = new Set([module]); }); it("calls module.removeChunk with itself and returns true", function() { ChunkInstance.removeModule(module).should.eql(true); diff --git a/test/Compiler-caching.test.js b/test/Compiler-caching.test.js index d532978ed..82a91bccb 100644 --- a/test/Compiler-caching.test.js +++ b/test/Compiler-caching.test.js @@ -223,21 +223,21 @@ describe("Compiler (caching)", function() { const helper = compile("./temp-cache-fixture/c", options, (stats, files) => { // Built the first time - stats.modules[0].name.should.containEql("a.js"); - stats.modules[0].built.should.be.exactly(true, "a.js should have been built"); + stats.modules[0].name.should.containEql("c.js"); + stats.modules[0].built.should.be.exactly(true, "c.js should have been built"); - stats.modules[1].name.should.containEql("c.js"); - stats.modules[1].built.should.be.exactly(true, "c.js should have been built"); + stats.modules[1].name.should.containEql("a.js"); + stats.modules[1].built.should.be.exactly(true, "a.js should have been built"); setTimeout(() => { helper.runAgain((stats, files, iteration) => { // Not built when cached the second run - stats.modules[0].name.should.containEql("a.js"); - //stats.modules[0].built.should.be.exactly(false, "a.js should not have built"); + stats.modules[0].name.should.containEql("c.js"); + //stats.modules[0].built.should.be.exactly(false, "c.js should not have built"); - stats.modules[1].name.should.containEql("c.js"); - //stats.modules[1].built.should.be.exactly(false, "c.js should not have built"); + stats.modules[1].name.should.containEql("a.js"); + //stats.modules[1].built.should.be.exactly(false, "a.js should not have built"); const aContent = fs.readFileSync(tempFixture.aFilepath).toString().replace("This is a", "This is a MODIFIED"); @@ -247,11 +247,11 @@ describe("Compiler (caching)", function() { helper.runAgain((stats, files, iteration) => { // And only a.js built after it was modified - stats.modules[0].name.should.containEql("a.js"); - stats.modules[0].built.should.be.exactly(true, "a.js should have been built"); + stats.modules[0].name.should.containEql("c.js"); + stats.modules[0].built.should.be.exactly(false, "c.js should not have built"); - stats.modules[1].name.should.containEql("c.js"); - stats.modules[1].built.should.be.exactly(false, "c.js should not have built"); + stats.modules[1].name.should.containEql("a.js"); + stats.modules[1].built.should.be.exactly(true, "a.js should have been built"); done(); }); @@ -269,20 +269,20 @@ describe("Compiler (caching)", function() { const helper = compile("./temp-cache-fixture/c", options, (stats, files) => { // Built the first time - stats.modules[0].name.should.containEql("a.js"); - stats.modules[0].built.should.be.exactly(true, "a.js should have been built"); + stats.modules[0].name.should.containEql("c.js"); + stats.modules[0].built.should.be.exactly(true, "c.js should have been built"); - stats.modules[1].name.should.containEql("c.js"); - stats.modules[1].built.should.be.exactly(true, "c.js should have been built"); + stats.modules[1].name.should.containEql("a.js"); + stats.modules[1].built.should.be.exactly(true, "a.js should have been built"); helper.runAgain((stats, files, iteration) => { // Not built when cached the second run - stats.modules[0].name.should.containEql("a.js"); - //stats.modules[0].built.should.be.exactly(false, "a.js should not have built"); + stats.modules[0].name.should.containEql("c.js"); + //stats.modules[0].built.should.be.exactly(false, "c.js should not have built"); - stats.modules[1].name.should.containEql("c.js"); - //stats.modules[1].built.should.be.exactly(false, "c.js should not have built"); + stats.modules[1].name.should.containEql("a.js"); + //stats.modules[1].built.should.be.exactly(false, "a.js should not have built"); const aContent = fs.readFileSync(tempFixture.aFilepath).toString().replace("This is a", "This is a MODIFIED"); @@ -291,11 +291,11 @@ describe("Compiler (caching)", function() { helper.runAgain((stats, files, iteration) => { // And only a.js built after it was modified - stats.modules[0].name.should.containEql("a.js"); - stats.modules[0].built.should.be.exactly(true, "a.js should have been built"); + stats.modules[0].name.should.containEql("c.js"); + //stats.modules[0].built.should.be.exactly(false, "c.js should not have built"); - stats.modules[1].name.should.containEql("c.js"); - //stats.modules[1].built.should.be.exactly(false, "c.js should not have built"); + stats.modules[1].name.should.containEql("a.js"); + stats.modules[1].built.should.be.exactly(true, "a.js should have been built"); done(); }); diff --git a/test/Compiler.test.js b/test/Compiler.test.js index fd657dd30..7a7d9eaea 100644 --- a/test/Compiler.test.js +++ b/test/Compiler.test.js @@ -78,7 +78,7 @@ describe("Compiler", () => { Object.keys(files).should.be.eql(["/main.js"]); const bundle = files["/main.js"]; bundle.should.containEql("function __webpack_require__("); - bundle.should.containEql("__webpack_require__(/*! ./a */ 0);"); + bundle.should.containEql("__webpack_require__(/*! ./a */ 1);"); bundle.should.containEql("./c.js"); bundle.should.containEql("./a.js"); bundle.should.containEql("This is a"); @@ -101,7 +101,7 @@ describe("Compiler", () => { bundle.should.containEql("./main1.js"); bundle.should.containEql("./a.js"); bundle.should.containEql("./b.js"); - bundle.should.containEql("./~/m1/a.js"); + bundle.should.containEql("./node_modules/m1/a.js"); bundle.should.containEql("This is a"); bundle.should.containEql("This is b"); bundle.should.containEql("This is m1/a"); diff --git a/test/MultiStats.test.js b/test/MultiStats.test.js index c0737a0e8..211014e88 100644 --- a/test/MultiStats.test.js +++ b/test/MultiStats.test.js @@ -210,7 +210,6 @@ describe("MultiStats", () => { "(xyz890-compilation) xyz890-warning-1", "(xyz890-compilation) xyz890-warning-2" ], - hash: "abc123xyz890", children: [{ warnings: ["abc123-warning"], errors: ["abc123-error"], diff --git a/test/Stats.test.js b/test/Stats.test.js index 9943d9a50..c49ab7930 100644 --- a/test/Stats.test.js +++ b/test/Stats.test.js @@ -154,22 +154,7 @@ describe("Stats", () => { describe("Presets", () => { describe("presetToOptions", () => { it("returns correct object with 'Normal'", () => { - Stats.presetToOptions("Normal").should.eql({ - assets: false, - version: false, - timings: true, - hash: true, - entrypoints: false, - chunks: true, - chunkModules: false, - errorDetails: true, - reasons: false, - depth: false, - usedExports: false, - providedExports: false, - colors: true, - performance: true - }); + Stats.presetToOptions("Normal").should.eql({}); }); it("truthy values behave as 'normal'", () => { const normalOpts = Stats.presetToOptions("normal"); @@ -182,25 +167,7 @@ describe("Stats", () => { }); it("returns correct object with 'none'", () => { Stats.presetToOptions("none").should.eql({ - hash: false, - version: false, - timings: false, - assets: false, - entrypoints: false, - chunks: false, - chunkModules: false, - modules: false, - reasons: false, - depth: false, - usedExports: false, - providedExports: false, - children: false, - source: false, - errors: false, - errorDetails: false, - warnings: false, - publicPath: false, - performance: false + all: false }); }); it("falsy values behave as 'none'", () => { diff --git a/test/TestCases.test.js b/test/TestCases.test.js index fd97d6e01..5c6461626 100644 --- a/test/TestCases.test.js +++ b/test/TestCases.test.js @@ -22,6 +22,11 @@ describe("TestCases", () => { }); [{ name: "normal" + }, { + name: "concat", + plugins: [ + new webpack.optimize.ModuleConcatenationPlugin() + ] }, { name: "hot", plugins: [ diff --git a/test/binCases/entry/multi-file/test.js b/test/binCases/entry/multi-file/test.js index 2fec036be..be912a01e 100644 --- a/test/binCases/entry/multi-file/test.js +++ b/test/binCases/entry/multi-file/test.js @@ -5,9 +5,9 @@ module.exports = function testAssertions(code, stdout, stderr) { stdout.should.be.ok(); stdout[4].should.containEql("null.js"); - stdout[5].should.match(/a\.js.*\{0\}/); + stdout[5].should.match(/multi.*index\.js.*a\.js/); // should have multi-file entry stdout[6].should.match(/index\.js.*\{0\}/); - stdout[7].should.match(/multi.*index\.js.*a\.js/); // should have multi-file entry + stdout[7].should.match(/a\.js.*\{0\}/); stderr.should.be.empty(); }; diff --git a/test/binCases/entry/multi-file/test.opts b/test/binCases/entry/multi-file/test.opts index 7e426fa77..53402ac53 100644 --- a/test/binCases/entry/multi-file/test.opts +++ b/test/binCases/entry/multi-file/test.opts @@ -1 +1,6 @@ +--entry ./index.js --entry ./a.js +--config ./webpack.config.js +--output-filename [name].js +--output-chunk-filename [id].chunk.js +--target async-node diff --git a/test/binCases/entry/named-entry/test.opts b/test/binCases/entry/named-entry/test.opts index fce9b8c17..b8f0fa016 100644 --- a/test/binCases/entry/named-entry/test.opts +++ b/test/binCases/entry/named-entry/test.opts @@ -1 +1,6 @@ --entry foo=./a.js +--entry ./index.js +--config ./webpack.config.js +--output-filename [name].js +--output-chunk-filename [id].chunk.js +--target async-node diff --git a/test/binCases/entry/non-hyphenated-args/test.js b/test/binCases/entry/non-hyphenated-args/test.js index a94b8a518..2b4c30827 100644 --- a/test/binCases/entry/non-hyphenated-args/test.js +++ b/test/binCases/entry/non-hyphenated-args/test.js @@ -6,8 +6,8 @@ module.exports = function testAssertions(code, stdout, stderr) { stdout.should.be.ok(); stdout[4].should.containEql("null.js"); stdout[5].should.containEql("main.js"); // non-hyphenated arg ./a.js should create chunk "main" - stdout[6].should.match(/a\.js.*\{1\}/); // a.js should be in chunk 1 - stdout[7].should.match(/index\.js.*\{0\}/); // index.js should be in chunk 0 + stdout[6].should.match(/index\.js.*\{0\}/); // index.js should be in chunk 0 + stdout[7].should.match(/a\.js.*\{1\}/); // a.js should be in chunk 1 stderr.should.be.empty(); }; diff --git a/test/binCases/entry/non-hyphenated-args/test.opts b/test/binCases/entry/non-hyphenated-args/test.opts index 777a4a4b9..6b8499d52 100644 --- a/test/binCases/entry/non-hyphenated-args/test.opts +++ b/test/binCases/entry/non-hyphenated-args/test.opts @@ -1 +1,6 @@ ./a.js +--entry ./index.js +--config ./webpack.config.js +--output-filename [name].js +--output-chunk-filename [id].chunk.js +--target async-node diff --git a/test/binCases/plugins/uglifyjsplugin-empty-args/test.opts b/test/binCases/plugins/uglifyjsplugin-empty-args/test.opts index 9c67444ed..edc5ab3dc 100644 --- a/test/binCases/plugins/uglifyjsplugin-empty-args/test.opts +++ b/test/binCases/plugins/uglifyjsplugin-empty-args/test.opts @@ -1 +1,6 @@ +--entry ./index.js +--config ./webpack.config.js +--output-filename [name].js +--output-chunk-filename [id].chunk.js +--target async-node --plugin webpack/lib/optimize/UglifyJsPlugin diff --git a/test/binCases/stats/custom-preset/index.js b/test/binCases/stats/custom-preset/index.js new file mode 100644 index 000000000..e7134e700 --- /dev/null +++ b/test/binCases/stats/custom-preset/index.js @@ -0,0 +1 @@ +module.exports = "foo"; diff --git a/test/binCases/stats/custom-preset/test.js b/test/binCases/stats/custom-preset/test.js new file mode 100644 index 000000000..0b93dfe3c --- /dev/null +++ b/test/binCases/stats/custom-preset/test.js @@ -0,0 +1,8 @@ +"use strict"; + +module.exports = function testAssertions(code, stdout, stderr) { + stderr.should.be.empty(); + code.should.be.eql(0); + + stdout.should.be.empty(); +}; diff --git a/test/binCases/stats/custom-preset/test.opts b/test/binCases/stats/custom-preset/test.opts new file mode 100644 index 000000000..4747dc2f3 --- /dev/null +++ b/test/binCases/stats/custom-preset/test.opts @@ -0,0 +1,5 @@ +--entry ./index.js +--output-filename [name].js +--output-chunk-filename [id].chunk.js +--target async-node +--display none diff --git a/test/binCases/stats/none/index.js b/test/binCases/stats/none/index.js new file mode 100644 index 000000000..e7134e700 --- /dev/null +++ b/test/binCases/stats/none/index.js @@ -0,0 +1 @@ +module.exports = "foo"; diff --git a/test/binCases/stats/none/test.js b/test/binCases/stats/none/test.js new file mode 100644 index 000000000..ee38bdcc2 --- /dev/null +++ b/test/binCases/stats/none/test.js @@ -0,0 +1,8 @@ +"use strict"; + +module.exports = function testAssertions(code, stdout, stderr) { + code.should.be.eql(0); + + stdout.should.be.empty(); + stderr.should.be.empty(); +}; diff --git a/test/binCases/stats/none/webpack.config.js b/test/binCases/stats/none/webpack.config.js new file mode 100644 index 000000000..40a6ae807 --- /dev/null +++ b/test/binCases/stats/none/webpack.config.js @@ -0,0 +1,6 @@ +var path = require("path"); + +module.exports = { + entry: path.resolve(__dirname, "./index"), + stats: "none" +}; diff --git a/test/binCases/stats/single-config/test.js b/test/binCases/stats/single-config/test.js index 02dc1de94..a961bcd51 100644 --- a/test/binCases/stats/single-config/test.js +++ b/test/binCases/stats/single-config/test.js @@ -8,9 +8,10 @@ module.exports = function testAssertions(code, stdout, stderr) { stdout[1].should.containEql("Version: "); stdout[2].should.containEql("Time: "); stdout[4].should.containEql("\u001b[1m\u001b[32mnull.js\u001b[39m\u001b[22m"); - stdout[5].should.not.containEql("./index.js"); - stdout[5].should.not.containEql("[built]"); - stdout[5].should.containEql("1 hidden module"); + stdout[5].should.containEql("chunk"); + stdout[6].should.not.containEql("./index.js"); + stdout[6].should.not.containEql("[built]"); + stdout[6].should.containEql("1 module"); stderr.should.be.empty(); }; diff --git a/test/binCases/watch/multi-config-watch-opt/test.opts b/test/binCases/watch/multi-config-watch-opt/test.opts index c4b4d4f8b..38534ad57 100644 --- a/test/binCases/watch/multi-config-watch-opt/test.opts +++ b/test/binCases/watch/multi-config-watch-opt/test.opts @@ -1 +1,6 @@ +--entry ./index.js +--config ./webpack.config.js +--output-filename [name].js +--output-chunk-filename [id].chunk.js +--target async-node --watch diff --git a/test/binCases/watch/single-config-watch-opt/test.opts b/test/binCases/watch/single-config-watch-opt/test.opts index c4b4d4f8b..38534ad57 100644 --- a/test/binCases/watch/single-config-watch-opt/test.opts +++ b/test/binCases/watch/single-config-watch-opt/test.opts @@ -1 +1,6 @@ +--entry ./index.js +--config ./webpack.config.js +--output-filename [name].js +--output-chunk-filename [id].chunk.js +--target async-node --watch diff --git a/test/cases/loaders/_css/generateCss.js b/test/cases/loaders/_css/generateCss.js index f3adcd1da..b3bf64996 100644 --- a/test/cases/loaders/_css/generateCss.js +++ b/test/cases/loaders/_css/generateCss.js @@ -1,3 +1,7 @@ var fs = require("fs"); var path = require("path"); -module.exports = fs.readFileSync(path.join(path.dirname(__filename), "stylesheet.css"), "utf-8") + "\n.generated { color: red; }"; +module.exports = function() { + return { + code: fs.readFileSync(path.join(path.dirname(__filename), "stylesheet.css"), "utf-8") + "\n.generated { color: red; }" + }; +}; diff --git a/test/cases/scope-hoisting/chained-reexport/a.js b/test/cases/scope-hoisting/chained-reexport/a.js new file mode 100644 index 000000000..df79c24c5 --- /dev/null +++ b/test/cases/scope-hoisting/chained-reexport/a.js @@ -0,0 +1 @@ +export var named = "named"; diff --git a/test/cases/scope-hoisting/chained-reexport/b.js b/test/cases/scope-hoisting/chained-reexport/b.js new file mode 100644 index 000000000..378dcf843 --- /dev/null +++ b/test/cases/scope-hoisting/chained-reexport/b.js @@ -0,0 +1 @@ +export * from "./a"; diff --git a/test/cases/scope-hoisting/chained-reexport/c.js b/test/cases/scope-hoisting/chained-reexport/c.js new file mode 100644 index 000000000..feca56aea --- /dev/null +++ b/test/cases/scope-hoisting/chained-reexport/c.js @@ -0,0 +1 @@ +export { named } from "./b"; diff --git a/test/cases/scope-hoisting/chained-reexport/index.js b/test/cases/scope-hoisting/chained-reexport/index.js new file mode 100644 index 000000000..5ac21327b --- /dev/null +++ b/test/cases/scope-hoisting/chained-reexport/index.js @@ -0,0 +1,5 @@ +import { named } from "./c"; + +it("should have the correct values", function() { + named.should.be.eql("named"); +}); diff --git a/test/cases/scope-hoisting/export-namespace/index.js b/test/cases/scope-hoisting/export-namespace/index.js new file mode 100644 index 000000000..6c1b35d6f --- /dev/null +++ b/test/cases/scope-hoisting/export-namespace/index.js @@ -0,0 +1,16 @@ +import { ns as ns1 } from "./module1"; +const ns2 = require("./module2").ns; + +it("should allow to export a namespace object (concated)", function() { + ns1.should.be.eql({ + a: "a", + b: "b" + }); +}); + +it("should allow to export a namespace object (exposed)", function() { + ns2.should.be.eql({ + a: "a", + b: "b" + }); +}); diff --git a/test/cases/scope-hoisting/export-namespace/module1.js b/test/cases/scope-hoisting/export-namespace/module1.js new file mode 100644 index 000000000..59e7d89f9 --- /dev/null +++ b/test/cases/scope-hoisting/export-namespace/module1.js @@ -0,0 +1,2 @@ +import * as ns from "./ns1"; +export { ns }; diff --git a/test/cases/scope-hoisting/export-namespace/module2.js b/test/cases/scope-hoisting/export-namespace/module2.js new file mode 100644 index 000000000..32e099888 --- /dev/null +++ b/test/cases/scope-hoisting/export-namespace/module2.js @@ -0,0 +1,2 @@ +import * as ns from "./ns2"; +export { ns }; diff --git a/test/cases/scope-hoisting/export-namespace/ns1.js b/test/cases/scope-hoisting/export-namespace/ns1.js new file mode 100644 index 000000000..2151809d0 --- /dev/null +++ b/test/cases/scope-hoisting/export-namespace/ns1.js @@ -0,0 +1,2 @@ +export var a = "a"; +export var b = "b"; diff --git a/test/cases/scope-hoisting/export-namespace/ns2.js b/test/cases/scope-hoisting/export-namespace/ns2.js new file mode 100644 index 000000000..2151809d0 --- /dev/null +++ b/test/cases/scope-hoisting/export-namespace/ns2.js @@ -0,0 +1,2 @@ +export var a = "a"; +export var b = "b"; diff --git a/test/cases/scope-hoisting/indirect-reexport/a.js b/test/cases/scope-hoisting/indirect-reexport/a.js new file mode 100644 index 000000000..f22b615c7 --- /dev/null +++ b/test/cases/scope-hoisting/indirect-reexport/a.js @@ -0,0 +1 @@ +export default "named"; diff --git a/test/cases/scope-hoisting/indirect-reexport/b.js b/test/cases/scope-hoisting/indirect-reexport/b.js new file mode 100644 index 000000000..fa64420ef --- /dev/null +++ b/test/cases/scope-hoisting/indirect-reexport/b.js @@ -0,0 +1,2 @@ +import named from "./a"; +export { named } diff --git a/test/cases/scope-hoisting/indirect-reexport/c.js b/test/cases/scope-hoisting/indirect-reexport/c.js new file mode 100644 index 000000000..87b65ebdf --- /dev/null +++ b/test/cases/scope-hoisting/indirect-reexport/c.js @@ -0,0 +1,2 @@ +import { named } from "./b"; +export { named } diff --git a/test/cases/scope-hoisting/indirect-reexport/index.js b/test/cases/scope-hoisting/indirect-reexport/index.js new file mode 100644 index 000000000..f9a31c159 --- /dev/null +++ b/test/cases/scope-hoisting/indirect-reexport/index.js @@ -0,0 +1,5 @@ +var c = require("./c"); + +it("should have the correct values", function() { + c.named.should.be.eql("named"); +}); diff --git a/test/cases/scope-hoisting/intra-references/a.js b/test/cases/scope-hoisting/intra-references/a.js new file mode 100644 index 000000000..dfb1001dd --- /dev/null +++ b/test/cases/scope-hoisting/intra-references/a.js @@ -0,0 +1 @@ +export { default } from "./b"; diff --git a/test/cases/scope-hoisting/intra-references/b.js b/test/cases/scope-hoisting/intra-references/b.js new file mode 100644 index 000000000..04134a85c --- /dev/null +++ b/test/cases/scope-hoisting/intra-references/b.js @@ -0,0 +1 @@ +export { default } from "./c"; diff --git a/test/cases/scope-hoisting/intra-references/c.js b/test/cases/scope-hoisting/intra-references/c.js new file mode 100644 index 000000000..5c6b89abf --- /dev/null +++ b/test/cases/scope-hoisting/intra-references/c.js @@ -0,0 +1 @@ +export default "ok"; diff --git a/test/cases/scope-hoisting/intra-references/index.js b/test/cases/scope-hoisting/intra-references/index.js new file mode 100644 index 000000000..371843667 --- /dev/null +++ b/test/cases/scope-hoisting/intra-references/index.js @@ -0,0 +1,9 @@ +import value from "./a"; + +it("should have the correct values", function() { + value.should.be.eql("ok"); +}); + + +// prevent scope hoisting of b +require("./b"); diff --git a/test/cases/scope-hoisting/reexport-cjs/a.js b/test/cases/scope-hoisting/reexport-cjs/a.js new file mode 100644 index 000000000..c1ce35449 --- /dev/null +++ b/test/cases/scope-hoisting/reexport-cjs/a.js @@ -0,0 +1 @@ +exports.named = "named"; diff --git a/test/cases/scope-hoisting/reexport-cjs/b.js b/test/cases/scope-hoisting/reexport-cjs/b.js new file mode 100644 index 000000000..ee6e29df9 --- /dev/null +++ b/test/cases/scope-hoisting/reexport-cjs/b.js @@ -0,0 +1 @@ +export { named } from "./a"; diff --git a/test/cases/scope-hoisting/reexport-cjs/c.js b/test/cases/scope-hoisting/reexport-cjs/c.js new file mode 100644 index 000000000..feca56aea --- /dev/null +++ b/test/cases/scope-hoisting/reexport-cjs/c.js @@ -0,0 +1 @@ +export { named } from "./b"; diff --git a/test/cases/scope-hoisting/reexport-cjs/index.js b/test/cases/scope-hoisting/reexport-cjs/index.js new file mode 100644 index 000000000..5ac21327b --- /dev/null +++ b/test/cases/scope-hoisting/reexport-cjs/index.js @@ -0,0 +1,5 @@ +import { named } from "./c"; + +it("should have the correct values", function() { + named.should.be.eql("named"); +}); diff --git a/test/cases/scope-hoisting/reexport-exposed-cjs/a.js b/test/cases/scope-hoisting/reexport-exposed-cjs/a.js new file mode 100644 index 000000000..c1ce35449 --- /dev/null +++ b/test/cases/scope-hoisting/reexport-exposed-cjs/a.js @@ -0,0 +1 @@ +exports.named = "named"; diff --git a/test/cases/scope-hoisting/reexport-exposed-cjs/b.js b/test/cases/scope-hoisting/reexport-exposed-cjs/b.js new file mode 100644 index 000000000..ee6e29df9 --- /dev/null +++ b/test/cases/scope-hoisting/reexport-exposed-cjs/b.js @@ -0,0 +1 @@ +export { named } from "./a"; diff --git a/test/cases/scope-hoisting/reexport-exposed-cjs/c.js b/test/cases/scope-hoisting/reexport-exposed-cjs/c.js new file mode 100644 index 000000000..feca56aea --- /dev/null +++ b/test/cases/scope-hoisting/reexport-exposed-cjs/c.js @@ -0,0 +1 @@ +export { named } from "./b"; diff --git a/test/cases/scope-hoisting/reexport-exposed-cjs/index.js b/test/cases/scope-hoisting/reexport-exposed-cjs/index.js new file mode 100644 index 000000000..f9a31c159 --- /dev/null +++ b/test/cases/scope-hoisting/reexport-exposed-cjs/index.js @@ -0,0 +1,5 @@ +var c = require("./c"); + +it("should have the correct values", function() { + c.named.should.be.eql("named"); +}); diff --git a/test/cases/scope-hoisting/reexport-exposed-default-cjs/a.js b/test/cases/scope-hoisting/reexport-exposed-default-cjs/a.js new file mode 100644 index 000000000..674b586d5 --- /dev/null +++ b/test/cases/scope-hoisting/reexport-exposed-default-cjs/a.js @@ -0,0 +1 @@ +module.exports = "default"; diff --git a/test/cases/scope-hoisting/reexport-exposed-default-cjs/b.js b/test/cases/scope-hoisting/reexport-exposed-default-cjs/b.js new file mode 100644 index 000000000..ffe5601ed --- /dev/null +++ b/test/cases/scope-hoisting/reexport-exposed-default-cjs/b.js @@ -0,0 +1 @@ +export { default } from "./a"; diff --git a/test/cases/scope-hoisting/reexport-exposed-default-cjs/c.js b/test/cases/scope-hoisting/reexport-exposed-default-cjs/c.js new file mode 100644 index 000000000..dfb1001dd --- /dev/null +++ b/test/cases/scope-hoisting/reexport-exposed-default-cjs/c.js @@ -0,0 +1 @@ +export { default } from "./b"; diff --git a/test/cases/scope-hoisting/reexport-exposed-default-cjs/index.js b/test/cases/scope-hoisting/reexport-exposed-default-cjs/index.js new file mode 100644 index 000000000..80958b553 --- /dev/null +++ b/test/cases/scope-hoisting/reexport-exposed-default-cjs/index.js @@ -0,0 +1,5 @@ +var c = require("./c"); + +it("should have the correct values", function() { + c.default.should.be.eql("default"); +}); diff --git a/test/cases/scope-hoisting/reexport-exposed-harmony/a.js b/test/cases/scope-hoisting/reexport-exposed-harmony/a.js new file mode 100644 index 000000000..df79c24c5 --- /dev/null +++ b/test/cases/scope-hoisting/reexport-exposed-harmony/a.js @@ -0,0 +1 @@ +export var named = "named"; diff --git a/test/cases/scope-hoisting/reexport-exposed-harmony/b.js b/test/cases/scope-hoisting/reexport-exposed-harmony/b.js new file mode 100644 index 000000000..378dcf843 --- /dev/null +++ b/test/cases/scope-hoisting/reexport-exposed-harmony/b.js @@ -0,0 +1 @@ +export * from "./a"; diff --git a/test/cases/scope-hoisting/reexport-exposed-harmony/c.js b/test/cases/scope-hoisting/reexport-exposed-harmony/c.js new file mode 100644 index 000000000..feca56aea --- /dev/null +++ b/test/cases/scope-hoisting/reexport-exposed-harmony/c.js @@ -0,0 +1 @@ +export { named } from "./b"; diff --git a/test/cases/scope-hoisting/reexport-exposed-harmony/index.js b/test/cases/scope-hoisting/reexport-exposed-harmony/index.js new file mode 100644 index 000000000..f9a31c159 --- /dev/null +++ b/test/cases/scope-hoisting/reexport-exposed-harmony/index.js @@ -0,0 +1,5 @@ +var c = require("./c"); + +it("should have the correct values", function() { + c.named.should.be.eql("named"); +}); diff --git a/test/cases/scope-hoisting/renaming-4967/file1.js b/test/cases/scope-hoisting/renaming-4967/file1.js new file mode 100644 index 000000000..952255b8c --- /dev/null +++ b/test/cases/scope-hoisting/renaming-4967/file1.js @@ -0,0 +1,10 @@ +export function a() { + return "ok"; +} + +export function test() { + function file1_js_a() { + return "fail"; + } + return a(); +} diff --git a/test/cases/scope-hoisting/renaming-4967/index.js b/test/cases/scope-hoisting/renaming-4967/index.js new file mode 100644 index 000000000..445ebec05 --- /dev/null +++ b/test/cases/scope-hoisting/renaming-4967/index.js @@ -0,0 +1,5 @@ +it("should check existing variables when renaming", function() { + require("./module").d.x().should.be.eql("ok"); + require("./module").c.a().should.be.eql("ok"); + require("./module").test().should.be.eql("ok"); +}); diff --git a/test/cases/scope-hoisting/renaming-4967/module.js b/test/cases/scope-hoisting/renaming-4967/module.js new file mode 100644 index 000000000..d597dacb3 --- /dev/null +++ b/test/cases/scope-hoisting/renaming-4967/module.js @@ -0,0 +1,18 @@ +import { a as b, test } from './file1'; + +var c = { + a: function a() { + return b(); + }, +}; + +var d = { + x: function x() { + function a() { + return "fail"; + } + return b(); + }, +}; + +export { c, d, test }; diff --git a/test/cases/scope-hoisting/simple/index.js b/test/cases/scope-hoisting/simple/index.js new file mode 100644 index 000000000..b0ca24d53 --- /dev/null +++ b/test/cases/scope-hoisting/simple/index.js @@ -0,0 +1,6 @@ +import value, { named } from "./module"; + +it("should have the correct values", function() { + value.should.be.eql("default"); + named.should.be.eql("named"); +}); diff --git a/test/cases/scope-hoisting/simple/module.js b/test/cases/scope-hoisting/simple/module.js new file mode 100644 index 000000000..95dac8cca --- /dev/null +++ b/test/cases/scope-hoisting/simple/module.js @@ -0,0 +1,2 @@ +export default "default"; +export var named = "named"; diff --git a/test/configCases/async-commons-chunk/existing-name/index.js b/test/configCases/async-commons-chunk/existing-name/index.js index 72e5842dd..455d37ab0 100644 --- a/test/configCases/async-commons-chunk/existing-name/index.js +++ b/test/configCases/async-commons-chunk/existing-name/index.js @@ -1,19 +1,19 @@ require("should"); const sinon = require("sinon"); -const chunkLoadingSpy = sinon.spy(__webpack_require__, 'e'); +const chunkLoadingSpy = sinon.spy(__webpack_require__, "e"); it("should not have duplicate chunks in blocks", function(done) { // This split point should contain: a require.ensure([], function(require) { require("./a").should.be.eql("a"); - }, 'a'); + }, "a"); // This split point should contain: a and b - we use CommonsChunksPlugin to // have it only contain b and make chunk a be an async dependency. require.ensure([], function(require) { require("./a").should.be.eql("a"); require("./b").should.be.eql("b"); - }, 'a+b'); + }, "a+b"); // This split point should contain: a, b and c - we use CommonsChunksPlugin to // have it only contain c and make chunks a and a+b be async dependencies. @@ -21,13 +21,13 @@ it("should not have duplicate chunks in blocks", function(done) { require("./a").should.be.eql("a"); require("./b").should.be.eql("b"); require("./c").should.be.eql("c"); - }, 'a+b+c'); + }, "a+b+c"); // Each of the require.ensures above should end up resolving chunks: // - a // - a, a+b // - a, a+b, a+b+c chunkLoadingSpy.callCount.should.be.eql(6); - chunkLoadingSpy.args.should.be.eql([[0], [0], [1], [0], [1], [2]]); + chunkLoadingSpy.args.should.be.eql([["a"], ["a+b"], ["a"], ["a+b+c"], ["a+b"], ["a"]]); done(); }); diff --git a/test/configCases/async-commons-chunk/existing-name/webpack.config.js b/test/configCases/async-commons-chunk/existing-name/webpack.config.js index 2c8ad555f..14c7f7b35 100644 --- a/test/configCases/async-commons-chunk/existing-name/webpack.config.js +++ b/test/configCases/async-commons-chunk/existing-name/webpack.config.js @@ -10,5 +10,6 @@ module.exports = { chunks: ["a", "a+b"], async: "a", }), + new webpack.NamedChunksPlugin() ] }; diff --git a/test/configCases/code-generation/use-strict/index.js b/test/configCases/code-generation/use-strict/index.js index 1cd3a884c..5f259784a 100644 --- a/test/configCases/code-generation/use-strict/index.js +++ b/test/configCases/code-generation/use-strict/index.js @@ -16,11 +16,11 @@ it("should include only one use strict per module", function() { } matches.should.be.eql([ + "it(\"should include only one use strict per module\", function() {", + "Object.defineProperty(__webpack_exports__, \"__esModule\", { value: true });", "Object.defineProperty(__webpack_exports__, \"__esModule\", { value: true });", "Object.defineProperty(__webpack_exports__, \"__esModule\", { value: true });", "Object.defineProperty(__webpack_exports__, \"__esModule\", { value: true });", "/* unused harmony default export */ var _unused_webpack_default_export = (\"a\");", - "Object.defineProperty(__webpack_exports__, \"__esModule\", { value: true });", - "it(\"should include only one use strict per module\", function() {" ]); }); diff --git a/test/configCases/loaders/issue-3320/node_modules/any-loader.js b/test/configCases/loaders/issue-3320/node_modules/any-loader.js index 8aae39f90..956e65bee 100644 --- a/test/configCases/loaders/issue-3320/node_modules/any-loader.js +++ b/test/configCases/loaders/issue-3320/node_modules/any-loader.js @@ -2,7 +2,7 @@ var loaderUtils = require('loader-utils'); module.exports = function(source) { var loaderContext = this; - var options = loaderUtils.parseQuery(loaderContext.query); + var options = loaderUtils.getOptions(loaderContext); - return "module.exports=" + JSON.stringify(options.foo) + return "module.exports=" + JSON.stringify(options.foo); } diff --git a/test/cases/parsing/harmony-this/abc.js b/test/configCases/parsing/harmony-this/abc.js similarity index 100% rename from test/cases/parsing/harmony-this/abc.js rename to test/configCases/parsing/harmony-this/abc.js diff --git a/test/cases/parsing/harmony-this/index.js b/test/configCases/parsing/harmony-this/index.js similarity index 83% rename from test/cases/parsing/harmony-this/index.js rename to test/configCases/parsing/harmony-this/index.js index ae8c422a5..af774470b 100644 --- a/test/cases/parsing/harmony-this/index.js +++ b/test/configCases/parsing/harmony-this/index.js @@ -13,8 +13,10 @@ it("should have this = undefined on imported non-strict functions", function() { x B().should.be.eql("undefined"); x - abc.a().should.be.eql(abc); + abc.a().should.be.type("object"); x + var thing = abc.a(); + Object.keys(thing).should.be.eql(["a", "b", "default"]); }); import C2, { C } from "./new"; diff --git a/test/cases/parsing/harmony-this/new.js b/test/configCases/parsing/harmony-this/new.js similarity index 100% rename from test/cases/parsing/harmony-this/new.js rename to test/configCases/parsing/harmony-this/new.js diff --git a/test/configCases/parsing/harmony-this/webpack.config.js b/test/configCases/parsing/harmony-this/webpack.config.js new file mode 100644 index 000000000..dfb1984cf --- /dev/null +++ b/test/configCases/parsing/harmony-this/webpack.config.js @@ -0,0 +1,5 @@ +module.exports = { + module: { + strictThisContextOnImports: true + } +}; diff --git a/test/configCases/plugins/uglifyjs-plugin/index.js b/test/configCases/plugins/uglifyjs-plugin/index.js index 040074e30..9d81d8042 100644 --- a/test/configCases/plugins/uglifyjs-plugin/index.js +++ b/test/configCases/plugins/uglifyjs-plugin/index.js @@ -20,7 +20,7 @@ it("should pass mangle options", function() { var fs = require("fs"), path = require("path"); var source = fs.readFileSync(path.join(__dirname, "ie8.js"), "utf-8"); - source.should.containEql("function r(n){return function(t){try{n()}catch(n){t(n)}}}"); + source.should.containEql("function r(t){return function(n){try{t()}catch(t){n(t)}}}"); }); it("should extract comments to separate file", function() { @@ -48,7 +48,7 @@ it("should pass compress options", function() { var fs = require("fs"), path = require("path"); var source = fs.readFileSync(path.join(__dirname, "compress.js"), "utf-8"); - source.should.containEql("function e(){var n=2;n=3,console.log(1+n),console.log(n+3),console.log(4),console.log(1+n+3)}"); + source.should.containEql("function e(){var o=2;o=3,console.log(1+o),console.log(o+3),console.log(4),console.log(1+o+3)}"); }); require.include("./test.js"); diff --git a/test/configCases/records/issue-2991/test.js b/test/configCases/records/issue-2991/test.js index 48ae7d80d..b8c209e31 100644 --- a/test/configCases/records/issue-2991/test.js +++ b/test/configCases/records/issue-2991/test.js @@ -9,10 +9,10 @@ it("should write relative paths to records", function() { content.should.eql(`{ "modules": { "byIdentifier": { - "external \\"fs\\"": 0, - "external \\"path\\"": 1, - "ignored pkgs/somepackage/foo": 2, - "test.js": 3 + "test.js": 0, + "ignored pkgs/somepackage/foo": 1, + "external \\"fs\\"": 2, + "external \\"path\\"": 3 }, "usedIds": { "0": 0, diff --git a/test/configCases/records/issue-2991/webpack.config.js b/test/configCases/records/issue-2991/webpack.config.js index 9da472364..dea32c760 100644 --- a/test/configCases/records/issue-2991/webpack.config.js +++ b/test/configCases/records/issue-2991/webpack.config.js @@ -2,7 +2,7 @@ var path = require("path"); module.exports = { entry: "./test", - recordsPath: path.resolve(__dirname, "../../../js/config/records/issue-2991/records.json"), + recordsOutputPath: path.resolve(__dirname, "../../../js/config/records/issue-2991/records.json"), target: "node", node: { __dirname: false diff --git a/test/statsCases/aggressive-splitting-entry/expected.txt b/test/statsCases/aggressive-splitting-entry/expected.txt index d00d71dc1..fff900916 100644 --- a/test/statsCases/aggressive-splitting-entry/expected.txt +++ b/test/statsCases/aggressive-splitting-entry/expected.txt @@ -1,7 +1,7 @@ Hash: c4756fe25e35ccb187f7 Time: Xms Asset Size Chunks Chunk Names -48c8b1dae03a37363ec8.js 4.37 kB 1 [emitted] +48c8b1dae03a37363ec8.js 4.2 kB 1 [emitted] 002fc3bb6fc14459f8e8.js 2.23 kB 2 [emitted] 9356e9a0fb00a97b2e73.js 1.94 kB 3 [emitted] 88d78642a86768757078.js 979 bytes 4 [emitted] diff --git a/test/statsCases/aggressive-splitting-entry/webpack.config.js b/test/statsCases/aggressive-splitting-entry/webpack.config.js index 4e58f335e..4a7dbe532 100644 --- a/test/statsCases/aggressive-splitting-entry/webpack.config.js +++ b/test/statsCases/aggressive-splitting-entry/webpack.config.js @@ -16,18 +16,11 @@ module.exports = { recordsInputPath: __dirname + "/input-records.json", //recordsOutputPath: __dirname + "/records.json", stats: { - reasons: false, + chunks: true, chunkModules: true, chunkOrigins: true, entrypoints: true, modules: false, - cached: true, - cachedAssets: true, - source: true, - errorDetails: true, - publicPath: true, - excludeModules: [ - /e\.js/ - ] + publicPath: true } }; diff --git a/test/statsCases/aggressive-splitting-on-demand/expected.txt b/test/statsCases/aggressive-splitting-on-demand/expected.txt index 288330f7a..c37ff156d 100644 --- a/test/statsCases/aggressive-splitting-on-demand/expected.txt +++ b/test/statsCases/aggressive-splitting-on-demand/expected.txt @@ -1,4 +1,4 @@ -Hash: 57bbddba5221b9ac4a33 +Hash: 3605a628ea012f7d12ca Time: Xms Asset Size Chunks Chunk Names fc930a2adf8206ea2dc5.js 1.94 kB 0 [emitted] @@ -6,10 +6,10 @@ cd45585186d59208602b.js 1.96 kB 1 [emitted] 6b94c231e016c5aaccdb.js 1.94 kB 2 [emitted] fd0985cee894c4f3f1a6.js 1.94 kB 3 [emitted] d9fc46873c8ea924b895.js 979 bytes 4 [emitted] -beecea47f9a8ded3c298.js 7.63 kB 6 [emitted] main +a773fee259e5a284dea9.js 7.47 kB 6 [emitted] main b08c507d4e1e05cbab45.js 985 bytes 9 [emitted] 5d50e858fe6e559aa47c.js 977 bytes 11 [emitted] -Entrypoint main = beecea47f9a8ded3c298.js +Entrypoint main = a773fee259e5a284dea9.js chunk {0} fc930a2adf8206ea2dc5.js 1.8 kB {6} > aggressive-splitted duplicate [9] (webpack)/test/statsCases/aggressive-splitting-on-demand/index.js 4:0-51 > aggressive-splitted duplicate [9] (webpack)/test/statsCases/aggressive-splitting-on-demand/index.js 5:0-44 @@ -36,7 +36,7 @@ chunk {4} d9fc46873c8ea924b895.js 899 bytes {6} > aggressive-splitted duplicate [9] (webpack)/test/statsCases/aggressive-splitting-on-demand/index.js 2:0-23 > aggressive-splitted duplicate [9] (webpack)/test/statsCases/aggressive-splitting-on-demand/index.js 3:0-30 [2] (webpack)/test/statsCases/aggressive-splitting-on-demand/c.js 899 bytes {4} [built] -chunk {6} beecea47f9a8ded3c298.js (main) 248 bytes [entry] +chunk {6} a773fee259e5a284dea9.js (main) 248 bytes [entry] > main [9] (webpack)/test/statsCases/aggressive-splitting-on-demand/index.js [9] (webpack)/test/statsCases/aggressive-splitting-on-demand/index.js 248 bytes {6} [built] chunk {9} b08c507d4e1e05cbab45.js 899 bytes {6} diff --git a/test/statsCases/aggressive-splitting-on-demand/webpack.config.js b/test/statsCases/aggressive-splitting-on-demand/webpack.config.js index 4e58f335e..4a7dbe532 100644 --- a/test/statsCases/aggressive-splitting-on-demand/webpack.config.js +++ b/test/statsCases/aggressive-splitting-on-demand/webpack.config.js @@ -16,18 +16,11 @@ module.exports = { recordsInputPath: __dirname + "/input-records.json", //recordsOutputPath: __dirname + "/records.json", stats: { - reasons: false, + chunks: true, chunkModules: true, chunkOrigins: true, entrypoints: true, modules: false, - cached: true, - cachedAssets: true, - source: true, - errorDetails: true, - publicPath: true, - excludeModules: [ - /e\.js/ - ] + publicPath: true } }; diff --git a/test/statsCases/chunks/expected.txt b/test/statsCases/chunks/expected.txt index cc1a6fbde..4d539f6d9 100644 --- a/test/statsCases/chunks/expected.txt +++ b/test/statsCases/chunks/expected.txt @@ -1,49 +1,32 @@ -Hash: 6ab76347dbbefb99c3c5 +Hash: 458904e7e19c8ce28066 Time: Xms Asset Size Chunks Chunk Names 0.bundle.js 238 bytes 0 [emitted] -1.bundle.js 108 bytes 1 [emitted] -2.bundle.js 204 bytes 2 [emitted] - bundle.js 6.27 kB 3 [emitted] main +1.bundle.js 102 bytes 1 [emitted] +2.bundle.js 182 bytes 2 [emitted] + bundle.js 6.1 kB 3 [emitted] main chunk {0} 0.bundle.js 54 bytes {3} [rendered] - > [5] (webpack)/test/statsCases/chunks/index.js 3:0-16 - [2] (webpack)/test/statsCases/chunks/c.js 54 bytes {0} [built] - amd require ./c [5] (webpack)/test/statsCases/chunks/index.js 3:0-16 + > [0] (webpack)/test/statsCases/chunks/index.js 3:0-16 + [3] (webpack)/test/statsCases/chunks/c.js 54 bytes {0} [built] + amd require ./c [0] (webpack)/test/statsCases/chunks/index.js 3:0-16 [] -> factory:Xms building:Xms = Xms chunk {1} 1.bundle.js 22 bytes {3} [rendered] - > [5] (webpack)/test/statsCases/chunks/index.js 2:0-16 - [1] (webpack)/test/statsCases/chunks/b.js 22 bytes {1} [built] - amd require ./b [5] (webpack)/test/statsCases/chunks/index.js 2:0-16 + > [0] (webpack)/test/statsCases/chunks/index.js 2:0-16 + [2] (webpack)/test/statsCases/chunks/b.js 22 bytes {1} [built] + amd require ./b [0] (webpack)/test/statsCases/chunks/index.js 2:0-16 [] -> factory:Xms building:Xms = Xms chunk {2} 2.bundle.js 44 bytes {0} [rendered] - > [2] (webpack)/test/statsCases/chunks/c.js 1:0-52 - [3] (webpack)/test/statsCases/chunks/d.js 22 bytes {2} [built] - require.ensure item ./d [2] (webpack)/test/statsCases/chunks/c.js 1:0-52 + > [3] (webpack)/test/statsCases/chunks/c.js 1:0-52 + [4] (webpack)/test/statsCases/chunks/d.js 22 bytes {2} [built] + require.ensure item ./d [3] (webpack)/test/statsCases/chunks/c.js 1:0-52 [] -> factory:Xms building:Xms = Xms - [4] (webpack)/test/statsCases/chunks/e.js 22 bytes {2} [built] - require.ensure item ./e [2] (webpack)/test/statsCases/chunks/c.js 1:0-52 + [5] (webpack)/test/statsCases/chunks/e.js 22 bytes {2} [built] + require.ensure item ./e [3] (webpack)/test/statsCases/chunks/c.js 1:0-52 [] -> factory:Xms building:Xms = Xms chunk {3} bundle.js (main) 73 bytes [entry] [rendered] - > main [5] (webpack)/test/statsCases/chunks/index.js - [0] (webpack)/test/statsCases/chunks/a.js 22 bytes {3} [built] - cjs require ./a [5] (webpack)/test/statsCases/chunks/index.js 1:0-14 - [] -> factory:Xms building:Xms = Xms - [5] (webpack)/test/statsCases/chunks/index.js 51 bytes {3} [built] + > main [0] (webpack)/test/statsCases/chunks/index.js + [0] (webpack)/test/statsCases/chunks/index.js 51 bytes {3} [built] factory:Xms building:Xms = Xms - [0] (webpack)/test/statsCases/chunks/a.js 22 bytes {3} [built] - cjs require ./a [5] (webpack)/test/statsCases/chunks/index.js 1:0-14 - [] -> factory:Xms building:Xms = Xms - [1] (webpack)/test/statsCases/chunks/b.js 22 bytes {1} [built] - amd require ./b [5] (webpack)/test/statsCases/chunks/index.js 2:0-16 - [] -> factory:Xms building:Xms = Xms - [2] (webpack)/test/statsCases/chunks/c.js 54 bytes {0} [built] - amd require ./c [5] (webpack)/test/statsCases/chunks/index.js 3:0-16 - [] -> factory:Xms building:Xms = Xms - [3] (webpack)/test/statsCases/chunks/d.js 22 bytes {2} [built] - require.ensure item ./d [2] (webpack)/test/statsCases/chunks/c.js 1:0-52 - [] -> factory:Xms building:Xms = Xms - [4] (webpack)/test/statsCases/chunks/e.js 22 bytes {2} [built] - require.ensure item ./e [2] (webpack)/test/statsCases/chunks/c.js 1:0-52 - [] -> factory:Xms building:Xms = Xms - [5] (webpack)/test/statsCases/chunks/index.js 51 bytes {3} [built] - factory:Xms building:Xms = Xms \ No newline at end of file + [1] (webpack)/test/statsCases/chunks/a.js 22 bytes {3} [built] + cjs require ./a [0] (webpack)/test/statsCases/chunks/index.js 1:0-14 + [] -> factory:Xms building:Xms = Xms \ No newline at end of file diff --git a/test/statsCases/chunks/webpack.config.js b/test/statsCases/chunks/webpack.config.js index 78a5b433e..ac4b79411 100644 --- a/test/statsCases/chunks/webpack.config.js +++ b/test/statsCases/chunks/webpack.config.js @@ -6,16 +6,10 @@ module.exports = { profile: true, stats: { reasons: true, + chunks: true, chunkModules: true, chunkOrigins: true, - modules: true, - cached: true, - cachedAssets: true, - source: true, - errorDetails: true, - publicPath: true, - excludeModules: [ - /e\.js/ - ] + modules: false, + publicPath: true } }; diff --git a/test/statsCases/color-disabled/expected.txt b/test/statsCases/color-disabled/expected.txt index 89a004014..9e18644ea 100644 --- a/test/statsCases/color-disabled/expected.txt +++ b/test/statsCases/color-disabled/expected.txt @@ -1,6 +1,5 @@ Hash: 6c781fe6bf412ba6435b Time: Xms Asset Size Chunks Chunk Names -main.js 2.63 kB 0 [emitted] main -chunk {0} main.js (main) 0 bytes [entry] [rendered] - [0] (webpack)/test/statsCases/color-disabled/index.js 0 bytes {0} [built] \ No newline at end of file +main.js 2.47 kB 0 [emitted] main + [0] (webpack)/test/statsCases/color-disabled/index.js 0 bytes {0} [built] \ No newline at end of file diff --git a/test/statsCases/color-enabled-custom/expected.txt b/test/statsCases/color-enabled-custom/expected.txt index e75eca438..f14fd735e 100644 --- a/test/statsCases/color-enabled-custom/expected.txt +++ b/test/statsCases/color-enabled-custom/expected.txt @@ -1,6 +1,5 @@ Hash: 6c781fe6bf412ba6435b Time: Xms Asset Size Chunks Chunk Names -main.js 2.63 kB 0 [emitted] main -chunk {0} main.js (main) 0 bytes [entry] [rendered] - [0] (webpack)/test/statsCases/color-enabled-custom/index.js 0 bytes {0} [built] \ No newline at end of file +main.js 2.47 kB 0 [emitted] main + [0] (webpack)/test/statsCases/color-enabled-custom/index.js 0 bytes {0} [built] \ No newline at end of file diff --git a/test/statsCases/color-enabled/expected.txt b/test/statsCases/color-enabled/expected.txt index 3873582f1..a9ee8d254 100644 --- a/test/statsCases/color-enabled/expected.txt +++ b/test/statsCases/color-enabled/expected.txt @@ -1,6 +1,5 @@ Hash: 6c781fe6bf412ba6435b Time: Xms Asset Size Chunks Chunk Names -main.js 2.63 kB 0 [emitted] main -chunk {0} main.js (main) 0 bytes [entry] [rendered] - [0] (webpack)/test/statsCases/color-enabled/index.js 0 bytes {0} [built] \ No newline at end of file +main.js 2.47 kB 0 [emitted] main + [0] (webpack)/test/statsCases/color-enabled/index.js 0 bytes {0} [built] \ No newline at end of file diff --git a/test/statsCases/commons-chunk-min-size-0/expected.txt b/test/statsCases/commons-chunk-min-size-0/expected.txt index a5025646b..0673e9ea2 100644 --- a/test/statsCases/commons-chunk-min-size-0/expected.txt +++ b/test/statsCases/commons-chunk-min-size-0/expected.txt @@ -2,14 +2,12 @@ Hash: dc6038bec87a57d1a45e Time: Xms Asset Size Chunks Chunk Names entry-1.js 25 bytes 0 [emitted] entry-1 -vendor-1.js 6.93 kB 1 [emitted] vendor-1 -chunk {0} entry-1.js (entry-1) 0 bytes {1} [initial] [rendered] -chunk {1} vendor-1.js (vendor-1) 329 bytes [entry] [rendered] - [0] (webpack)/test/statsCases/commons-chunk-min-size-0/modules/a.js 22 bytes {1} [built] - [1] (webpack)/test/statsCases/commons-chunk-min-size-0/modules/b.js 22 bytes {1} [built] - [2] (webpack)/test/statsCases/commons-chunk-min-size-0/modules/c.js 22 bytes {1} [built] - [3] (webpack)/test/statsCases/commons-chunk-min-size-0/modules/d.js 22 bytes {1} [built] - [4] (webpack)/test/statsCases/commons-chunk-min-size-0/modules/e.js 22 bytes {1} [built] - [5] (webpack)/test/statsCases/commons-chunk-min-size-0/modules/f.js 22 bytes {1} [built] - [6] multi ./modules/a ./modules/b ./modules/c 52 bytes {1} [built] - [7] (webpack)/test/statsCases/commons-chunk-min-size-0/entry-1.js 145 bytes {1} [built] \ No newline at end of file +vendor-1.js 6.76 kB 1 [emitted] vendor-1 + [0] (webpack)/test/statsCases/commons-chunk-min-size-0/modules/a.js 22 bytes {1} [built] + [1] (webpack)/test/statsCases/commons-chunk-min-size-0/modules/b.js 22 bytes {1} [built] + [2] (webpack)/test/statsCases/commons-chunk-min-size-0/modules/c.js 22 bytes {1} [built] + [3] (webpack)/test/statsCases/commons-chunk-min-size-0/modules/d.js 22 bytes {1} [built] + [4] (webpack)/test/statsCases/commons-chunk-min-size-0/modules/e.js 22 bytes {1} [built] + [5] (webpack)/test/statsCases/commons-chunk-min-size-0/modules/f.js 22 bytes {1} [built] + [6] multi ./modules/a ./modules/b ./modules/c 52 bytes {1} [built] + [7] (webpack)/test/statsCases/commons-chunk-min-size-0/entry-1.js 145 bytes {1} [built] \ No newline at end of file diff --git a/test/statsCases/commons-chunk-min-size-Infinity/expected.txt b/test/statsCases/commons-chunk-min-size-Infinity/expected.txt index 7fc0b94b5..604973f76 100644 --- a/test/statsCases/commons-chunk-min-size-Infinity/expected.txt +++ b/test/statsCases/commons-chunk-min-size-Infinity/expected.txt @@ -1,18 +1,13 @@ Hash: 9c0d5be5c7febb314e7a Time: Xms Asset Size Chunks Chunk Names - entry-1.js 3.27 kB 0 [emitted] entry-1 -vendor-1.js 3.02 kB 1 [emitted] vendor-1 -chunk {0} entry-1.js (entry-1) 277 bytes [entry] [rendered] - [0] (webpack)/test/statsCases/commons-chunk-min-size-Infinity/modules/a.js 22 bytes {0} {1} [built] - [1] (webpack)/test/statsCases/commons-chunk-min-size-Infinity/modules/b.js 22 bytes {0} {1} [built] - [2] (webpack)/test/statsCases/commons-chunk-min-size-Infinity/modules/c.js 22 bytes {0} {1} [built] - [3] (webpack)/test/statsCases/commons-chunk-min-size-Infinity/entry-1.js 145 bytes {0} [built] - [4] (webpack)/test/statsCases/commons-chunk-min-size-Infinity/modules/d.js 22 bytes {0} [built] - [5] (webpack)/test/statsCases/commons-chunk-min-size-Infinity/modules/e.js 22 bytes {0} [built] - [6] (webpack)/test/statsCases/commons-chunk-min-size-Infinity/modules/f.js 22 bytes {0} [built] -chunk {1} vendor-1.js (vendor-1) 118 bytes [entry] [rendered] - [0] (webpack)/test/statsCases/commons-chunk-min-size-Infinity/modules/a.js 22 bytes {0} {1} [built] - [1] (webpack)/test/statsCases/commons-chunk-min-size-Infinity/modules/b.js 22 bytes {0} {1} [built] - [2] (webpack)/test/statsCases/commons-chunk-min-size-Infinity/modules/c.js 22 bytes {0} {1} [built] - [7] multi ./modules/a ./modules/b ./modules/c 52 bytes {1} [built] \ No newline at end of file + entry-1.js 3.11 kB 0 [emitted] entry-1 +vendor-1.js 2.85 kB 1 [emitted] vendor-1 + [0] (webpack)/test/statsCases/commons-chunk-min-size-Infinity/modules/a.js 22 bytes {0} {1} [built] + [1] (webpack)/test/statsCases/commons-chunk-min-size-Infinity/modules/b.js 22 bytes {0} {1} [built] + [2] (webpack)/test/statsCases/commons-chunk-min-size-Infinity/modules/c.js 22 bytes {0} {1} [built] + [3] (webpack)/test/statsCases/commons-chunk-min-size-Infinity/entry-1.js 145 bytes {0} [built] + [4] (webpack)/test/statsCases/commons-chunk-min-size-Infinity/modules/d.js 22 bytes {0} [built] + [5] (webpack)/test/statsCases/commons-chunk-min-size-Infinity/modules/e.js 22 bytes {0} [built] + [6] (webpack)/test/statsCases/commons-chunk-min-size-Infinity/modules/f.js 22 bytes {0} [built] + [7] multi ./modules/a ./modules/b ./modules/c 52 bytes {1} [built] \ No newline at end of file diff --git a/test/statsCases/commons-plugin-issue-4980/expected.txt b/test/statsCases/commons-plugin-issue-4980/expected.txt index 5ff459a5a..36d2ebbe8 100644 --- a/test/statsCases/commons-plugin-issue-4980/expected.txt +++ b/test/statsCases/commons-plugin-issue-4980/expected.txt @@ -5,25 +5,19 @@ Child Asset Size Chunks Chunk Names app.js 1.27 kB 0 [emitted] app vendor.bd2b4219dfda1a951495.js 443 bytes 1 [emitted] vendor - runtime.js 5.94 kB 2 [emitted] runtime - chunk {0} app.js (app) 185 bytes {1} [initial] [rendered] - [./entry-1.js] (webpack)/test/statsCases/commons-plugin-issue-4980/entry-1.js 67 bytes {0} [built] - [./submodule-a.js] (webpack)/test/statsCases/commons-plugin-issue-4980/submodule-a.js 59 bytes {0} [built] - [./submodule-b.js] (webpack)/test/statsCases/commons-plugin-issue-4980/submodule-b.js 59 bytes {0} [built] - chunk {1} vendor.bd2b4219dfda1a951495.js (vendor) 87 bytes {2} [initial] [rendered] - [./constants.js] (webpack)/test/statsCases/commons-plugin-issue-4980/constants.js 87 bytes {1} [built] - chunk {2} runtime.js (runtime) 0 bytes [entry] [rendered] + runtime.js 5.78 kB 2 [emitted] runtime + [./constants.js] (webpack)/test/statsCases/commons-plugin-issue-4980/constants.js 87 bytes {1} [built] + [./entry-1.js] (webpack)/test/statsCases/commons-plugin-issue-4980/entry-1.js 67 bytes {0} [built] + [./submodule-a.js] (webpack)/test/statsCases/commons-plugin-issue-4980/submodule-a.js 59 bytes {0} [built] + [./submodule-b.js] (webpack)/test/statsCases/commons-plugin-issue-4980/submodule-b.js 59 bytes {0} [built] Child Hash: 2897fe6052020598632c Time: Xms Asset Size Chunks Chunk Names app.js 1.32 kB 0 [emitted] app vendor.bd2b4219dfda1a951495.js 443 bytes 1 [emitted] vendor - runtime.js 5.94 kB 2 [emitted] runtime - chunk {0} app.js (app) 192 bytes {1} [initial] [rendered] - [./entry-2.js] (webpack)/test/statsCases/commons-plugin-issue-4980/entry-2.js 67 bytes {0} [built] - [./submodule-a.js] (webpack)/test/statsCases/commons-plugin-issue-4980/submodule-a.js 59 bytes {0} [built] - [./submodule-c.js] (webpack)/test/statsCases/commons-plugin-issue-4980/submodule-c.js 66 bytes {0} [built] - chunk {1} vendor.bd2b4219dfda1a951495.js (vendor) 87 bytes {2} [initial] [rendered] - [./constants.js] (webpack)/test/statsCases/commons-plugin-issue-4980/constants.js 87 bytes {1} [built] - chunk {2} runtime.js (runtime) 0 bytes [entry] [rendered] \ No newline at end of file + runtime.js 5.78 kB 2 [emitted] runtime + [./constants.js] (webpack)/test/statsCases/commons-plugin-issue-4980/constants.js 87 bytes {1} [built] + [./entry-2.js] (webpack)/test/statsCases/commons-plugin-issue-4980/entry-2.js 67 bytes {0} [built] + [./submodule-a.js] (webpack)/test/statsCases/commons-plugin-issue-4980/submodule-a.js 59 bytes {0} [built] + [./submodule-c.js] (webpack)/test/statsCases/commons-plugin-issue-4980/submodule-c.js 66 bytes {0} [built] \ No newline at end of file diff --git a/test/statsCases/define-plugin/expected.txt b/test/statsCases/define-plugin/expected.txt index d208e1168..bc25d5d7a 100644 --- a/test/statsCases/define-plugin/expected.txt +++ b/test/statsCases/define-plugin/expected.txt @@ -3,13 +3,11 @@ Child Hash: 052d0451a89cb963e4d3 Time: Xms Asset Size Chunks Chunk Names - main.js 2.68 kB 0 [emitted] main - chunk {0} main.js (main) 24 bytes [entry] [rendered] - [0] (webpack)/test/statsCases/define-plugin/index.js 24 bytes {0} [built] + main.js 2.52 kB 0 [emitted] main + [0] (webpack)/test/statsCases/define-plugin/index.js 24 bytes {0} [built] Child Hash: eb3ff8e5a88b9234d04f Time: Xms Asset Size Chunks Chunk Names - main.js 2.68 kB 0 [emitted] main - chunk {0} main.js (main) 24 bytes [entry] [rendered] - [0] (webpack)/test/statsCases/define-plugin/index.js 24 bytes {0} [built] \ No newline at end of file + main.js 2.52 kB 0 [emitted] main + [0] (webpack)/test/statsCases/define-plugin/index.js 24 bytes {0} [built] \ No newline at end of file diff --git a/test/statsCases/exclude-with-loader/expected.txt b/test/statsCases/exclude-with-loader/expected.txt index af7ff0f8d..b7e8b830f 100644 --- a/test/statsCases/exclude-with-loader/expected.txt +++ b/test/statsCases/exclude-with-loader/expected.txt @@ -1,8 +1,7 @@ -Hash: 7ab067a6a9fc61623ae0 +Hash: 9a949e8727d0583cb1c4 Time: Xms - Asset Size Chunks Chunk Names -bundle.js 2.9 kB 0 [emitted] main -chunk {0} bundle.js (main) 132 bytes [entry] [rendered] - [0] (webpack)/test/statsCases/exclude-with-loader/a.txt 43 bytes {0} [built] - [2] (webpack)/test/statsCases/exclude-with-loader/index.js 46 bytes {0} [built] - + 1 hidden modules \ No newline at end of file + Asset Size Chunks Chunk Names +bundle.js 2.74 kB 0 [emitted] main + [0] (webpack)/test/statsCases/exclude-with-loader/index.js 46 bytes {0} [built] + [1] (webpack)/test/statsCases/exclude-with-loader/a.txt 43 bytes {0} [built] + + 1 hidden module \ No newline at end of file diff --git a/test/statsCases/external/expected.txt b/test/statsCases/external/expected.txt index 18706b3f9..155880576 100644 --- a/test/statsCases/external/expected.txt +++ b/test/statsCases/external/expected.txt @@ -1,7 +1,6 @@ Hash: 86950abf8dcf924d9cc1 Time: Xms Asset Size Chunks Chunk Names -main.js 2.77 kB 0 [emitted] main -chunk {0} main.js (main) 59 bytes [entry] [rendered] - [0] (webpack)/test/statsCases/external/index.js 17 bytes {0} [built] - [1] external "test" 42 bytes {0} [not cacheable] \ No newline at end of file +main.js 2.61 kB 0 [emitted] main + [0] (webpack)/test/statsCases/external/index.js 17 bytes {0} [built] + [1] external "test" 42 bytes {0} [not cacheable] \ No newline at end of file diff --git a/test/statsCases/filter-warnings/expected.txt b/test/statsCases/filter-warnings/expected.txt index f51c93065..37608dea4 100644 --- a/test/statsCases/filter-warnings/expected.txt +++ b/test/statsCases/filter-warnings/expected.txt @@ -1,170 +1,157 @@ -Hash: e4d2b189bb205589ee1ee4d2b189bb205589ee1ee4d2b189bb205589ee1ee4d2b189bb205589ee1ee4d2b189bb205589ee1ee4d2b189bb205589ee1ee4d2b189bb205589ee1ee4d2b189bb205589ee1ee4d2b189bb205589ee1ee4d2b189bb205589ee1ee4d2b189bb205589ee1ee4d2b189bb205589ee1ee4d2b189bb205589ee1e +Hash: 3cc7bf529a74b021bee53cc7bf529a74b021bee53cc7bf529a74b021bee53cc7bf529a74b021bee53cc7bf529a74b021bee53cc7bf529a74b021bee53cc7bf529a74b021bee53cc7bf529a74b021bee53cc7bf529a74b021bee53cc7bf529a74b021bee53cc7bf529a74b021bee53cc7bf529a74b021bee53cc7bf529a74b021bee5 Child - Hash: e4d2b189bb205589ee1e + Hash: 3cc7bf529a74b021bee5 Time: Xms - Asset Size Chunks Chunk Names - bundle.js 2.17 kB 0 [emitted] main - chunk {0} bundle.js (main) 1.04 kB [entry] [rendered] + Asset Size Chunks Chunk Names + bundle.js 2.1 kB 0 [emitted] main WARNING in bundle.js from UglifyJs - Dropping unused function someRemoteUnUsedFunction1 [./a.js:3,0] - Dropping unused function someRemoteUnUsedFunction2 [./a.js:4,0] - Dropping unused function someRemoteUnUsedFunction3 [./a.js:5,0] - Dropping unused function someRemoteUnUsedFunction4 [./a.js:6,0] - Dropping unused function someRemoteUnUsedFunction5 [./a.js:7,0] Dropping side-effect-free statement [./index.js:6,0] Dropping unused function someUnUsedFunction1 [./index.js:8,0] Dropping unused function someUnUsedFunction2 [./index.js:9,0] Dropping unused function someUnUsedFunction3 [./index.js:10,0] Dropping unused function someUnUsedFunction4 [./index.js:11,0] Dropping unused function someUnUsedFunction5 [./index.js:12,0] -Child - Hash: e4d2b189bb205589ee1e - Time: Xms - Asset Size Chunks Chunk Names - bundle.js 2.17 kB 0 [emitted] main - chunk {0} bundle.js (main) 1.04 kB [entry] [rendered] -Child - Hash: e4d2b189bb205589ee1e - Time: Xms - Asset Size Chunks Chunk Names - bundle.js 2.17 kB 0 [emitted] main - chunk {0} bundle.js (main) 1.04 kB [entry] [rendered] -Child - Hash: e4d2b189bb205589ee1e - Time: Xms - Asset Size Chunks Chunk Names - bundle.js 2.17 kB 0 [emitted] main - chunk {0} bundle.js (main) 1.04 kB [entry] [rendered] -Child - Hash: e4d2b189bb205589ee1e - Time: Xms - Asset Size Chunks Chunk Names - bundle.js 2.17 kB 0 [emitted] main - chunk {0} bundle.js (main) 1.04 kB [entry] [rendered] -Child - Hash: e4d2b189bb205589ee1e - Time: Xms - Asset Size Chunks Chunk Names - bundle.js 2.17 kB 0 [emitted] main - chunk {0} bundle.js (main) 1.04 kB [entry] [rendered] -Child - Hash: e4d2b189bb205589ee1e - Time: Xms - Asset Size Chunks Chunk Names - bundle.js 2.17 kB 0 [emitted] main - chunk {0} bundle.js (main) 1.04 kB [entry] [rendered] -Child - Hash: e4d2b189bb205589ee1e - Time: Xms - Asset Size Chunks Chunk Names - bundle.js 2.17 kB 0 [emitted] main - chunk {0} bundle.js (main) 1.04 kB [entry] [rendered] - - WARNING in bundle.js from UglifyJs Dropping unused function someRemoteUnUsedFunction1 [./a.js:3,0] Dropping unused function someRemoteUnUsedFunction2 [./a.js:4,0] Dropping unused function someRemoteUnUsedFunction3 [./a.js:5,0] Dropping unused function someRemoteUnUsedFunction4 [./a.js:6,0] Dropping unused function someRemoteUnUsedFunction5 [./a.js:7,0] +Child + Hash: 3cc7bf529a74b021bee5 + Time: Xms + Asset Size Chunks Chunk Names + bundle.js 2.1 kB 0 [emitted] main +Child + Hash: 3cc7bf529a74b021bee5 + Time: Xms + Asset Size Chunks Chunk Names + bundle.js 2.1 kB 0 [emitted] main +Child + Hash: 3cc7bf529a74b021bee5 + Time: Xms + Asset Size Chunks Chunk Names + bundle.js 2.1 kB 0 [emitted] main +Child + Hash: 3cc7bf529a74b021bee5 + Time: Xms + Asset Size Chunks Chunk Names + bundle.js 2.1 kB 0 [emitted] main +Child + Hash: 3cc7bf529a74b021bee5 + Time: Xms + Asset Size Chunks Chunk Names + bundle.js 2.1 kB 0 [emitted] main +Child + Hash: 3cc7bf529a74b021bee5 + Time: Xms + Asset Size Chunks Chunk Names + bundle.js 2.1 kB 0 [emitted] main +Child + Hash: 3cc7bf529a74b021bee5 + Time: Xms + Asset Size Chunks Chunk Names + bundle.js 2.1 kB 0 [emitted] main + + WARNING in bundle.js from UglifyJs Dropping side-effect-free statement [./index.js:6,0] Dropping unused function someUnUsedFunction1 [./index.js:8,0] Dropping unused function someUnUsedFunction2 [./index.js:9,0] Dropping unused function someUnUsedFunction3 [./index.js:10,0] Dropping unused function someUnUsedFunction4 [./index.js:11,0] Dropping unused function someUnUsedFunction5 [./index.js:12,0] -Child - Hash: e4d2b189bb205589ee1e - Time: Xms - Asset Size Chunks Chunk Names - bundle.js 2.17 kB 0 [emitted] main - chunk {0} bundle.js (main) 1.04 kB [entry] [rendered] - - WARNING in bundle.js from UglifyJs Dropping unused function someRemoteUnUsedFunction1 [./a.js:3,0] Dropping unused function someRemoteUnUsedFunction2 [./a.js:4,0] Dropping unused function someRemoteUnUsedFunction3 [./a.js:5,0] Dropping unused function someRemoteUnUsedFunction4 [./a.js:6,0] Dropping unused function someRemoteUnUsedFunction5 [./a.js:7,0] +Child + Hash: 3cc7bf529a74b021bee5 + Time: Xms + Asset Size Chunks Chunk Names + bundle.js 2.1 kB 0 [emitted] main + + WARNING in bundle.js from UglifyJs Dropping side-effect-free statement [./index.js:6,0] Dropping unused function someUnUsedFunction1 [./index.js:8,0] Dropping unused function someUnUsedFunction2 [./index.js:9,0] Dropping unused function someUnUsedFunction3 [./index.js:10,0] Dropping unused function someUnUsedFunction4 [./index.js:11,0] Dropping unused function someUnUsedFunction5 [./index.js:12,0] -Child - Hash: e4d2b189bb205589ee1e - Time: Xms - Asset Size Chunks Chunk Names - bundle.js 2.17 kB 0 [emitted] main - chunk {0} bundle.js (main) 1.04 kB [entry] [rendered] - - WARNING in bundle.js from UglifyJs Dropping unused function someRemoteUnUsedFunction1 [./a.js:3,0] Dropping unused function someRemoteUnUsedFunction2 [./a.js:4,0] Dropping unused function someRemoteUnUsedFunction3 [./a.js:5,0] Dropping unused function someRemoteUnUsedFunction4 [./a.js:6,0] Dropping unused function someRemoteUnUsedFunction5 [./a.js:7,0] +Child + Hash: 3cc7bf529a74b021bee5 + Time: Xms + Asset Size Chunks Chunk Names + bundle.js 2.1 kB 0 [emitted] main + + WARNING in bundle.js from UglifyJs Dropping side-effect-free statement [./index.js:6,0] Dropping unused function someUnUsedFunction1 [./index.js:8,0] Dropping unused function someUnUsedFunction2 [./index.js:9,0] Dropping unused function someUnUsedFunction3 [./index.js:10,0] Dropping unused function someUnUsedFunction4 [./index.js:11,0] Dropping unused function someUnUsedFunction5 [./index.js:12,0] -Child - Hash: e4d2b189bb205589ee1e - Time: Xms - Asset Size Chunks Chunk Names - bundle.js 2.17 kB 0 [emitted] main - chunk {0} bundle.js (main) 1.04 kB [entry] [rendered] - - WARNING in bundle.js from UglifyJs Dropping unused function someRemoteUnUsedFunction1 [./a.js:3,0] Dropping unused function someRemoteUnUsedFunction2 [./a.js:4,0] Dropping unused function someRemoteUnUsedFunction3 [./a.js:5,0] Dropping unused function someRemoteUnUsedFunction4 [./a.js:6,0] Dropping unused function someRemoteUnUsedFunction5 [./a.js:7,0] +Child + Hash: 3cc7bf529a74b021bee5 + Time: Xms + Asset Size Chunks Chunk Names + bundle.js 2.1 kB 0 [emitted] main + + WARNING in bundle.js from UglifyJs Dropping side-effect-free statement [./index.js:6,0] Dropping unused function someUnUsedFunction1 [./index.js:8,0] Dropping unused function someUnUsedFunction2 [./index.js:9,0] Dropping unused function someUnUsedFunction3 [./index.js:10,0] Dropping unused function someUnUsedFunction4 [./index.js:11,0] Dropping unused function someUnUsedFunction5 [./index.js:12,0] -Child - Hash: e4d2b189bb205589ee1e - Time: Xms - Asset Size Chunks Chunk Names - bundle.js 2.17 kB 0 [emitted] main - chunk {0} bundle.js (main) 1.04 kB [entry] [rendered] - - WARNING in bundle.js from UglifyJs Dropping unused function someRemoteUnUsedFunction1 [./a.js:3,0] Dropping unused function someRemoteUnUsedFunction2 [./a.js:4,0] Dropping unused function someRemoteUnUsedFunction3 [./a.js:5,0] Dropping unused function someRemoteUnUsedFunction4 [./a.js:6,0] Dropping unused function someRemoteUnUsedFunction5 [./a.js:7,0] +Child + Hash: 3cc7bf529a74b021bee5 + Time: Xms + Asset Size Chunks Chunk Names + bundle.js 2.1 kB 0 [emitted] main + + WARNING in bundle.js from UglifyJs Dropping side-effect-free statement [./index.js:6,0] Dropping unused function someUnUsedFunction1 [./index.js:8,0] Dropping unused function someUnUsedFunction2 [./index.js:9,0] Dropping unused function someUnUsedFunction3 [./index.js:10,0] Dropping unused function someUnUsedFunction4 [./index.js:11,0] Dropping unused function someUnUsedFunction5 [./index.js:12,0] -Child - Hash: e4d2b189bb205589ee1e - Time: Xms - Asset Size Chunks Chunk Names - bundle.js 2.17 kB 0 [emitted] main - chunk {0} bundle.js (main) 1.04 kB [entry] [rendered] - - WARNING in bundle.js from UglifyJs Dropping unused function someRemoteUnUsedFunction1 [./a.js:3,0] Dropping unused function someRemoteUnUsedFunction2 [./a.js:4,0] Dropping unused function someRemoteUnUsedFunction3 [./a.js:5,0] Dropping unused function someRemoteUnUsedFunction4 [./a.js:6,0] Dropping unused function someRemoteUnUsedFunction5 [./a.js:7,0] +Child + Hash: 3cc7bf529a74b021bee5 + Time: Xms + Asset Size Chunks Chunk Names + bundle.js 2.1 kB 0 [emitted] main + + WARNING in bundle.js from UglifyJs Dropping side-effect-free statement [./index.js:6,0] Dropping unused function someUnUsedFunction1 [./index.js:8,0] Dropping unused function someUnUsedFunction2 [./index.js:9,0] Dropping unused function someUnUsedFunction3 [./index.js:10,0] Dropping unused function someUnUsedFunction4 [./index.js:11,0] - Dropping unused function someUnUsedFunction5 [./index.js:12,0] \ No newline at end of file + Dropping unused function someUnUsedFunction5 [./index.js:12,0] + Dropping unused function someRemoteUnUsedFunction1 [./a.js:3,0] + Dropping unused function someRemoteUnUsedFunction2 [./a.js:4,0] + Dropping unused function someRemoteUnUsedFunction3 [./a.js:5,0] + Dropping unused function someRemoteUnUsedFunction4 [./a.js:6,0] + Dropping unused function someRemoteUnUsedFunction5 [./a.js:7,0] \ No newline at end of file diff --git a/test/statsCases/limit-chunk-count-plugin/expected.txt b/test/statsCases/limit-chunk-count-plugin/expected.txt index d3349caff..e020942cc 100644 --- a/test/statsCases/limit-chunk-count-plugin/expected.txt +++ b/test/statsCases/limit-chunk-count-plugin/expected.txt @@ -1,61 +1,61 @@ -Hash: 7785ad0c3d45a94a3238a8178dd1adacd47a6b70043f3d1f8be496acf7a6e0df24380874d11a123a +Hash: e0c3e190f6cf11c37f15b34fa5f72acbbc9cbd9a404c277a8869b8a6a62e5c32ec6fc2ff40a3b587 Child - Hash: 7785ad0c3d45a94a3238 + Hash: e0c3e190f6cf11c37f15 Time: Xms - Asset Size Chunks Chunk Names - bundle.js 3.56 kB 0 [emitted] main + Asset Size Chunks Chunk Names + bundle.js 3.4 kB 0 [emitted] main chunk {0} bundle.js (main) 191 bytes [entry] [rendered] - [0] (webpack)/test/statsCases/limit-chunk-count-plugin/a.js 22 bytes {0} [built] - [1] (webpack)/test/statsCases/limit-chunk-count-plugin/b.js 22 bytes {0} [built] - [2] (webpack)/test/statsCases/limit-chunk-count-plugin/c.js 30 bytes {0} [built] - [3] (webpack)/test/statsCases/limit-chunk-count-plugin/d.js 22 bytes {0} [built] - [4] (webpack)/test/statsCases/limit-chunk-count-plugin/e.js 22 bytes {0} [built] - [5] (webpack)/test/statsCases/limit-chunk-count-plugin/index.js 73 bytes {0} [built] + [0] (webpack)/test/statsCases/limit-chunk-count-plugin/index.js 73 bytes {0} [built] + [1] (webpack)/test/statsCases/limit-chunk-count-plugin/a.js 22 bytes {0} [built] + [2] (webpack)/test/statsCases/limit-chunk-count-plugin/b.js 22 bytes {0} [built] + [3] (webpack)/test/statsCases/limit-chunk-count-plugin/c.js 30 bytes {0} [built] + [4] (webpack)/test/statsCases/limit-chunk-count-plugin/d.js 22 bytes {0} [built] + [5] (webpack)/test/statsCases/limit-chunk-count-plugin/e.js 22 bytes {0} [built] Child - Hash: a8178dd1adacd47a6b70 + Hash: b34fa5f72acbbc9cbd9a Time: Xms Asset Size Chunks Chunk Names - 0.bundle.js 592 bytes 0 [emitted] - bundle.js 6.29 kB 1 [emitted] main + 0.bundle.js 601 bytes 0 [emitted] + bundle.js 6.12 kB 1 [emitted] main chunk {0} 0.bundle.js 118 bytes {1} [rendered] - [0] (webpack)/test/statsCases/limit-chunk-count-plugin/a.js 22 bytes {0} [built] - [1] (webpack)/test/statsCases/limit-chunk-count-plugin/b.js 22 bytes {0} [built] - [2] (webpack)/test/statsCases/limit-chunk-count-plugin/c.js 30 bytes {0} [built] - [3] (webpack)/test/statsCases/limit-chunk-count-plugin/d.js 22 bytes {0} [built] - [4] (webpack)/test/statsCases/limit-chunk-count-plugin/e.js 22 bytes {0} [built] + [1] (webpack)/test/statsCases/limit-chunk-count-plugin/a.js 22 bytes {0} [built] + [2] (webpack)/test/statsCases/limit-chunk-count-plugin/b.js 22 bytes {0} [built] + [3] (webpack)/test/statsCases/limit-chunk-count-plugin/c.js 30 bytes {0} [built] + [4] (webpack)/test/statsCases/limit-chunk-count-plugin/d.js 22 bytes {0} [built] + [5] (webpack)/test/statsCases/limit-chunk-count-plugin/e.js 22 bytes {0} [built] chunk {1} bundle.js (main) 73 bytes [entry] [rendered] - [5] (webpack)/test/statsCases/limit-chunk-count-plugin/index.js 73 bytes {1} [built] + [0] (webpack)/test/statsCases/limit-chunk-count-plugin/index.js 73 bytes {1} [built] Child - Hash: 043f3d1f8be496acf7a6 + Hash: 404c277a8869b8a6a62e Time: Xms Asset Size Chunks Chunk Names - 0.bundle.js 445 bytes 0 [emitted] - 1.bundle.js 204 bytes 1 [emitted] - bundle.js 6.28 kB 2 [emitted] main + 0.bundle.js 454 bytes 0 [emitted] + 1.bundle.js 182 bytes 1 [emitted] + bundle.js 6.11 kB 2 [emitted] main chunk {0} 0.bundle.js 74 bytes {2} [rendered] - [0] (webpack)/test/statsCases/limit-chunk-count-plugin/a.js 22 bytes {0} [built] - [2] (webpack)/test/statsCases/limit-chunk-count-plugin/c.js 30 bytes {0} [built] - [3] (webpack)/test/statsCases/limit-chunk-count-plugin/d.js 22 bytes {0} [built] + [1] (webpack)/test/statsCases/limit-chunk-count-plugin/a.js 22 bytes {0} [built] + [3] (webpack)/test/statsCases/limit-chunk-count-plugin/c.js 30 bytes {0} [built] + [4] (webpack)/test/statsCases/limit-chunk-count-plugin/d.js 22 bytes {0} [built] chunk {1} 1.bundle.js 44 bytes {0} {2} [rendered] - [1] (webpack)/test/statsCases/limit-chunk-count-plugin/b.js 22 bytes {1} [built] - [4] (webpack)/test/statsCases/limit-chunk-count-plugin/e.js 22 bytes {1} [built] + [2] (webpack)/test/statsCases/limit-chunk-count-plugin/b.js 22 bytes {1} [built] + [5] (webpack)/test/statsCases/limit-chunk-count-plugin/e.js 22 bytes {1} [built] chunk {2} bundle.js (main) 73 bytes [entry] [rendered] - [5] (webpack)/test/statsCases/limit-chunk-count-plugin/index.js 73 bytes {2} [built] + [0] (webpack)/test/statsCases/limit-chunk-count-plugin/index.js 73 bytes {2} [built] Child - Hash: e0df24380874d11a123a + Hash: 5c32ec6fc2ff40a3b587 Time: Xms Asset Size Chunks Chunk Names - 0.bundle.js 204 bytes 0 [emitted] - 1.bundle.js 195 bytes 1 [emitted] + 0.bundle.js 182 bytes 0 [emitted] + 1.bundle.js 204 bytes 1 [emitted] 2.bundle.js 283 bytes 2 [emitted] - bundle.js 6.26 kB 3 [emitted] main + bundle.js 6.1 kB 3 [emitted] main chunk {0} 0.bundle.js 44 bytes {2} {3} [rendered] - [1] (webpack)/test/statsCases/limit-chunk-count-plugin/b.js 22 bytes {0} [built] - [4] (webpack)/test/statsCases/limit-chunk-count-plugin/e.js 22 bytes {0} [built] + [2] (webpack)/test/statsCases/limit-chunk-count-plugin/b.js 22 bytes {0} [built] + [5] (webpack)/test/statsCases/limit-chunk-count-plugin/e.js 22 bytes {0} [built] chunk {1} 1.bundle.js 44 bytes {2} {3} [rendered] - [0] (webpack)/test/statsCases/limit-chunk-count-plugin/a.js 22 bytes {1} [built] - [3] (webpack)/test/statsCases/limit-chunk-count-plugin/d.js 22 bytes {1} [built] + [1] (webpack)/test/statsCases/limit-chunk-count-plugin/a.js 22 bytes {1} [built] + [4] (webpack)/test/statsCases/limit-chunk-count-plugin/d.js 22 bytes {1} [built] chunk {2} 2.bundle.js 30 bytes {3} [rendered] - [2] (webpack)/test/statsCases/limit-chunk-count-plugin/c.js 30 bytes {2} [built] + [3] (webpack)/test/statsCases/limit-chunk-count-plugin/c.js 30 bytes {2} [built] chunk {3} bundle.js (main) 73 bytes [entry] [rendered] - [5] (webpack)/test/statsCases/limit-chunk-count-plugin/index.js 73 bytes {3} [built] \ No newline at end of file + [0] (webpack)/test/statsCases/limit-chunk-count-plugin/index.js 73 bytes {3} [built] \ No newline at end of file diff --git a/test/statsCases/max-modules-default/expected.txt b/test/statsCases/max-modules-default/expected.txt index 6f4233e4b..e4cee1b02 100644 --- a/test/statsCases/max-modules-default/expected.txt +++ b/test/statsCases/max-modules-default/expected.txt @@ -1,21 +1,20 @@ -Hash: 8f4b66734cb63e0581be +Hash: b70eb677e8a8b3694c25 Time: Xms Asset Size Chunks Chunk Names -main.js 5.95 kB 0 [emitted] main -chunk {0} main.js (main) 1.18 kB [entry] [rendered] - [0] (webpack)/test/statsCases/max-modules-default/a.js?1 33 bytes {0} [built] - [1] (webpack)/test/statsCases/max-modules-default/a.js?10 33 bytes {0} [built] - [2] (webpack)/test/statsCases/max-modules-default/a.js?2 33 bytes {0} [built] - [3] (webpack)/test/statsCases/max-modules-default/a.js?3 33 bytes {0} [built] - [4] (webpack)/test/statsCases/max-modules-default/a.js?4 33 bytes {0} [built] - [5] (webpack)/test/statsCases/max-modules-default/a.js?5 33 bytes {0} [built] - [6] (webpack)/test/statsCases/max-modules-default/a.js?6 33 bytes {0} [built] - [7] (webpack)/test/statsCases/max-modules-default/a.js?7 33 bytes {0} [built] - [8] (webpack)/test/statsCases/max-modules-default/a.js?8 33 bytes {0} [built] - [9] (webpack)/test/statsCases/max-modules-default/a.js?9 33 bytes {0} [built] - [20] (webpack)/test/statsCases/max-modules-default/c.js?1 33 bytes {0} [built] - [21] (webpack)/test/statsCases/max-modules-default/c.js?10 33 bytes {0} [built] - [22] (webpack)/test/statsCases/max-modules-default/c.js?2 33 bytes {0} [built] - [23] (webpack)/test/statsCases/max-modules-default/c.js?3 33 bytes {0} [built] - [30] (webpack)/test/statsCases/max-modules-default/index.js 181 bytes {0} [built] - + 16 hidden modules \ No newline at end of file +main.js 5.79 kB 0 [emitted] main + [0] (webpack)/test/statsCases/max-modules-default/a.js?1 33 bytes {0} [built] + [1] (webpack)/test/statsCases/max-modules-default/a.js?2 33 bytes {0} [built] + [2] (webpack)/test/statsCases/max-modules-default/a.js?3 33 bytes {0} [built] + [3] (webpack)/test/statsCases/max-modules-default/a.js?4 33 bytes {0} [built] + [4] (webpack)/test/statsCases/max-modules-default/a.js?5 33 bytes {0} [built] + [5] (webpack)/test/statsCases/max-modules-default/a.js?6 33 bytes {0} [built] + [6] (webpack)/test/statsCases/max-modules-default/a.js?7 33 bytes {0} [built] + [7] (webpack)/test/statsCases/max-modules-default/a.js?8 33 bytes {0} [built] + [8] (webpack)/test/statsCases/max-modules-default/a.js?9 33 bytes {0} [built] + [9] (webpack)/test/statsCases/max-modules-default/a.js?10 33 bytes {0} [built] + [10] (webpack)/test/statsCases/max-modules-default/index.js 181 bytes {0} [built] + [11] (webpack)/test/statsCases/max-modules-default/c.js?1 33 bytes {0} [built] + [13] (webpack)/test/statsCases/max-modules-default/c.js?2 33 bytes {0} [built] + [27] (webpack)/test/statsCases/max-modules-default/c.js?9 33 bytes {0} [built] + [29] (webpack)/test/statsCases/max-modules-default/c.js?10 33 bytes {0} [built] + + 16 hidden modules \ No newline at end of file diff --git a/test/statsCases/max-modules/expected.txt b/test/statsCases/max-modules/expected.txt index 16a20b5f2..9303956d2 100644 --- a/test/statsCases/max-modules/expected.txt +++ b/test/statsCases/max-modules/expected.txt @@ -1,26 +1,25 @@ -Hash: 8f4b66734cb63e0581be +Hash: b70eb677e8a8b3694c25 Time: Xms Asset Size Chunks Chunk Names -main.js 5.95 kB 0 [emitted] main -chunk {0} main.js (main) 1.18 kB [entry] [rendered] - [0] (webpack)/test/statsCases/max-modules/a.js?1 33 bytes {0} [built] - [1] (webpack)/test/statsCases/max-modules/a.js?10 33 bytes {0} [built] - [2] (webpack)/test/statsCases/max-modules/a.js?2 33 bytes {0} [built] - [3] (webpack)/test/statsCases/max-modules/a.js?3 33 bytes {0} [built] - [4] (webpack)/test/statsCases/max-modules/a.js?4 33 bytes {0} [built] - [5] (webpack)/test/statsCases/max-modules/a.js?5 33 bytes {0} [built] - [6] (webpack)/test/statsCases/max-modules/a.js?6 33 bytes {0} [built] - [7] (webpack)/test/statsCases/max-modules/a.js?7 33 bytes {0} [built] - [8] (webpack)/test/statsCases/max-modules/a.js?8 33 bytes {0} [built] - [9] (webpack)/test/statsCases/max-modules/a.js?9 33 bytes {0} [built] - [20] (webpack)/test/statsCases/max-modules/c.js?1 33 bytes {0} [built] - [21] (webpack)/test/statsCases/max-modules/c.js?10 33 bytes {0} [built] - [22] (webpack)/test/statsCases/max-modules/c.js?2 33 bytes {0} [built] - [23] (webpack)/test/statsCases/max-modules/c.js?3 33 bytes {0} [built] - [24] (webpack)/test/statsCases/max-modules/c.js?4 33 bytes {0} [built] - [25] (webpack)/test/statsCases/max-modules/c.js?5 33 bytes {0} [built] - [26] (webpack)/test/statsCases/max-modules/c.js?6 33 bytes {0} [built] - [27] (webpack)/test/statsCases/max-modules/c.js?7 33 bytes {0} [built] - [28] (webpack)/test/statsCases/max-modules/c.js?8 33 bytes {0} [built] - [30] (webpack)/test/statsCases/max-modules/index.js 181 bytes {0} [built] - + 11 hidden modules \ No newline at end of file +main.js 5.79 kB 0 [emitted] main + [0] (webpack)/test/statsCases/max-modules/a.js?1 33 bytes {0} [built] + [1] (webpack)/test/statsCases/max-modules/a.js?2 33 bytes {0} [built] + [2] (webpack)/test/statsCases/max-modules/a.js?3 33 bytes {0} [built] + [3] (webpack)/test/statsCases/max-modules/a.js?4 33 bytes {0} [built] + [4] (webpack)/test/statsCases/max-modules/a.js?5 33 bytes {0} [built] + [5] (webpack)/test/statsCases/max-modules/a.js?6 33 bytes {0} [built] + [6] (webpack)/test/statsCases/max-modules/a.js?7 33 bytes {0} [built] + [7] (webpack)/test/statsCases/max-modules/a.js?8 33 bytes {0} [built] + [8] (webpack)/test/statsCases/max-modules/a.js?9 33 bytes {0} [built] + [9] (webpack)/test/statsCases/max-modules/a.js?10 33 bytes {0} [built] + [10] (webpack)/test/statsCases/max-modules/index.js 181 bytes {0} [built] + [11] (webpack)/test/statsCases/max-modules/c.js?1 33 bytes {0} [built] + [13] (webpack)/test/statsCases/max-modules/c.js?2 33 bytes {0} [built] + [15] (webpack)/test/statsCases/max-modules/c.js?3 33 bytes {0} [built] + [17] (webpack)/test/statsCases/max-modules/c.js?4 33 bytes {0} [built] + [19] (webpack)/test/statsCases/max-modules/c.js?5 33 bytes {0} [built] + [23] (webpack)/test/statsCases/max-modules/c.js?7 33 bytes {0} [built] + [25] (webpack)/test/statsCases/max-modules/c.js?8 33 bytes {0} [built] + [27] (webpack)/test/statsCases/max-modules/c.js?9 33 bytes {0} [built] + [29] (webpack)/test/statsCases/max-modules/c.js?10 33 bytes {0} [built] + + 11 hidden modules \ No newline at end of file diff --git a/test/statsCases/module-trace-disabled-in-error/expected.txt b/test/statsCases/module-trace-disabled-in-error/expected.txt index 423af5c6e..4a1cecf00 100644 --- a/test/statsCases/module-trace-disabled-in-error/expected.txt +++ b/test/statsCases/module-trace-disabled-in-error/expected.txt @@ -1,9 +1,8 @@ Hash: 6e950f2e83663cb6e9a6 Time: Xms Asset Size Chunks Chunk Names -main.js 2.81 kB 0 [emitted] main -chunk {0} main.js (main) 25 bytes [entry] [rendered] - [0] (webpack)/test/statsCases/module-trace-disabled-in-error/index.js 25 bytes {0} [built] +main.js 2.65 kB 0 [emitted] main + [0] (webpack)/test/statsCases/module-trace-disabled-in-error/index.js 25 bytes {0} [built] ERROR in (webpack)/test/statsCases/module-trace-disabled-in-error/index.js Module not found: Error: Can't resolve 'does-not-exist' in 'Xdir/module-trace-disabled-in-error' \ No newline at end of file diff --git a/test/statsCases/module-trace-enabled-in-error/expected.txt b/test/statsCases/module-trace-enabled-in-error/expected.txt index edb194098..f5b134c2e 100644 --- a/test/statsCases/module-trace-enabled-in-error/expected.txt +++ b/test/statsCases/module-trace-enabled-in-error/expected.txt @@ -1,9 +1,8 @@ Hash: 6e950f2e83663cb6e9a6 Time: Xms Asset Size Chunks Chunk Names -main.js 2.81 kB 0 [emitted] main -chunk {0} main.js (main) 25 bytes [entry] [rendered] - [0] (webpack)/test/statsCases/module-trace-enabled-in-error/index.js 25 bytes {0} [built] +main.js 2.65 kB 0 [emitted] main + [0] (webpack)/test/statsCases/module-trace-enabled-in-error/index.js 25 bytes {0} [built] ERROR in (webpack)/test/statsCases/module-trace-enabled-in-error/index.js Module not found: Error: Can't resolve 'does-not-exist' in 'Xdir/module-trace-enabled-in-error' diff --git a/test/statsCases/named-chunks-plugin-async/expected.txt b/test/statsCases/named-chunks-plugin-async/expected.txt index bdd1c509f..809ff0492 100644 --- a/test/statsCases/named-chunks-plugin-async/expected.txt +++ b/test/statsCases/named-chunks-plugin-async/expected.txt @@ -3,10 +3,7 @@ Time: Xms Asset Size Chunks Chunk Names chunk-containing-__a_js.js 266 bytes chunk-containing-__a_js [emitted] chunk-containing-__b_js.js 123 bytes chunk-containing-__b_js [emitted] - entry.js 6.15 kB entry [emitted] entry -chunk {chunk-containing-__a_js} chunk-containing-__a_js.js 37 bytes {entry} [rendered] - [2] (webpack)/test/statsCases/named-chunks-plugin-async/modules/a.js 37 bytes {chunk-containing-__a_js} [built] -chunk {chunk-containing-__b_js} chunk-containing-__b_js.js 22 bytes {chunk-containing-__a_js} {entry} [rendered] - [0] (webpack)/test/statsCases/named-chunks-plugin-async/modules/b.js 22 bytes {chunk-containing-__b_js} [built] -chunk {entry} entry.js (entry) 47 bytes [entry] [rendered] - [1] (webpack)/test/statsCases/named-chunks-plugin-async/entry.js 47 bytes {entry} [built] \ No newline at end of file + entry.js 5.99 kB entry [emitted] entry + [0] (webpack)/test/statsCases/named-chunks-plugin-async/modules/b.js 22 bytes {chunk-containing-__b_js} [built] + [1] (webpack)/test/statsCases/named-chunks-plugin-async/entry.js 47 bytes {entry} [built] + [2] (webpack)/test/statsCases/named-chunks-plugin-async/modules/a.js 37 bytes {chunk-containing-__a_js} [built] \ No newline at end of file diff --git a/test/statsCases/named-chunks-plugin-async/webpack.config.js b/test/statsCases/named-chunks-plugin-async/webpack.config.js index 468dcf850..1b81d94fa 100644 --- a/test/statsCases/named-chunks-plugin-async/webpack.config.js +++ b/test/statsCases/named-chunks-plugin-async/webpack.config.js @@ -12,13 +12,13 @@ module.exports = { if(chunk.name) { return chunk.name; } - const modulesToName = (mods) => mods.map((mod) => { + const chunkModulesToName = (chunk) => chunk.mapModules((mod) => { const rs = new RequestShortener(mod.context); return rs.shorten(mod.request).replace(/[.\/\\]/g, "_"); }).join("-"); - if(chunk.modules.length > 0) { - return `chunk-containing-${modulesToName(chunk.modules)}`; + if(chunk.getNumberOfModules() > 0) { + return `chunk-containing-${chunkModulesToName(chunk)}`; } return null; diff --git a/test/statsCases/named-chunks-plugin/expected.txt b/test/statsCases/named-chunks-plugin/expected.txt index c4704ca4d..e19f2054f 100644 --- a/test/statsCases/named-chunks-plugin/expected.txt +++ b/test/statsCases/named-chunks-plugin/expected.txt @@ -2,13 +2,10 @@ Hash: ac63e5be974bcdfea3a3 Time: Xms Asset Size Chunks Chunk Names entry.js 345 bytes entry [emitted] entry -manifest.js 5.95 kB manifest [emitted] manifest +manifest.js 5.78 kB manifest [emitted] manifest vendor.js 397 bytes vendor [emitted] vendor -chunk {entry} entry.js (entry) 94 bytes {vendor} [initial] [rendered] - [./entry.js] (webpack)/test/statsCases/named-chunks-plugin/entry.js 72 bytes {entry} [built] - [./modules/c.js] (webpack)/test/statsCases/named-chunks-plugin/modules/c.js 22 bytes {entry} [built] -chunk {manifest} manifest.js (manifest) 0 bytes [entry] [rendered] -chunk {vendor} vendor.js (vendor) 84 bytes {manifest} [initial] [rendered] - [./modules/a.js] (webpack)/test/statsCases/named-chunks-plugin/modules/a.js 22 bytes {vendor} [built] - [./modules/b.js] (webpack)/test/statsCases/named-chunks-plugin/modules/b.js 22 bytes {vendor} [built] - [0] multi ./modules/a ./modules/b 40 bytes {vendor} [built] \ No newline at end of file + [0] multi ./modules/a ./modules/b 40 bytes {vendor} [built] +[./entry.js] (webpack)/test/statsCases/named-chunks-plugin/entry.js 72 bytes {entry} [built] +[./modules/a.js] (webpack)/test/statsCases/named-chunks-plugin/modules/a.js 22 bytes {vendor} [built] +[./modules/b.js] (webpack)/test/statsCases/named-chunks-plugin/modules/b.js 22 bytes {vendor} [built] +[./modules/c.js] (webpack)/test/statsCases/named-chunks-plugin/modules/c.js 22 bytes {entry} [built] \ No newline at end of file diff --git a/test/statsCases/optimize-chunks/expected.txt b/test/statsCases/optimize-chunks/expected.txt index 49f2369d0..9a932b565 100644 --- a/test/statsCases/optimize-chunks/expected.txt +++ b/test/statsCases/optimize-chunks/expected.txt @@ -1,43 +1,43 @@ -Hash: 999ae28af33cdfa6ec93 +Hash: 9a598b7aa486cde5256a Time: Xms Asset Size Chunks Chunk Names 0.js 231 bytes 0 [emitted] cir1 - 1.js 218 bytes 1, 2 [emitted] abd + 1.js 209 bytes 1, 2 [emitted] abd 2.js 133 bytes 2 [emitted] ab 3.js 246 bytes 3 [emitted] cir2 - 4.js 140 bytes 4, 6 [emitted] chunk + 4.js 162 bytes 4, 6 [emitted] chunk 5.js 306 bytes 5, 3 [emitted] cir2 from cir1 6.js 80 bytes 6 [emitted] ac in ab -main.js 6.94 kB 7 [emitted] main +main.js 6.78 kB 7 [emitted] main chunk {0} 0.js (cir1) 81 bytes {3} {5} {7} [rendered] - > duplicate cir1 from cir2 [3] (webpack)/test/statsCases/optimize-chunks/circular2.js 1:0-79 + > duplicate cir1 from cir2 [6] (webpack)/test/statsCases/optimize-chunks/circular2.js 1:0-79 > duplicate cir1 [7] (webpack)/test/statsCases/optimize-chunks/index.js 13:0-54 - [2] (webpack)/test/statsCases/optimize-chunks/circular1.js 81 bytes {0} [built] + [5] (webpack)/test/statsCases/optimize-chunks/circular1.js 81 bytes {0} [built] chunk {1} 1.js (abd) 0 bytes {7} [rendered] > abd [7] (webpack)/test/statsCases/optimize-chunks/index.js 8:0-11:9 [0] (webpack)/test/statsCases/optimize-chunks/modules/a.js 0 bytes {1} {2} [built] [1] (webpack)/test/statsCases/optimize-chunks/modules/b.js 0 bytes {1} {2} [built] - [5] (webpack)/test/statsCases/optimize-chunks/modules/d.js 0 bytes {1} {4} [built] + [4] (webpack)/test/statsCases/optimize-chunks/modules/d.js 0 bytes {1} {4} [built] chunk {2} 2.js (ab) 0 bytes {7} [rendered] > ab [7] (webpack)/test/statsCases/optimize-chunks/index.js 1:0-6:8 [0] (webpack)/test/statsCases/optimize-chunks/modules/a.js 0 bytes {1} {2} [built] [1] (webpack)/test/statsCases/optimize-chunks/modules/b.js 0 bytes {1} {2} [built] chunk {3} 3.js (cir2) 81 bytes {7} [rendered] > cir2 [7] (webpack)/test/statsCases/optimize-chunks/index.js 14:0-54 - [3] (webpack)/test/statsCases/optimize-chunks/circular2.js 81 bytes {3} {5} [built] + [6] (webpack)/test/statsCases/optimize-chunks/circular2.js 81 bytes {3} {5} [built] chunk {4} 4.js (chunk) 0 bytes {1} {6} [rendered] > chunk [7] (webpack)/test/statsCases/optimize-chunks/index.js 3:2-4:13 > chunk [7] (webpack)/test/statsCases/optimize-chunks/index.js 9:1-10:12 - [4] (webpack)/test/statsCases/optimize-chunks/modules/c.js 0 bytes {4} {6} [built] - [5] (webpack)/test/statsCases/optimize-chunks/modules/d.js 0 bytes {1} {4} [built] + [3] (webpack)/test/statsCases/optimize-chunks/modules/c.js 0 bytes {4} {6} [built] + [4] (webpack)/test/statsCases/optimize-chunks/modules/d.js 0 bytes {1} {4} [built] chunk {5} 5.js (cir2 from cir1) 81 bytes {0} [rendered] - > cir2 from cir1 [2] (webpack)/test/statsCases/optimize-chunks/circular1.js 1:0-79 - [3] (webpack)/test/statsCases/optimize-chunks/circular2.js 81 bytes {3} {5} [built] + > cir2 from cir1 [5] (webpack)/test/statsCases/optimize-chunks/circular1.js 1:0-79 + [6] (webpack)/test/statsCases/optimize-chunks/circular2.js 81 bytes {3} {5} [built] [8] (webpack)/test/statsCases/optimize-chunks/modules/e.js 0 bytes {5} [built] chunk {6} 6.js (ac in ab) 0 bytes {2} [rendered] > ac in ab [7] (webpack)/test/statsCases/optimize-chunks/index.js 2:1-5:15 - [4] (webpack)/test/statsCases/optimize-chunks/modules/c.js 0 bytes {4} {6} [built] + [3] (webpack)/test/statsCases/optimize-chunks/modules/c.js 0 bytes {4} {6} [built] chunk {7} main.js (main) 523 bytes [entry] [rendered] > main [7] (webpack)/test/statsCases/optimize-chunks/index.js - [6] (webpack)/test/statsCases/optimize-chunks/modules/f.js 0 bytes {7} [built] + [2] (webpack)/test/statsCases/optimize-chunks/modules/f.js 0 bytes {7} [built] [7] (webpack)/test/statsCases/optimize-chunks/index.js 523 bytes {7} [built] \ No newline at end of file diff --git a/test/statsCases/optimize-chunks/webpack.config.js b/test/statsCases/optimize-chunks/webpack.config.js index aaf6056a2..1af7de230 100644 --- a/test/statsCases/optimize-chunks/webpack.config.js +++ b/test/statsCases/optimize-chunks/webpack.config.js @@ -2,6 +2,9 @@ module.exports = { entry: "./index", stats: { reasons: false, + modules: false, + chunks: true, + chunkModules: true, chunkOrigins: true } }; diff --git a/test/statsCases/performance-disabled/expected.txt b/test/statsCases/performance-disabled/expected.txt index fd629bff5..8c700e931 100644 --- a/test/statsCases/performance-disabled/expected.txt +++ b/test/statsCases/performance-disabled/expected.txt @@ -1,17 +1,13 @@ Time: Xms Asset Size Chunks Chunk Names 0.js 238 bytes 0 [emitted] - 1.js 108 bytes 1 [emitted] - 2.js 204 bytes 2 [emitted] + 1.js 102 bytes 1 [emitted] + 2.js 182 bytes 2 [emitted] main.js 306 kB 3 [emitted] main Entrypoint main = main.js -chunk {0} 0.js 54 bytes {3} [rendered] - [2] (webpack)/test/statsCases/performance-disabled/c.js 54 bytes {0} [built] -chunk {1} 1.js 22 bytes {3} [rendered] - [1] (webpack)/test/statsCases/performance-disabled/b.js 22 bytes {1} [built] -chunk {2} 2.js 44 bytes {0} [rendered] - [3] (webpack)/test/statsCases/performance-disabled/d.js 22 bytes {2} [built] - [4] (webpack)/test/statsCases/performance-disabled/e.js 22 bytes {2} [built] -chunk {3} main.js (main) 300 kB [entry] [rendered] - [0] (webpack)/test/statsCases/performance-disabled/a.js 300 kB {3} [built] - [5] (webpack)/test/statsCases/performance-disabled/index.js 52 bytes {3} [built] \ No newline at end of file + [0] (webpack)/test/statsCases/performance-disabled/index.js 52 bytes {3} [built] + [1] (webpack)/test/statsCases/performance-disabled/a.js 300 kB {3} [built] + [2] (webpack)/test/statsCases/performance-disabled/b.js 22 bytes {1} [built] + [3] (webpack)/test/statsCases/performance-disabled/c.js 54 bytes {0} [built] + [4] (webpack)/test/statsCases/performance-disabled/d.js 22 bytes {2} [built] + [5] (webpack)/test/statsCases/performance-disabled/e.js 22 bytes {2} [built] \ No newline at end of file diff --git a/test/statsCases/performance-error/expected.txt b/test/statsCases/performance-error/expected.txt index 35daf3e17..57c4f2d85 100644 --- a/test/statsCases/performance-error/expected.txt +++ b/test/statsCases/performance-error/expected.txt @@ -1,20 +1,16 @@ Time: Xms Asset Size Chunks Chunk Names 0.js 238 bytes 0 [emitted] - 1.js 108 bytes 1 [emitted] - 2.js 204 bytes 2 [emitted] + 1.js 102 bytes 1 [emitted] + 2.js 182 bytes 2 [emitted] main.js 306 kB 3 [emitted] [big] main Entrypoint main [big] = main.js -chunk {0} 0.js 54 bytes {3} [rendered] - [2] (webpack)/test/statsCases/performance-error/c.js 54 bytes {0} [built] -chunk {1} 1.js 22 bytes {3} [rendered] - [1] (webpack)/test/statsCases/performance-error/b.js 22 bytes {1} [built] -chunk {2} 2.js 44 bytes {0} [rendered] - [3] (webpack)/test/statsCases/performance-error/d.js 22 bytes {2} [built] - [4] (webpack)/test/statsCases/performance-error/e.js 22 bytes {2} [built] -chunk {3} main.js (main) 300 kB [entry] [rendered] - [0] (webpack)/test/statsCases/performance-error/a.js 300 kB {3} [built] - [5] (webpack)/test/statsCases/performance-error/index.js 52 bytes {3} [built] + [0] (webpack)/test/statsCases/performance-error/index.js 52 bytes {3} [built] + [1] (webpack)/test/statsCases/performance-error/a.js 300 kB {3} [built] + [2] (webpack)/test/statsCases/performance-error/b.js 22 bytes {1} [built] + [3] (webpack)/test/statsCases/performance-error/c.js 54 bytes {0} [built] + [4] (webpack)/test/statsCases/performance-error/d.js 22 bytes {2} [built] + [5] (webpack)/test/statsCases/performance-error/e.js 22 bytes {2} [built] ERROR in asset size limit: The following asset(s) exceed the recommended size limit (250 kB). This can impact web performance. diff --git a/test/statsCases/performance-no-async-chunks-shown/expected.txt b/test/statsCases/performance-no-async-chunks-shown/expected.txt index 3437df4c2..8ed34c516 100644 --- a/test/statsCases/performance-no-async-chunks-shown/expected.txt +++ b/test/statsCases/performance-no-async-chunks-shown/expected.txt @@ -1,18 +1,15 @@ Time: Xms Asset Size Chunks Chunk Names - sec.js 2.98 kB 0 [emitted] sec + sec.js 2.82 kB 0 [emitted] sec main.js 303 kB 1 [emitted] [big] main Entrypoint main [big] = main.js Entrypoint sec = sec.js -chunk {0} sec.js (sec) 114 bytes [entry] [rendered] - [0] (webpack)/test/statsCases/performance-no-async-chunks-shown/b.js 22 bytes {0} {1} [built] - [2] (webpack)/test/statsCases/performance-no-async-chunks-shown/c.js 22 bytes {0} [built] - [3] (webpack)/test/statsCases/performance-no-async-chunks-shown/d.js 22 bytes {0} [built] - [5] (webpack)/test/statsCases/performance-no-async-chunks-shown/index2.js 48 bytes {0} [built] -chunk {1} main.js (main) 300 kB [entry] [rendered] - [0] (webpack)/test/statsCases/performance-no-async-chunks-shown/b.js 22 bytes {0} {1} [built] - [1] (webpack)/test/statsCases/performance-no-async-chunks-shown/a.js 300 kB {1} [built] - [4] (webpack)/test/statsCases/performance-no-async-chunks-shown/index.js 32 bytes {1} [built] + [0] (webpack)/test/statsCases/performance-no-async-chunks-shown/b.js 22 bytes {0} {1} [built] + [1] (webpack)/test/statsCases/performance-no-async-chunks-shown/index.js 32 bytes {1} [built] + [2] (webpack)/test/statsCases/performance-no-async-chunks-shown/a.js 300 kB {1} [built] + [3] (webpack)/test/statsCases/performance-no-async-chunks-shown/index2.js 48 bytes {0} [built] + [4] (webpack)/test/statsCases/performance-no-async-chunks-shown/c.js 22 bytes {0} [built] + [5] (webpack)/test/statsCases/performance-no-async-chunks-shown/d.js 22 bytes {0} [built] WARNING in asset size limit: The following asset(s) exceed the recommended size limit (250 kB). This can impact web performance. diff --git a/test/statsCases/performance-no-hints/expected.txt b/test/statsCases/performance-no-hints/expected.txt index 1fd21e405..e044be0ff 100644 --- a/test/statsCases/performance-no-hints/expected.txt +++ b/test/statsCases/performance-no-hints/expected.txt @@ -1,17 +1,13 @@ Time: Xms Asset Size Chunks Chunk Names 0.js 238 bytes 0 [emitted] - 1.js 108 bytes 1 [emitted] - 2.js 204 bytes 2 [emitted] + 1.js 102 bytes 1 [emitted] + 2.js 182 bytes 2 [emitted] main.js 306 kB 3 [emitted] [big] main Entrypoint main [big] = main.js -chunk {0} 0.js 54 bytes {3} [rendered] - [2] (webpack)/test/statsCases/performance-no-hints/c.js 54 bytes {0} [built] -chunk {1} 1.js 22 bytes {3} [rendered] - [1] (webpack)/test/statsCases/performance-no-hints/b.js 22 bytes {1} [built] -chunk {2} 2.js 44 bytes {0} [rendered] - [3] (webpack)/test/statsCases/performance-no-hints/d.js 22 bytes {2} [built] - [4] (webpack)/test/statsCases/performance-no-hints/e.js 22 bytes {2} [built] -chunk {3} main.js (main) 300 kB [entry] [rendered] - [0] (webpack)/test/statsCases/performance-no-hints/a.js 300 kB {3} [built] - [5] (webpack)/test/statsCases/performance-no-hints/index.js 52 bytes {3} [built] \ No newline at end of file + [0] (webpack)/test/statsCases/performance-no-hints/index.js 52 bytes {3} [built] + [1] (webpack)/test/statsCases/performance-no-hints/a.js 300 kB {3} [built] + [2] (webpack)/test/statsCases/performance-no-hints/b.js 22 bytes {1} [built] + [3] (webpack)/test/statsCases/performance-no-hints/c.js 54 bytes {0} [built] + [4] (webpack)/test/statsCases/performance-no-hints/d.js 22 bytes {2} [built] + [5] (webpack)/test/statsCases/performance-no-hints/e.js 22 bytes {2} [built] \ No newline at end of file diff --git a/test/statsCases/performance-oversize-limit-error/expected.txt b/test/statsCases/performance-oversize-limit-error/expected.txt index 92f30846f..200eedb07 100644 --- a/test/statsCases/performance-oversize-limit-error/expected.txt +++ b/test/statsCases/performance-oversize-limit-error/expected.txt @@ -4,12 +4,9 @@ Time: Xms main.js 303 kB 1 [emitted] [big] main Entrypoint main [big] = main.js Entrypoint sec [big] = sec.js -chunk {0} sec.js (sec) 300 kB [entry] [rendered] - [0] (webpack)/test/statsCases/performance-oversize-limit-error/a.js 300 kB {0} {1} [built] - [2] (webpack)/test/statsCases/performance-oversize-limit-error/index2.js 16 bytes {0} [built] -chunk {1} main.js (main) 300 kB [entry] [rendered] - [0] (webpack)/test/statsCases/performance-oversize-limit-error/a.js 300 kB {0} {1} [built] - [1] (webpack)/test/statsCases/performance-oversize-limit-error/index.js 16 bytes {1} [built] + [0] (webpack)/test/statsCases/performance-oversize-limit-error/a.js 300 kB {0} {1} [built] + [1] (webpack)/test/statsCases/performance-oversize-limit-error/index.js 16 bytes {1} [built] + [2] (webpack)/test/statsCases/performance-oversize-limit-error/index2.js 16 bytes {0} [built] ERROR in asset size limit: The following asset(s) exceed the recommended size limit (250 kB). This can impact web performance. diff --git a/test/statsCases/preset-detailed/a.js b/test/statsCases/preset-detailed/a.js new file mode 100644 index 000000000..6cd1d0075 --- /dev/null +++ b/test/statsCases/preset-detailed/a.js @@ -0,0 +1 @@ +module.exports = "a"; diff --git a/test/statsCases/preset-detailed/b.js b/test/statsCases/preset-detailed/b.js new file mode 100644 index 000000000..dfbbeb621 --- /dev/null +++ b/test/statsCases/preset-detailed/b.js @@ -0,0 +1 @@ +module.exports = "b"; diff --git a/test/statsCases/preset-detailed/c.js b/test/statsCases/preset-detailed/c.js new file mode 100644 index 000000000..84bdba76f --- /dev/null +++ b/test/statsCases/preset-detailed/c.js @@ -0,0 +1 @@ +require.ensure(["./d", "./e"], function(require) {}); diff --git a/test/statsCases/preset-detailed/d.js b/test/statsCases/preset-detailed/d.js new file mode 100644 index 000000000..0a281018c --- /dev/null +++ b/test/statsCases/preset-detailed/d.js @@ -0,0 +1 @@ +module.exports = "d"; diff --git a/test/statsCases/preset-detailed/e.js b/test/statsCases/preset-detailed/e.js new file mode 100644 index 000000000..7884d62f7 --- /dev/null +++ b/test/statsCases/preset-detailed/e.js @@ -0,0 +1 @@ +module.exports = "e"; diff --git a/test/statsCases/preset-detailed/expected.txt b/test/statsCases/preset-detailed/expected.txt new file mode 100644 index 000000000..d4b48f326 --- /dev/null +++ b/test/statsCases/preset-detailed/expected.txt @@ -0,0 +1,22 @@ +Hash: fd034b07589b0d56afb3 +Time: Xms + Asset Size Chunks Chunk Names + 0.js 238 bytes 0 [emitted] + 1.js 102 bytes 1 [emitted] + 2.js 182 bytes 2 [emitted] +main.js 6.1 kB 3 [emitted] main +Entrypoint main = main.js +chunk {0} 0.js 54 bytes {3} [rendered] + > [0] (webpack)/test/statsCases/preset-detailed/index.js 3:0-16 +chunk {1} 1.js 22 bytes {3} [rendered] + > [0] (webpack)/test/statsCases/preset-detailed/index.js 2:0-16 +chunk {2} 2.js 44 bytes {0} [rendered] + > [3] (webpack)/test/statsCases/preset-detailed/c.js 1:0-52 +chunk {3} main.js (main) 73 bytes [entry] [rendered] + > main [0] (webpack)/test/statsCases/preset-detailed/index.js + [0] (webpack)/test/statsCases/preset-detailed/index.js 51 bytes {3} [depth 0] [built] + [1] (webpack)/test/statsCases/preset-detailed/a.js 22 bytes {3} [depth 1] [built] + [2] (webpack)/test/statsCases/preset-detailed/b.js 22 bytes {1} [depth 1] [built] + [3] (webpack)/test/statsCases/preset-detailed/c.js 54 bytes {0} [depth 1] [built] + [4] (webpack)/test/statsCases/preset-detailed/d.js 22 bytes {2} [depth 2] [built] + [5] (webpack)/test/statsCases/preset-detailed/e.js 22 bytes {2} [depth 2] [built] \ No newline at end of file diff --git a/test/statsCases/preset-detailed/index.js b/test/statsCases/preset-detailed/index.js new file mode 100644 index 000000000..86b979b0d --- /dev/null +++ b/test/statsCases/preset-detailed/index.js @@ -0,0 +1,3 @@ +require("./a"); +require(["./b"]); +require(["./c"]); \ No newline at end of file diff --git a/test/statsCases/preset-detailed/webpack.config.js b/test/statsCases/preset-detailed/webpack.config.js new file mode 100644 index 000000000..0557c0405 --- /dev/null +++ b/test/statsCases/preset-detailed/webpack.config.js @@ -0,0 +1,4 @@ +module.exports = { + entry: "./index", + stats: "detailed" +}; diff --git a/test/statsCases/preset-minimal-simple/expected.txt b/test/statsCases/preset-minimal-simple/expected.txt index 21bb031a2..2ba6dec13 100644 --- a/test/statsCases/preset-minimal-simple/expected.txt +++ b/test/statsCases/preset-minimal-simple/expected.txt @@ -1 +1 @@ -chunk {0} main.js (main) 0 bytes [entry] [rendered] \ No newline at end of file + 1 module \ No newline at end of file diff --git a/test/statsCases/preset-minimal/expected.txt b/test/statsCases/preset-minimal/expected.txt index b5228183e..fb8d2244f 100644 --- a/test/statsCases/preset-minimal/expected.txt +++ b/test/statsCases/preset-minimal/expected.txt @@ -1,4 +1 @@ -chunk {0} 0.js 54 bytes {3} [rendered] -chunk {1} 1.js 22 bytes {3} [rendered] -chunk {2} 2.js 44 bytes {0} [rendered] -chunk {3} main.js (main) 73 bytes [entry] [rendered] \ No newline at end of file + 6 modules \ No newline at end of file diff --git a/test/statsCases/preset-mixed-array/expected.txt b/test/statsCases/preset-mixed-array/expected.txt index 3665b12d1..e355ec4b6 100644 --- a/test/statsCases/preset-mixed-array/expected.txt +++ b/test/statsCases/preset-mixed-array/expected.txt @@ -1,4 +1,5 @@ Child minimal: - chunk {0} main.js (main) 8 bytes [entry] [rendered] + 1 module Child verbose: - Entrypoint main = main.js \ No newline at end of file + Entrypoint main = main.js + [0] (webpack)/test/statsCases/preset-mixed-array/index.js 8 bytes {0} [built] \ No newline at end of file diff --git a/test/statsCases/preset-normal-performance-ensure-filter-sourcemaps/expected.txt b/test/statsCases/preset-normal-performance-ensure-filter-sourcemaps/expected.txt index 3ccf98a42..33bec0f02 100644 --- a/test/statsCases/preset-normal-performance-ensure-filter-sourcemaps/expected.txt +++ b/test/statsCases/preset-normal-performance-ensure-filter-sourcemaps/expected.txt @@ -1,23 +1,19 @@ Time: Xms Asset Size Chunks Chunk Names 0.js 268 bytes 0 [emitted] - 1.js 138 bytes 1 [emitted] - 2.js 234 bytes 2 [emitted] + 1.js 132 bytes 1 [emitted] + 2.js 212 bytes 2 [emitted] main.js 306 kB 3 [emitted] [big] main 0.js.map 291 bytes 0 [emitted] 1.js.map 250 bytes 1 [emitted] - 2.js.map 405 bytes 2 [emitted] + 2.js.map 404 bytes 2 [emitted] main.js.map 1.81 MB 3 [emitted] main -chunk {0} 0.js, 0.js.map 54 bytes {3} [rendered] - [2] (webpack)/test/statsCases/preset-normal-performance-ensure-filter-sourcemaps/c.js 54 bytes {0} [built] -chunk {1} 1.js, 1.js.map 22 bytes {3} [rendered] - [1] (webpack)/test/statsCases/preset-normal-performance-ensure-filter-sourcemaps/b.js 22 bytes {1} [built] -chunk {2} 2.js, 2.js.map 44 bytes {0} [rendered] - [3] (webpack)/test/statsCases/preset-normal-performance-ensure-filter-sourcemaps/d.js 22 bytes {2} [built] - [4] (webpack)/test/statsCases/preset-normal-performance-ensure-filter-sourcemaps/e.js 22 bytes {2} [built] -chunk {3} main.js, main.js.map (main) 300 kB [entry] [rendered] - [0] (webpack)/test/statsCases/preset-normal-performance-ensure-filter-sourcemaps/a.js 300 kB {3} [built] - [5] (webpack)/test/statsCases/preset-normal-performance-ensure-filter-sourcemaps/index.js 52 bytes {3} [built] + [0] (webpack)/test/statsCases/preset-normal-performance-ensure-filter-sourcemaps/index.js 52 bytes {3} [built] + [1] (webpack)/test/statsCases/preset-normal-performance-ensure-filter-sourcemaps/a.js 300 kB {3} [built] + [2] (webpack)/test/statsCases/preset-normal-performance-ensure-filter-sourcemaps/b.js 22 bytes {1} [built] + [3] (webpack)/test/statsCases/preset-normal-performance-ensure-filter-sourcemaps/c.js 54 bytes {0} [built] + [4] (webpack)/test/statsCases/preset-normal-performance-ensure-filter-sourcemaps/d.js 22 bytes {2} [built] + [5] (webpack)/test/statsCases/preset-normal-performance-ensure-filter-sourcemaps/e.js 22 bytes {2} [built] WARNING in asset size limit: The following asset(s) exceed the recommended size limit (250 kB). This can impact web performance. diff --git a/test/statsCases/preset-normal-performance/expected.txt b/test/statsCases/preset-normal-performance/expected.txt index 044000957..b7d797ecb 100644 --- a/test/statsCases/preset-normal-performance/expected.txt +++ b/test/statsCases/preset-normal-performance/expected.txt @@ -1,19 +1,15 @@ Time: Xms Asset Size Chunks Chunk Names 0.js 238 bytes 0 [emitted] - 1.js 108 bytes 1 [emitted] - 2.js 204 bytes 2 [emitted] + 1.js 102 bytes 1 [emitted] + 2.js 182 bytes 2 [emitted] main.js 306 kB 3 [emitted] [big] main -chunk {0} 0.js 54 bytes {3} [rendered] - [2] (webpack)/test/statsCases/preset-normal-performance/c.js 54 bytes {0} [built] -chunk {1} 1.js 22 bytes {3} [rendered] - [1] (webpack)/test/statsCases/preset-normal-performance/b.js 22 bytes {1} [built] -chunk {2} 2.js 44 bytes {0} [rendered] - [3] (webpack)/test/statsCases/preset-normal-performance/d.js 22 bytes {2} [built] - [4] (webpack)/test/statsCases/preset-normal-performance/e.js 22 bytes {2} [built] -chunk {3} main.js (main) 300 kB [entry] [rendered] - [0] (webpack)/test/statsCases/preset-normal-performance/a.js 300 kB {3} [built] - [5] (webpack)/test/statsCases/preset-normal-performance/index.js 52 bytes {3} [built] + [0] (webpack)/test/statsCases/preset-normal-performance/index.js 52 bytes {3} [built] + [1] (webpack)/test/statsCases/preset-normal-performance/a.js 300 kB {3} [built] + [2] (webpack)/test/statsCases/preset-normal-performance/b.js 22 bytes {1} [built] + [3] (webpack)/test/statsCases/preset-normal-performance/c.js 54 bytes {0} [built] + [4] (webpack)/test/statsCases/preset-normal-performance/d.js 22 bytes {2} [built] + [5] (webpack)/test/statsCases/preset-normal-performance/e.js 22 bytes {2} [built] WARNING in asset size limit: The following asset(s) exceed the recommended size limit (250 kB). This can impact web performance. diff --git a/test/statsCases/preset-normal/expected.txt b/test/statsCases/preset-normal/expected.txt index a10567f8b..80a51e555 100644 --- a/test/statsCases/preset-normal/expected.txt +++ b/test/statsCases/preset-normal/expected.txt @@ -1,6 +1,13 @@ -Hash: c5a6856b43905ae12f17 +Hash: fd034b07589b0d56afb3 Time: Xms -chunk {0} 0.js 54 bytes {3} [rendered] -chunk {1} 1.js 22 bytes {3} [rendered] -chunk {2} 2.js 44 bytes {0} [rendered] -chunk {3} main.js (main) 73 bytes [entry] [rendered] \ No newline at end of file + Asset Size Chunks Chunk Names + 0.js 238 bytes 0 [emitted] + 1.js 102 bytes 1 [emitted] + 2.js 182 bytes 2 [emitted] +main.js 6.1 kB 3 [emitted] main + [0] (webpack)/test/statsCases/preset-normal/index.js 51 bytes {3} [built] + [1] (webpack)/test/statsCases/preset-normal/a.js 22 bytes {3} [built] + [2] (webpack)/test/statsCases/preset-normal/b.js 22 bytes {1} [built] + [3] (webpack)/test/statsCases/preset-normal/c.js 54 bytes {0} [built] + [4] (webpack)/test/statsCases/preset-normal/d.js 22 bytes {2} [built] + [5] (webpack)/test/statsCases/preset-normal/e.js 22 bytes {2} [built] \ No newline at end of file diff --git a/test/statsCases/preset-verbose/expected.txt b/test/statsCases/preset-verbose/expected.txt index f53f5e384..686bf3a65 100644 --- a/test/statsCases/preset-verbose/expected.txt +++ b/test/statsCases/preset-verbose/expected.txt @@ -1,29 +1,33 @@ -Hash: c5a6856b43905ae12f17 +Hash: fd034b07589b0d56afb3 Time: Xms Asset Size Chunks Chunk Names 0.js 238 bytes 0 [emitted] - 1.js 108 bytes 1 [emitted] - 2.js 204 bytes 2 [emitted] -main.js 6.26 kB 3 [emitted] main + 1.js 102 bytes 1 [emitted] + 2.js 182 bytes 2 [emitted] +main.js 6.1 kB 3 [emitted] main Entrypoint main = main.js chunk {0} 0.js 54 bytes {3} [rendered] - [2] (webpack)/test/statsCases/preset-verbose/c.js 54 bytes {0} [depth 1] [built] - amd require ./c [5] (webpack)/test/statsCases/preset-verbose/index.js 3:0-16 + > [0] (webpack)/test/statsCases/preset-verbose/index.js 3:0-16 + [3] (webpack)/test/statsCases/preset-verbose/c.js 54 bytes {0} [depth 1] [built] + amd require ./c [0] (webpack)/test/statsCases/preset-verbose/index.js 3:0-16 [] -> factory:Xms building:Xms = Xms chunk {1} 1.js 22 bytes {3} [rendered] - [1] (webpack)/test/statsCases/preset-verbose/b.js 22 bytes {1} [depth 1] [built] - amd require ./b [5] (webpack)/test/statsCases/preset-verbose/index.js 2:0-16 + > [0] (webpack)/test/statsCases/preset-verbose/index.js 2:0-16 + [2] (webpack)/test/statsCases/preset-verbose/b.js 22 bytes {1} [depth 1] [built] + amd require ./b [0] (webpack)/test/statsCases/preset-verbose/index.js 2:0-16 [] -> factory:Xms building:Xms = Xms chunk {2} 2.js 44 bytes {0} [rendered] - [3] (webpack)/test/statsCases/preset-verbose/d.js 22 bytes {2} [depth 2] [built] - require.ensure item ./d [2] (webpack)/test/statsCases/preset-verbose/c.js 1:0-52 + > [3] (webpack)/test/statsCases/preset-verbose/c.js 1:0-52 + [4] (webpack)/test/statsCases/preset-verbose/d.js 22 bytes {2} [depth 2] [built] + require.ensure item ./d [3] (webpack)/test/statsCases/preset-verbose/c.js 1:0-52 [] -> factory:Xms building:Xms = Xms - [4] (webpack)/test/statsCases/preset-verbose/e.js 22 bytes {2} [depth 2] [built] - require.ensure item ./e [2] (webpack)/test/statsCases/preset-verbose/c.js 1:0-52 + [5] (webpack)/test/statsCases/preset-verbose/e.js 22 bytes {2} [depth 2] [built] + require.ensure item ./e [3] (webpack)/test/statsCases/preset-verbose/c.js 1:0-52 [] -> factory:Xms building:Xms = Xms chunk {3} main.js (main) 73 bytes [entry] [rendered] - [0] (webpack)/test/statsCases/preset-verbose/a.js 22 bytes {3} [depth 1] [built] - cjs require ./a [5] (webpack)/test/statsCases/preset-verbose/index.js 1:0-14 - [] -> factory:Xms building:Xms = Xms - [5] (webpack)/test/statsCases/preset-verbose/index.js 51 bytes {3} [depth 0] [built] - factory:Xms building:Xms = Xms \ No newline at end of file + > main [0] (webpack)/test/statsCases/preset-verbose/index.js + [0] (webpack)/test/statsCases/preset-verbose/index.js 51 bytes {3} [depth 0] [built] + factory:Xms building:Xms = Xms + [1] (webpack)/test/statsCases/preset-verbose/a.js 22 bytes {3} [depth 1] [built] + cjs require ./a [0] (webpack)/test/statsCases/preset-verbose/index.js 1:0-14 + [] -> factory:Xms building:Xms = Xms \ No newline at end of file diff --git a/test/statsCases/resolve-plugin-context/expected.txt b/test/statsCases/resolve-plugin-context/expected.txt index fdf773037..033a761bd 100644 --- a/test/statsCases/resolve-plugin-context/expected.txt +++ b/test/statsCases/resolve-plugin-context/expected.txt @@ -1,10 +1,9 @@ Hash: 94e1d97f3e1cf37e753f Time: Xms Asset Size Chunks Chunk Names -bundle.js 3.04 kB 0 [emitted] main -chunk {0} bundle.js (main) 80 bytes [entry] [rendered] - [0] (webpack)/test/statsCases/resolve-plugin-context/~/xyz/index.js 0 bytes {0} [built] +bundle.js 2.88 kB 0 [emitted] main + [0] (webpack)/test/statsCases/resolve-plugin-context/node_modules/xyz/index.js 0 bytes {0} [built] [1] (webpack)/test/statsCases/resolve-plugin-context/index.js 48 bytes {0} [built] - [2] (webpack)/test/statsCases/resolve-plugin-context/~/abc/index.js 16 bytes {0} [built] - [3] (webpack)/test/statsCases/resolve-plugin-context/~/def/index.js 16 bytes {0} [built] - [4] (webpack)/test/statsCases/resolve-plugin-context/~/def/~/xyz/index.js 0 bytes {0} [built] \ No newline at end of file + [2] (webpack)/test/statsCases/resolve-plugin-context/node_modules/abc/index.js 16 bytes {0} [built] + [3] (webpack)/test/statsCases/resolve-plugin-context/node_modules/def/index.js 16 bytes {0} [built] + [4] (webpack)/test/statsCases/resolve-plugin-context/node_modules/def/node_modules/xyz/index.js 0 bytes {0} [built] \ No newline at end of file diff --git a/test/statsCases/reverse-sort-modules/expected.txt b/test/statsCases/reverse-sort-modules/expected.txt index bf4a49031..7ce77ddc3 100644 --- a/test/statsCases/reverse-sort-modules/expected.txt +++ b/test/statsCases/reverse-sort-modules/expected.txt @@ -1,26 +1,25 @@ -Hash: 8f4b66734cb63e0581be +Hash: b70eb677e8a8b3694c25 Time: Xms Asset Size Chunks Chunk Names -main.js 5.95 kB 0 [emitted] main -chunk {0} main.js (main) 1.18 kB [entry] [rendered] - [30] (webpack)/test/statsCases/reverse-sort-modules/index.js 181 bytes {0} [built] - [28] (webpack)/test/statsCases/reverse-sort-modules/c.js?8 33 bytes {0} [built] - [27] (webpack)/test/statsCases/reverse-sort-modules/c.js?7 33 bytes {0} [built] - [26] (webpack)/test/statsCases/reverse-sort-modules/c.js?6 33 bytes {0} [built] - [25] (webpack)/test/statsCases/reverse-sort-modules/c.js?5 33 bytes {0} [built] - [24] (webpack)/test/statsCases/reverse-sort-modules/c.js?4 33 bytes {0} [built] - [23] (webpack)/test/statsCases/reverse-sort-modules/c.js?3 33 bytes {0} [built] - [22] (webpack)/test/statsCases/reverse-sort-modules/c.js?2 33 bytes {0} [built] - [21] (webpack)/test/statsCases/reverse-sort-modules/c.js?10 33 bytes {0} [built] - [20] (webpack)/test/statsCases/reverse-sort-modules/c.js?1 33 bytes {0} [built] - [9] (webpack)/test/statsCases/reverse-sort-modules/a.js?9 33 bytes {0} [built] - [8] (webpack)/test/statsCases/reverse-sort-modules/a.js?8 33 bytes {0} [built] - [7] (webpack)/test/statsCases/reverse-sort-modules/a.js?7 33 bytes {0} [built] - [6] (webpack)/test/statsCases/reverse-sort-modules/a.js?6 33 bytes {0} [built] - [5] (webpack)/test/statsCases/reverse-sort-modules/a.js?5 33 bytes {0} [built] - [4] (webpack)/test/statsCases/reverse-sort-modules/a.js?4 33 bytes {0} [built] - [3] (webpack)/test/statsCases/reverse-sort-modules/a.js?3 33 bytes {0} [built] - [2] (webpack)/test/statsCases/reverse-sort-modules/a.js?2 33 bytes {0} [built] - [1] (webpack)/test/statsCases/reverse-sort-modules/a.js?10 33 bytes {0} [built] - [0] (webpack)/test/statsCases/reverse-sort-modules/a.js?1 33 bytes {0} [built] - + 11 hidden modules \ No newline at end of file +main.js 5.79 kB 0 [emitted] main + [29] (webpack)/test/statsCases/reverse-sort-modules/c.js?10 33 bytes {0} [built] + [27] (webpack)/test/statsCases/reverse-sort-modules/c.js?9 33 bytes {0} [built] + [25] (webpack)/test/statsCases/reverse-sort-modules/c.js?8 33 bytes {0} [built] + [23] (webpack)/test/statsCases/reverse-sort-modules/c.js?7 33 bytes {0} [built] + [19] (webpack)/test/statsCases/reverse-sort-modules/c.js?5 33 bytes {0} [built] + [17] (webpack)/test/statsCases/reverse-sort-modules/c.js?4 33 bytes {0} [built] + [15] (webpack)/test/statsCases/reverse-sort-modules/c.js?3 33 bytes {0} [built] + [13] (webpack)/test/statsCases/reverse-sort-modules/c.js?2 33 bytes {0} [built] + [11] (webpack)/test/statsCases/reverse-sort-modules/c.js?1 33 bytes {0} [built] + [10] (webpack)/test/statsCases/reverse-sort-modules/index.js 181 bytes {0} [built] + [9] (webpack)/test/statsCases/reverse-sort-modules/a.js?10 33 bytes {0} [built] + [8] (webpack)/test/statsCases/reverse-sort-modules/a.js?9 33 bytes {0} [built] + [7] (webpack)/test/statsCases/reverse-sort-modules/a.js?8 33 bytes {0} [built] + [6] (webpack)/test/statsCases/reverse-sort-modules/a.js?7 33 bytes {0} [built] + [5] (webpack)/test/statsCases/reverse-sort-modules/a.js?6 33 bytes {0} [built] + [4] (webpack)/test/statsCases/reverse-sort-modules/a.js?5 33 bytes {0} [built] + [3] (webpack)/test/statsCases/reverse-sort-modules/a.js?4 33 bytes {0} [built] + [2] (webpack)/test/statsCases/reverse-sort-modules/a.js?3 33 bytes {0} [built] + [1] (webpack)/test/statsCases/reverse-sort-modules/a.js?2 33 bytes {0} [built] + [0] (webpack)/test/statsCases/reverse-sort-modules/a.js?1 33 bytes {0} [built] + + 11 hidden modules \ No newline at end of file diff --git a/test/statsCases/separate-css-bundle/expected.txt b/test/statsCases/separate-css-bundle/expected.txt index 5cb419e5c..3afb3b42d 100644 --- a/test/statsCases/separate-css-bundle/expected.txt +++ b/test/statsCases/separate-css-bundle/expected.txt @@ -1,27 +1,31 @@ -Hash: 0be4035986816982617a1139e89514abc13454ce +Hash: a3f5cb0c4f2d75d79214074bc8c917dae9eb215a Child - Hash: 0be4035986816982617a + Hash: a3f5cb0c4f2d75d79214 Time: Xms Asset Size Chunks Chunk Names - c7ab11336573e45dc51e.js 2.78 kB 0 [emitted] main + 5a21b890f95ec575ba49.js 2.62 kB 0 [emitted] main c815cf440254d4f3bba4e7041db00a28.css 26 bytes 0 [emitted] main - chunk {0} c7ab11336573e45dc51e.js, c815cf440254d4f3bba4e7041db00a28.css (main) 64 bytes [entry] [rendered] - [0] (webpack)/test/statsCases/separate-css-bundle/a/file.css 41 bytes {0} [built] - [1] (webpack)/test/statsCases/separate-css-bundle/a/index.js 23 bytes {0} [built] + [0] (webpack)/test/statsCases/separate-css-bundle/a/index.js 23 bytes {0} [built] + [1] (webpack)/test/statsCases/separate-css-bundle/a/file.css 41 bytes {0} [built] + [2] (webpack)/node_modules/css-loader!(webpack)/test/statsCases/separate-css-bundle/a/file.css 199 bytes [built] + [3] (webpack)/node_modules/css-loader/lib/css-base.js 2.26 kB [built] + [4] (webpack)/node_modules/style-loader/lib/addStyles.js 8.66 kB [built] + [5] (webpack)/node_modules/style-loader/lib/urls.js 3.01 kB [built] Child extract-text-webpack-plugin: - chunk {0} extract-text-webpack-plugin-output-filename 1.65 kB [entry] [rendered] - [0] (webpack)/~/css-loader!(webpack)/test/statsCases/separate-css-bundle/a/file.css 190 bytes {0} [built] - [1] (webpack)/~/css-loader/lib/css-base.js 1.46 kB {0} [built] + [0] (webpack)/node_modules/css-loader!(webpack)/test/statsCases/separate-css-bundle/a/file.css 199 bytes {0} [built] + [1] (webpack)/node_modules/css-loader/lib/css-base.js 2.26 kB {0} [built] Child - Hash: 1139e89514abc13454ce + Hash: 074bc8c917dae9eb215a Time: Xms Asset Size Chunks Chunk Names - c7ab11336573e45dc51e.js 2.78 kB 0 [emitted] main + 5a21b890f95ec575ba49.js 2.62 kB 0 [emitted] main a3f385680aef7a9bb2a517699532cc34.css 28 bytes 0 [emitted] main - chunk {0} c7ab11336573e45dc51e.js, a3f385680aef7a9bb2a517699532cc34.css (main) 64 bytes [entry] [rendered] - [0] (webpack)/test/statsCases/separate-css-bundle/b/file.css 41 bytes {0} [built] - [1] (webpack)/test/statsCases/separate-css-bundle/b/index.js 23 bytes {0} [built] + [0] (webpack)/test/statsCases/separate-css-bundle/b/index.js 23 bytes {0} [built] + [1] (webpack)/test/statsCases/separate-css-bundle/b/file.css 41 bytes {0} [built] + [2] (webpack)/node_modules/css-loader!(webpack)/test/statsCases/separate-css-bundle/b/file.css 201 bytes [built] + [3] (webpack)/node_modules/css-loader/lib/css-base.js 2.26 kB [built] + [4] (webpack)/node_modules/style-loader/lib/addStyles.js 8.66 kB [built] + [5] (webpack)/node_modules/style-loader/lib/urls.js 3.01 kB [built] Child extract-text-webpack-plugin: - chunk {0} extract-text-webpack-plugin-output-filename 1.65 kB [entry] [rendered] - [0] (webpack)/~/css-loader!(webpack)/test/statsCases/separate-css-bundle/b/file.css 192 bytes {0} [built] - [1] (webpack)/~/css-loader/lib/css-base.js 1.46 kB {0} [built] \ No newline at end of file + [0] (webpack)/node_modules/css-loader!(webpack)/test/statsCases/separate-css-bundle/b/file.css 201 bytes {0} [built] + [1] (webpack)/node_modules/css-loader/lib/css-base.js 2.26 kB {0} [built] \ No newline at end of file diff --git a/test/statsCases/simple-more-info/expected.txt b/test/statsCases/simple-more-info/expected.txt index 2058e7a0d..ecf254996 100644 --- a/test/statsCases/simple-more-info/expected.txt +++ b/test/statsCases/simple-more-info/expected.txt @@ -1,10 +1,6 @@ Hash: 0bd4f09244f0e8c60354 Time: Xms Asset Size Chunks Chunk Names -bundle.js 2.63 kB 0 [emitted] main -chunk {0} bundle.js (main) 0 bytes [entry] [rendered] - > main [0] (webpack)/test/statsCases/simple-more-info/index.js - [0] (webpack)/test/statsCases/simple-more-info/index.js 0 bytes {0} [built] - factory:Xms building:Xms = Xms +bundle.js 2.47 kB 0 [emitted] main [0] (webpack)/test/statsCases/simple-more-info/index.js 0 bytes {0} [built] factory:Xms building:Xms = Xms \ No newline at end of file diff --git a/test/statsCases/simple/expected.txt b/test/statsCases/simple/expected.txt index 71893b161..4974e2530 100644 --- a/test/statsCases/simple/expected.txt +++ b/test/statsCases/simple/expected.txt @@ -1,6 +1,5 @@ Hash: 0bd4f09244f0e8c60354 Time: Xms Asset Size Chunks Chunk Names -bundle.js 2.63 kB 0 [emitted] main -chunk {0} bundle.js (main) 0 bytes [entry] [rendered] - [0] (webpack)/test/statsCases/simple/index.js 0 bytes {0} [built] \ No newline at end of file +bundle.js 2.47 kB 0 [emitted] main + [0] (webpack)/test/statsCases/simple/index.js 0 bytes {0} [built] \ No newline at end of file diff --git a/test/statsCases/tree-shaking/expected.txt b/test/statsCases/tree-shaking/expected.txt index a6b3bed4a..6459b0ac8 100644 --- a/test/statsCases/tree-shaking/expected.txt +++ b/test/statsCases/tree-shaking/expected.txt @@ -1,8 +1,7 @@ -Hash: 347e6d2384c1a580ac4d +Hash: d655480cef20a0a12dff Time: Xms Asset Size Chunks Chunk Names -bundle.js 7.49 kB 0 [emitted] main -chunk {0} bundle.js (main) 588 bytes [entry] [rendered] +bundle.js 7.33 kB 0 [emitted] main [0] (webpack)/test/statsCases/tree-shaking/a.js 13 bytes {0} [built] [exports: a] [only some exports used: a] @@ -11,19 +10,19 @@ chunk {0} bundle.js (main) 588 bytes [entry] [rendered] [only some exports used: ] [2] (webpack)/test/statsCases/tree-shaking/unknown.js 0 bytes {0} [built] [only some exports used: c] - [3] (webpack)/test/statsCases/tree-shaking/edge.js 45 bytes {0} [built] - [only some exports used: y] - [4] (webpack)/test/statsCases/tree-shaking/index.js 276 bytes {0} [built] - [5] (webpack)/test/statsCases/tree-shaking/reexport-known.js 49 bytes {0} [built] + [3] (webpack)/test/statsCases/tree-shaking/index.js 276 bytes {0} [built] + [4] (webpack)/test/statsCases/tree-shaking/reexport-known.js 49 bytes {0} [built] [exports: a, b] [only some exports used: a] + [5] (webpack)/test/statsCases/tree-shaking/reexport-unknown.js 83 bytes {0} [built] + [exports: a, b, c, d] + [only some exports used: a, c] [6] (webpack)/test/statsCases/tree-shaking/reexport-star-known.js 41 bytes {0} [built] [exports: a, b] [only some exports used: a] [7] (webpack)/test/statsCases/tree-shaking/reexport-star-unknown.js 68 bytes {0} [built] [only some exports used: a, c] - [8] (webpack)/test/statsCases/tree-shaking/reexport-unknown.js 83 bytes {0} [built] - [exports: a, b, c, d] - [only some exports used: a, c] + [8] (webpack)/test/statsCases/tree-shaking/edge.js 45 bytes {0} [built] + [only some exports used: y] [9] (webpack)/test/statsCases/tree-shaking/unknown2.js 0 bytes {0} [built] [only some exports used: y] \ No newline at end of file diff --git a/test/statsCases/warnings-uglifyjs/expected.txt b/test/statsCases/warnings-uglifyjs/expected.txt index edc03af90..1e79500ce 100644 --- a/test/statsCases/warnings-uglifyjs/expected.txt +++ b/test/statsCases/warnings-uglifyjs/expected.txt @@ -1,11 +1,10 @@ -Hash: 4beee256fa6b8f69eae8 +Hash: 2c9851f0ea4c9778e64a Time: Xms - Asset Size Chunks Chunk Names -bundle.js 2.17 kB 0 [emitted] main -chunk {0} bundle.js (main) 1.04 kB [entry] [rendered] - [0] (webpack)/buildin/module.js 495 bytes {0} [built] + Asset Size Chunks Chunk Names +bundle.js 2.1 kB 0 [emitted] main + [0] (webpack)/test/statsCases/warnings-uglifyjs/index.js 299 bytes {0} [built] [1] (webpack)/test/statsCases/warnings-uglifyjs/a.js 249 bytes {0} [built] - [2] (webpack)/test/statsCases/warnings-uglifyjs/index.js 299 bytes {0} [built] + [2] (webpack)/buildin/module.js 495 bytes {0} [built] WARNING in bundle.js from UglifyJs Dropping unused function someUnRemoteUsedFunction1 [./a.js:3,0] diff --git a/yarn.lock b/yarn.lock index c3ad70e0c..4b530d5a5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -73,7 +73,7 @@ ajv@^4.11.2, ajv@^4.7.0, ajv@^4.9.1: co "^4.6.0" json-stable-stringify "^1.0.1" -ajv@^5.1.5: +ajv@^5.0.0, ajv@^5.1.5: version "5.1.5" resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.1.5.tgz#8734931b601f00d4feef7c65738d77d1b65d1f68" dependencies: @@ -586,6 +586,10 @@ clone@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.2.tgz#260b7a99ebb1edfe247538175f783243cb19d149" +clone@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.1.tgz#d217d1e961118e3ac9a4b8bba3285553bf647cdb" + co@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" @@ -828,35 +832,28 @@ css-color-names@0.0.4: version "0.0.4" resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0" -css-loader@~0.25.0: - version "0.25.0" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-0.25.0.tgz#c3febc8ce28f4c83576b6b13707f47f90c390223" +css-loader@^0.28.3: + version "0.28.3" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-0.28.3.tgz#9fd5e0b8c405b6df927ba1103887015d360640ce" dependencies: babel-code-frame "^6.11.0" - css-selector-tokenizer "^0.6.0" + css-selector-tokenizer "^0.7.0" cssnano ">=2.6.1 <4" - loader-utils "~0.2.2" - lodash.camelcase "^3.0.1" + loader-utils "^1.0.2" + lodash.camelcase "^4.3.0" object-assign "^4.0.1" postcss "^5.0.6" postcss-modules-extract-imports "^1.0.0" postcss-modules-local-by-default "^1.0.1" postcss-modules-scope "^1.0.0" postcss-modules-values "^1.1.0" - source-list-map "^0.1.4" + postcss-value-parser "^3.3.0" + source-list-map "^0.1.7" css-parse@1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/css-parse/-/css-parse-1.0.4.tgz#38b0503fbf9da9f54e9c1dbda60e145c77117bdd" -css-selector-tokenizer@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/css-selector-tokenizer/-/css-selector-tokenizer-0.6.0.tgz#6445f582c7930d241dcc5007a43d6fcb8f073152" - dependencies: - cssesc "^0.1.0" - fastparse "^1.1.1" - regexpu-core "^1.0.0" - css-selector-tokenizer@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/css-selector-tokenizer/-/css-selector-tokenizer-0.7.0.tgz#e6988474ae8c953477bf5e7efecfceccd9cf4c86" @@ -1417,11 +1414,11 @@ file-entry-cache@^2.0.0: flat-cache "^1.2.1" object-assign "^4.0.1" -file-loader@~0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-0.9.0.tgz#1d2daddd424ce6d1b07cfe3f79731bed3617ab42" +file-loader@^0.11.1: + version "0.11.1" + resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-0.11.1.tgz#6b328ee1234a729e4e47d36375dd6d35c0e1db84" dependencies: - loader-utils "~0.2.5" + loader-utils "^1.0.2" filename-regex@^2.0.0: version "2.0.1" @@ -2218,11 +2215,13 @@ lcov-parse@0.0.10, lcov-parse@0.x: version "0.0.10" resolved "https://registry.yarnpkg.com/lcov-parse/-/lcov-parse-0.0.10.tgz#1b0b8ff9ac9c7889250582b70b71315d9da6d9a3" -less-loader@^2.0.0: - version "2.2.3" - resolved "https://registry.yarnpkg.com/less-loader/-/less-loader-2.2.3.tgz#b6d8f8139c8493df09d992a93a00734b08f84528" +less-loader@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/less-loader/-/less-loader-4.0.3.tgz#d1e6462ca2f090c11248455e14b8dda4616d0521" dependencies: - loader-utils "^0.2.5" + clone "^2.1.1" + loader-utils "^1.1.0" + pify "^2.3.0" less@^2.5.1: version "2.7.2" @@ -2258,7 +2257,15 @@ loader-runner@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.0.tgz#f482aea82d543e07921700d5a46ef26fdac6b8a2" -loader-utils@0.2.x, loader-utils@^0.2.16, loader-utils@^0.2.5, loader-utils@~0.2.2, loader-utils@~0.2.5: +loader-utils@^1.0.2, loader-utils@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.1.0.tgz#c98aef488bcceda2ffb5e2de646d6a754429f5cd" + dependencies: + big.js "^3.1.3" + emojis-list "^2.0.0" + json5 "^0.5.0" + +loader-utils@~0.2.5: version "0.2.17" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.17.tgz#f86e6374d43205a6e6c60e9196f17c0299bfb348" dependencies: @@ -2267,14 +2274,6 @@ loader-utils@0.2.x, loader-utils@^0.2.16, loader-utils@^0.2.5, loader-utils@~0.2 json5 "^0.5.0" object-assign "^4.0.1" -loader-utils@^1.0.2: - version "1.1.0" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.1.0.tgz#c98aef488bcceda2ffb5e2de646d6a754429f5cd" - dependencies: - big.js "^3.1.3" - emojis-list "^2.0.0" - json5 "^0.5.0" - lodash._baseassign@^3.0.0: version "3.2.0" resolved "https://registry.yarnpkg.com/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz#8c38a099500f215ad09e59f1722fd0c52bfe0a4e" @@ -2290,13 +2289,6 @@ lodash._basecreate@^3.0.0: version "3.0.3" resolved "https://registry.yarnpkg.com/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz#1bc661614daa7fc311b7d03bf16806a0213cf821" -lodash._createcompounder@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/lodash._createcompounder/-/lodash._createcompounder-3.0.0.tgz#5dd2cb55372d6e70e0e2392fb2304d6631091075" - dependencies: - lodash.deburr "^3.0.0" - lodash.words "^3.0.0" - lodash._getnative@^3.0.0: version "3.9.1" resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" @@ -2305,15 +2297,9 @@ lodash._isiterateecall@^3.0.0: version "3.0.9" resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c" -lodash._root@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/lodash._root/-/lodash._root-3.0.1.tgz#fba1c4524c19ee9a5f8136b4609f017cf4ded692" - -lodash.camelcase@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-3.0.1.tgz#932c8b87f8a4377897c67197533282f97aeac298" - dependencies: - lodash._createcompounder "^3.0.0" +lodash.camelcase@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" lodash.create@3.1.1: version "3.1.1" @@ -2323,12 +2309,6 @@ lodash.create@3.1.1: lodash._basecreate "^3.0.0" lodash._isiterateecall "^3.0.0" -lodash.deburr@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/lodash.deburr/-/lodash.deburr-3.2.0.tgz#6da8f54334a366a7cf4c4c76ef8d80aa1b365ed5" - dependencies: - lodash._root "^3.0.0" - lodash.isarguments@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" @@ -2353,12 +2333,6 @@ lodash.uniq@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" -lodash.words@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/lodash.words/-/lodash.words-3.2.0.tgz#4e2a8649bc08745b17c695b1a3ce8fee596623b3" - dependencies: - lodash._root "^3.0.0" - lodash@^3.10.0: version "3.10.1" resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6" @@ -2855,7 +2829,7 @@ performance-now@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5" -pify@^2.0.0: +pify@^2.0.0, pify@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" @@ -3569,6 +3543,12 @@ sax@~1.2.1: version "1.2.2" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.2.tgz#fd8631a23bc7826bef5d871bdb87378c95647828" +schema-utils@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.3.0.tgz#f5877222ce3e931edae039f17eb3716e7137f8cf" + dependencies: + ajv "^5.0.0" + script-loader@~0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/script-loader/-/script-loader-0.7.0.tgz#685dc7e7069e0dee7a92674f0ebc5b0f55baa5ec" @@ -3738,13 +3718,13 @@ sort-keys@^1.0.0: dependencies: is-plain-obj "^1.0.0" -source-list-map@^0.1.4, source-list-map@~0.1.7: +source-list-map@^0.1.7, source-list-map@~0.1.7: version "0.1.8" resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-0.1.8.tgz#c550b2ab5427f6b3f21f5afead88c4f5587b2106" -source-list-map@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-1.1.2.tgz#9889019d1024cce55cdc069498337ef6186a11a1" +source-list-map@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.0.tgz#aaa47403f7b245a92fbc97ea08f250d6087ed085" source-map@0.4.x, source-map@^0.4.4: version "0.4.4" @@ -3891,11 +3871,12 @@ strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" -style-loader@~0.13.0: - version "0.13.2" - resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-0.13.2.tgz#74533384cf698c7104c7951150b49717adc2f3bb" +style-loader@^0.18.1: + version "0.18.1" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-0.18.1.tgz#6afca8953c842830e5e2dc84796309880a97f7e8" dependencies: loader-utils "^1.0.2" + schema-utils "^0.3.0" subcommand@^2.0.3: version "2.1.0" @@ -4158,11 +4139,11 @@ uuid@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.0.1.tgz#6544bba2dfda8c1cf17e629a3a305e2bb1fee6c1" -val-loader@~0.5.0: - version "0.5.1" - resolved "https://registry.yarnpkg.com/val-loader/-/val-loader-0.5.1.tgz#a20f9d63e4be036f86f4ee4bdcb2a103b85884e7" +val-loader@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/val-loader/-/val-loader-1.0.2.tgz#7909198093b37cba0a96bf4f6d29de970d099d3d" dependencies: - loader-utils "^1.0.2" + loader-utils "^1.1.0" validate-npm-package-license@^3.0.1: version "3.0.1" @@ -4219,11 +4200,11 @@ webpack-sources@^0.1.0: source-list-map "~0.1.7" source-map "~0.5.3" -webpack-sources@^0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-0.2.3.tgz#17c62bfaf13c707f9d02c479e0dcdde8380697fb" +webpack-sources@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.0.1.tgz#c7356436a4d13123be2e2426a05d1dad9cbe65cf" dependencies: - source-list-map "^1.1.1" + source-list-map "^2.0.0" source-map "~0.5.3" whatwg-fetch@>=0.10.0: @@ -4269,11 +4250,11 @@ wordwrap@^1.0.0, wordwrap@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" -worker-loader@~0.7.0: - version "0.7.1" - resolved "https://registry.yarnpkg.com/worker-loader/-/worker-loader-0.7.1.tgz#91ffd2e2fbf76921a43e8ca3766d12e9537f5d70" +worker-loader@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/worker-loader/-/worker-loader-0.8.0.tgz#13582960dcd7d700dc829d3fd252a7561696167e" dependencies: - loader-utils "0.2.x" + loader-utils "^1.0.2" wrap-ansi@^2.0.0: version "2.1.0"