From 49bd54313d8a7af185f7cd298b5af9a1d95ce5c5 Mon Sep 17 00:00:00 2001 From: Ronan Amsterdam Date: Sun, 27 May 2018 09:24:01 +0800 Subject: [PATCH 01/36] Issue #7395: webpack import options comments warning propagation --- lib/Parser.js | 35 +++++++++++--- .../valid-invalid-import-comments/chunk1-a.js | 0 .../valid-invalid-import-comments/chunk1-b.js | 0 .../valid-invalid-import-comments/chunk1-c.js | 0 .../valid-invalid-import-comments/chunk1.js | 5 ++ .../valid-invalid-import-comments/index.js | 46 +++++++++++++++++++ .../webpack.config.js | 13 ++++++ 7 files changed, 92 insertions(+), 7 deletions(-) create mode 100644 test/configCases/web/valid-invalid-import-comments/chunk1-a.js create mode 100644 test/configCases/web/valid-invalid-import-comments/chunk1-b.js create mode 100644 test/configCases/web/valid-invalid-import-comments/chunk1-c.js create mode 100644 test/configCases/web/valid-invalid-import-comments/chunk1.js create mode 100644 test/configCases/web/valid-invalid-import-comments/index.js create mode 100644 test/configCases/web/valid-invalid-import-comments/webpack.config.js diff --git a/lib/Parser.js b/lib/Parser.js index de2e9690b04..15b1ec19468 100644 --- a/lib/Parser.js +++ b/lib/Parser.js @@ -31,6 +31,16 @@ const defaultParserOptions = { } }; +const webpackImportCommentOptions = [ + "webpackIgnore", + "webpackChunkName", + "webpackMode", + "webpackPrefetch", + "webpackPreload", + "webpackInclude", + "webpackExclude" +]; + class Parser extends Tapable { constructor(options, sourceType = "auto") { super(); @@ -1983,17 +1993,28 @@ class Parser extends Tapable { } getCommentOptions(range) { + const webpackCommentRegExp = new RegExp( + webpackImportCommentOptions.join("|") + ); + const comments = this.getComments(range); if (comments.length === 0) return null; const options = comments.map(comment => { - try { - let val = vm.runInNewContext( - `(function(){return {${comment.value}};})()` - ); - return val; - } catch (e) { - return {}; + const { value } = comment; + if (value && webpackCommentRegExp.test(value)) { + // try compile only if webpack options comment is present + try { + let val = vm.runInNewContext( + `(function(){return {${comment.value}};})()` + ); + return val; + } catch (e) { + console.warn(e); + return {}; + } } + + return {}; }); return options.reduce((o, i) => Object.assign(o, i), {}); } diff --git a/test/configCases/web/valid-invalid-import-comments/chunk1-a.js b/test/configCases/web/valid-invalid-import-comments/chunk1-a.js new file mode 100644 index 00000000000..e69de29bb2d diff --git a/test/configCases/web/valid-invalid-import-comments/chunk1-b.js b/test/configCases/web/valid-invalid-import-comments/chunk1-b.js new file mode 100644 index 00000000000..e69de29bb2d diff --git a/test/configCases/web/valid-invalid-import-comments/chunk1-c.js b/test/configCases/web/valid-invalid-import-comments/chunk1-c.js new file mode 100644 index 00000000000..e69de29bb2d diff --git a/test/configCases/web/valid-invalid-import-comments/chunk1.js b/test/configCases/web/valid-invalid-import-comments/chunk1.js new file mode 100644 index 00000000000..67b0a62e88a --- /dev/null +++ b/test/configCases/web/valid-invalid-import-comments/chunk1.js @@ -0,0 +1,5 @@ +export default function() { + import(/* webpackPrefetch: true, webpackChunkName: notGoingToCompileChunkName */ "./chunk1-a"); + import(/* webpackPrefetch: 0, webpackChunkName: "goingToCompileChunkName-b" */ "./chunk1-b"); + import(/* webpack Prefetch: 0, webpackChunkName: "notGoingToCompile-c" */ "./chunk1-c"); +} diff --git a/test/configCases/web/valid-invalid-import-comments/index.js b/test/configCases/web/valid-invalid-import-comments/index.js new file mode 100644 index 00000000000..9231f487833 --- /dev/null +++ b/test/configCases/web/valid-invalid-import-comments/index.js @@ -0,0 +1,46 @@ +const FakeDocument = require("../../../helpers/FakeDocument"); + +let oldNonce; +let oldPublicPath; + +beforeEach(() => { + oldNonce = __webpack_nonce__; + oldPublicPath = __webpack_public_path__; + global.document = new FakeDocument(undefined, false); + global.window = {}; +}); + +afterEach(() => { + delete global.document; + delete global.window; + __webpack_nonce__ = oldNonce; + __webpack_public_path__ = oldPublicPath; +}) + +it("should not process invalid webpack import() option comments", (done) => { + __webpack_nonce__ = "nonce"; + __webpack_public_path__ = "/public/path/"; + + const promise = import(/* webpackChunkName: "chunk1" */ "./chunk1"); + expect(document.head._children).toHaveLength(1); + const script = document.head._children[0]; + expect(script._type).toBe("script"); + expect(script.src).toBe("/public/path/chunk1.js") + expect(script.getAttribute("nonce")).toBe("nonce") + expect(script.crossOrigin).toBe("anonymous"); + expect(script.onload).toBeTypeOf("function"); + + __non_webpack_require__("./chunk1.js"); + script.onload(); + return promise.then((ex) => { + // making sure the chunk with valid options is still being loaded + expect(document.head._children).toHaveLength(2); + + let link = document.head._children[1]; + expect(link._type).toBe("link"); + expect(link.rel).toBe("prefetch"); + expect(link.href).toBe("/public/path/goingToCompileChunkName-b.js"); + done(); + }, done); +}) + diff --git a/test/configCases/web/valid-invalid-import-comments/webpack.config.js b/test/configCases/web/valid-invalid-import-comments/webpack.config.js new file mode 100644 index 00000000000..34460c414c7 --- /dev/null +++ b/test/configCases/web/valid-invalid-import-comments/webpack.config.js @@ -0,0 +1,13 @@ +module.exports = { + target: "web", + output: { + chunkFilename: "[name].js", + crossOriginLoading: "anonymous" + }, + performance: { + hints: false + }, + optimization: { + minimize: false + } +}; From 48a8d8534a86aab9d5de8bebca1621453ae71879 Mon Sep 17 00:00:00 2001 From: Ronan Amsterdam Date: Mon, 28 May 2018 15:29:50 +0800 Subject: [PATCH 02/36] webpackCommentRegExp moved outside of getCommentOptions() per review request --- lib/Parser.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/lib/Parser.js b/lib/Parser.js index 15b1ec19468..e590a059973 100644 --- a/lib/Parser.js +++ b/lib/Parser.js @@ -41,6 +41,8 @@ const webpackImportCommentOptions = [ "webpackExclude" ]; +const webpackCommentRegExp = new RegExp(webpackImportCommentOptions.join("|")); + class Parser extends Tapable { constructor(options, sourceType = "auto") { super(); @@ -1993,10 +1995,6 @@ class Parser extends Tapable { } getCommentOptions(range) { - const webpackCommentRegExp = new RegExp( - webpackImportCommentOptions.join("|") - ); - const comments = this.getComments(range); if (comments.length === 0) return null; const options = comments.map(comment => { @@ -2013,7 +2011,6 @@ class Parser extends Tapable { return {}; } } - return {}; }); return options.reduce((o, i) => Object.assign(o, i), {}); From 0e58d54f5d1108e62004fc1397541df41dde774f Mon Sep 17 00:00:00 2001 From: Sven SAULEAU Date: Fri, 25 May 2018 18:05:36 +0200 Subject: [PATCH 03/36] feat: add failing test --- test/cases/wasm/global-refs-imported-global/env.js | 1 + .../wasm/global-refs-imported-global/index.js | 10 ++++++++++ .../wasm/global-refs-imported-global/module.wasm | Bin 0 -> 54 bytes .../global-refs-imported-global/test.filter.js | 5 +++++ 4 files changed, 16 insertions(+) create mode 100644 test/cases/wasm/global-refs-imported-global/env.js create mode 100644 test/cases/wasm/global-refs-imported-global/index.js create mode 100644 test/cases/wasm/global-refs-imported-global/module.wasm create mode 100644 test/cases/wasm/global-refs-imported-global/test.filter.js diff --git a/test/cases/wasm/global-refs-imported-global/env.js b/test/cases/wasm/global-refs-imported-global/env.js new file mode 100644 index 00000000000..3d521168145 --- /dev/null +++ b/test/cases/wasm/global-refs-imported-global/env.js @@ -0,0 +1 @@ +export const n = 33; diff --git a/test/cases/wasm/global-refs-imported-global/index.js b/test/cases/wasm/global-refs-imported-global/index.js new file mode 100644 index 00000000000..81f19fcf13a --- /dev/null +++ b/test/cases/wasm/global-refs-imported-global/index.js @@ -0,0 +1,10 @@ +// (module +// (import "./env.js" "n" (global i32)) +// (global (export "value") i32 (get_global 0)) +// ) + +it("should allow global with imported global as initilizer", function() { + return import("./module.wasm").then(function({value}) { + expect(value).toEqual(33); + }); +}); diff --git a/test/cases/wasm/global-refs-imported-global/module.wasm b/test/cases/wasm/global-refs-imported-global/module.wasm new file mode 100644 index 0000000000000000000000000000000000000000..47c0d24f1ccadc70b6eb9b8f22a1ea58d361df45 GIT binary patch literal 54 zcmZQbEY4+QU|?Y4XXMb+Pt7aS%PMBfW3FdlV`HpmP-fs}=VW9pOUx-vWoBgHV986& JO=V(a000O*37`M~ literal 0 HcmV?d00001 diff --git a/test/cases/wasm/global-refs-imported-global/test.filter.js b/test/cases/wasm/global-refs-imported-global/test.filter.js new file mode 100644 index 00000000000..23177349638 --- /dev/null +++ b/test/cases/wasm/global-refs-imported-global/test.filter.js @@ -0,0 +1,5 @@ +var supportsWebAssembly = require("../../../helpers/supportsWebAssembly"); + +module.exports = function(config) { + return supportsWebAssembly(); +}; From 8f269150dcd3ce8c02b4d3c60dbad121572a8b7d Mon Sep 17 00:00:00 2001 From: Sven SAULEAU Date: Mon, 28 May 2018 11:14:08 +0200 Subject: [PATCH 04/36] feat: switch to wast test --- .../wasm/global-refs-imported-global/index.js | 7 +------ .../wasm/global-refs-imported-global/module.wasm | Bin 54 -> 0 bytes .../wasm/global-refs-imported-global/module.wat | 4 ++++ 3 files changed, 5 insertions(+), 6 deletions(-) delete mode 100644 test/cases/wasm/global-refs-imported-global/module.wasm create mode 100644 test/cases/wasm/global-refs-imported-global/module.wat diff --git a/test/cases/wasm/global-refs-imported-global/index.js b/test/cases/wasm/global-refs-imported-global/index.js index 81f19fcf13a..dd03a23123a 100644 --- a/test/cases/wasm/global-refs-imported-global/index.js +++ b/test/cases/wasm/global-refs-imported-global/index.js @@ -1,10 +1,5 @@ -// (module -// (import "./env.js" "n" (global i32)) -// (global (export "value") i32 (get_global 0)) -// ) - it("should allow global with imported global as initilizer", function() { - return import("./module.wasm").then(function({value}) { + return import("./module.wat").then(function({value}) { expect(value).toEqual(33); }); }); diff --git a/test/cases/wasm/global-refs-imported-global/module.wasm b/test/cases/wasm/global-refs-imported-global/module.wasm deleted file mode 100644 index 47c0d24f1ccadc70b6eb9b8f22a1ea58d361df45..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 54 zcmZQbEY4+QU|?Y4XXMb+Pt7aS%PMBfW3FdlV`HpmP-fs}=VW9pOUx-vWoBgHV986& JO=V(a000O*37`M~ diff --git a/test/cases/wasm/global-refs-imported-global/module.wat b/test/cases/wasm/global-refs-imported-global/module.wat new file mode 100644 index 00000000000..cb6706e49e9 --- /dev/null +++ b/test/cases/wasm/global-refs-imported-global/module.wat @@ -0,0 +1,4 @@ +(module + (import "./env.js" "n" (global i32)) + (global (export "value") i32 (get_global 0)) +) From 974381a3acb0d55665c75cb95b9c897eb5d38028 Mon Sep 17 00:00:00 2001 From: Sven SAULEAU Date: Mon, 28 May 2018 11:25:59 +0200 Subject: [PATCH 05/36] cherry-picked acc45fd806145e1d1f42aa8042a76c79121eaf1f --- package.json | 1 + test/TestCases.template.js | 5 +++++ yarn.lock | 10 ++++++++++ 3 files changed, 16 insertions(+) diff --git a/package.json b/package.json index 6763a7642d4..6882784adb4 100644 --- a/package.json +++ b/package.json @@ -73,6 +73,7 @@ "url-loader": "^0.6.2", "val-loader": "^1.0.2", "vm-browserify": "~0.0.0", + "wast-loader": "^1.5.5", "webpack-dev-middleware": "^1.9.0", "worker-loader": "^1.1.1", "xxhashjs": "^0.2.1" diff --git a/test/TestCases.template.js b/test/TestCases.template.js index 8168b8ee5c4..57dab3269db 100644 --- a/test/TestCases.template.js +++ b/test/TestCases.template.js @@ -143,6 +143,11 @@ const describeCases = config => { { test: /\.pug/, loader: "pug-loader" + }, + { + test: /\.wat$/i, + loader: "wast-loader", + type: "webassembly/experimental" } ] }, diff --git a/yarn.lock b/yarn.lock index 7d8c4f8fc9e..8f5f0d42fc7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6182,12 +6182,22 @@ w3c-hr-time@^1.0.1: dependencies: browser-process-hrtime "^0.1.2" +wabt@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wabt/-/wabt-1.0.0.tgz#f33a5c4a6405370ec80ba97e782d092f1d599ff4" + walker@~1.0.5: version "1.0.7" resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb" dependencies: makeerror "1.0.x" +wast-loader@^1.5.5: + version "1.5.7" + resolved "https://registry.yarnpkg.com/wast-loader/-/wast-loader-1.5.7.tgz#1b165cef7225c70a7e82a50e4f8bf0bc1ec9f2fd" + dependencies: + wabt "^1.0.0" + watch@~0.18.0: version "0.18.0" resolved "https://registry.yarnpkg.com/watch/-/watch-0.18.0.tgz#28095476c6df7c90c963138990c0a5423eb4b986" From 16b7022b2e5b824c094ca39be3eb8ce8a167bfef Mon Sep 17 00:00:00 2001 From: Sven SAULEAU Date: Mon, 28 May 2018 16:55:44 +0200 Subject: [PATCH 06/36] chore: update test --- test/cases/wasm/global-refs-imported-global/index.js | 4 ++-- test/cases/wasm/global-refs-imported-global/module.wat | 7 ++++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/test/cases/wasm/global-refs-imported-global/index.js b/test/cases/wasm/global-refs-imported-global/index.js index dd03a23123a..3cb8ff40e28 100644 --- a/test/cases/wasm/global-refs-imported-global/index.js +++ b/test/cases/wasm/global-refs-imported-global/index.js @@ -1,5 +1,5 @@ it("should allow global with imported global as initilizer", function() { - return import("./module.wat").then(function({value}) { - expect(value).toEqual(33); + return import("./module.wat").then(function({get}) { + expect(get()).toEqual(33); }); }); diff --git a/test/cases/wasm/global-refs-imported-global/module.wat b/test/cases/wasm/global-refs-imported-global/module.wat index cb6706e49e9..eb1ea8c6f6a 100644 --- a/test/cases/wasm/global-refs-imported-global/module.wat +++ b/test/cases/wasm/global-refs-imported-global/module.wat @@ -1,4 +1,9 @@ (module (import "./env.js" "n" (global i32)) - (global (export "value") i32 (get_global 0)) + (global i32 (get_global 0)) + + (func (export "get") (result i32) + (get_global 1) + ) ) + From 38604c3cb03965ed94e9608565234b319f408a8c Mon Sep 17 00:00:00 2001 From: Sven SAULEAU Date: Mon, 28 May 2018 16:56:06 +0200 Subject: [PATCH 07/36] feat: WIP add global into runtime --- lib/wasm/WebAssemblyGenerator.js | 73 +++++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 2 deletions(-) diff --git a/lib/wasm/WebAssemblyGenerator.js b/lib/wasm/WebAssemblyGenerator.js index 7afb2648efd..49b32d85769 100644 --- a/lib/wasm/WebAssemblyGenerator.js +++ b/lib/wasm/WebAssemblyGenerator.js @@ -189,12 +189,20 @@ const rewriteImportedGlobals = state => bin => { newGlobals.push( t.global(globalType, [ - t.objectInstruction("const", "i32", [t.numberLiteralFromRaw(0)]) + // Poisong globals, they are meant to be rewritten + t.objectInstruction("const", "i32", [t.numberLiteralFromRaw(666)]) ]) ); path.remove(); } + }, + + // in order to preserve non-imported global's order we need to re-inject + // those as well + Global(path) { + newGlobals.push(path.node); + path.remove(); } }); @@ -202,6 +210,65 @@ const rewriteImportedGlobals = state => bin => { return addWithAST(state.ast, bin, newGlobals); }; +const rewriteGlobalsReferingImportedGlobals = state => bin => { + const additionalInitCode = []; + + // Track global index in the module + let globalidx = 0; + + bin = editWithAST(state.ast, bin, { + ModuleImport({ node }) { + if (isGlobalImport(node) === true) { + globalidx++; + } + }, + + Global({ node }) { + const [init] = node.init; + + if (init.id === "get_global") { + node.globalType.mutability = "var"; + + const initialGlobalidx = init.args[0]; + + const valtype = node.globalType.valtype; + + node.init = [ + // Poisong globals, they are meant to be rewritten + t.objectInstruction("const", valtype, [t.numberLiteralFromRaw(666)]) + ]; + + additionalInitCode.push( + /** + * get_global in global initilizer only work for imported globals. + * They have the same indices than the init params, so use the + * same index. + */ + t.instruction("get_local", [initialGlobalidx]), + t.instruction("set_global", [t.indexLiteral(globalidx)]) + ); + } + + globalidx++; + } + }); + + // Update the init with our additional runtime code + if (additionalInitCode.length > 0) { + bin = editWithAST(state.ast, bin, { + Func({ node }) { + if (node.name.value === state.initFuncId.value) { + const newBody = [...node.body, ...additionalInitCode]; + + node.body = newBody; + } + } + }); + } + + return bin; +}; + /** * Rewrite the export names * @param {Object} state state @@ -373,7 +440,9 @@ class WebAssemblyGenerator extends Generator { startAtFuncIndex, nextFuncIndex, nextTypeIndex - }) + }), + + rewriteGlobalsReferingImportedGlobals({ ast, initFuncId }) ); const newBin = transform(bin); From 1969485f051654e6e110f83b01c408d27e040899 Mon Sep 17 00:00:00 2001 From: Ronan Amsterdam Date: Tue, 29 May 2018 15:29:23 +0800 Subject: [PATCH 08/36] warning class and propagation added to ImportParserPlugin and invalid-import tests moved to the statsCases --- lib/Parser.js | 9 ++-- lib/dependencies/ImportParserPlugin.js | 30 +++++++++++- .../__snapshots__/StatsTestCases.test.js.snap | 26 +++++++++++ .../valid-invalid-import-comments/chunk1-a.js | 0 .../valid-invalid-import-comments/chunk1-b.js | 0 .../valid-invalid-import-comments/chunk1-c.js | 0 .../valid-invalid-import-comments/index.js | 46 ------------------- .../webpack.config.js | 13 ------ .../chunk-a.js | 1 + .../chunk-b.js | 1 + .../chunk-c.js | 1 + .../chunk.js} | 6 +-- .../index.js | 1 + .../webpack.config.js | 8 ++++ 14 files changed, 74 insertions(+), 68 deletions(-) delete mode 100644 test/configCases/web/valid-invalid-import-comments/chunk1-a.js delete mode 100644 test/configCases/web/valid-invalid-import-comments/chunk1-b.js delete mode 100644 test/configCases/web/valid-invalid-import-comments/chunk1-c.js delete mode 100644 test/configCases/web/valid-invalid-import-comments/index.js delete mode 100644 test/configCases/web/valid-invalid-import-comments/webpack.config.js create mode 100644 test/statsCases/import-with-invalid-options-comments/chunk-a.js create mode 100644 test/statsCases/import-with-invalid-options-comments/chunk-b.js create mode 100644 test/statsCases/import-with-invalid-options-comments/chunk-c.js rename test/{configCases/web/valid-invalid-import-comments/chunk1.js => statsCases/import-with-invalid-options-comments/chunk.js} (69%) create mode 100644 test/statsCases/import-with-invalid-options-comments/index.js create mode 100644 test/statsCases/import-with-invalid-options-comments/webpack.config.js diff --git a/lib/Parser.js b/lib/Parser.js index e590a059973..8f66a8b4464 100644 --- a/lib/Parser.js +++ b/lib/Parser.js @@ -2002,13 +2002,12 @@ class Parser extends Tapable { if (value && webpackCommentRegExp.test(value)) { // try compile only if webpack options comment is present try { - let val = vm.runInNewContext( - `(function(){return {${comment.value}};})()` - ); + const val = vm.runInNewContext(`(function(){return {${value}};})()`); return val; } catch (e) { - console.warn(e); - return {}; + throw Error( + `compilation error while processing: /*${value}*/: ${e.message}` + ); } } return {}; diff --git a/lib/dependencies/ImportParserPlugin.js b/lib/dependencies/ImportParserPlugin.js index 40daaf66e02..148a1ce28e5 100644 --- a/lib/dependencies/ImportParserPlugin.js +++ b/lib/dependencies/ImportParserPlugin.js @@ -10,6 +10,7 @@ const ImportDependenciesBlock = require("./ImportDependenciesBlock"); const ImportEagerDependency = require("./ImportEagerDependency"); const ContextDependencyHelpers = require("./ContextDependencyHelpers"); const UnsupportedFeatureWarning = require("../UnsupportedFeatureWarning"); +const WebpackError = require("../WebpackError"); class ImportParserPlugin { constructor(options) { @@ -29,9 +30,21 @@ class ImportParserPlugin { let mode = "lazy"; let include = null; let exclude = null; + let importOptions = null; const groupOptions = {}; - const importOptions = parser.getCommentOptions(expr.range); + try { + importOptions = parser.getCommentOptions(expr.range); + } catch (e) { + parser.state.module.warnings.push( + new ImportOptionsCompileWarning( + e.message, + parser.state.module, + expr.loc + ) + ); + } + if (importOptions) { if (typeof importOptions.webpackIgnore !== "undefined") { if (typeof importOptions.webpackIgnore !== "boolean") { @@ -229,4 +242,19 @@ class ImportParserPlugin { }); } } + +class ImportOptionsCompileWarning extends WebpackError { + constructor(message, module, loc) { + super(); + + this.name = "ImportOptionsCompileWarning"; + this.message = message; + + this.origin = this.module = module; + this.originLoc = loc; + + Error.captureStackTrace(this, this.constructor); + } +} + module.exports = ImportParserPlugin; diff --git a/test/__snapshots__/StatsTestCases.test.js.snap b/test/__snapshots__/StatsTestCases.test.js.snap index 6d359b7f07c..1f328b6aa30 100644 --- a/test/__snapshots__/StatsTestCases.test.js.snap +++ b/test/__snapshots__/StatsTestCases.test.js.snap @@ -1007,6 +1007,32 @@ Entrypoint entry = entry.js [2] ./modules/a.js 37 bytes [built]" `; +exports[`StatsTestCases should print correct stats for import-with-invalid-options-comments 1`] = ` +"Hash: 3933c30f2b0ad856b9f3 +Time: Xms +Built at: Thu Jan 01 1970 00:00:00 GMT + Asset Size Chunks Chunk Names + chunk.js 1.16 KiB 0 [emitted] chunk + main.js 7.85 KiB 1 [emitted] main + 2.js 154 bytes 2 [emitted] +goingToCompileChunkName-b.js 163 bytes 3 [emitted] goingToCompileChunkName-b + 4.js 157 bytes 4 [emitted] +Entrypoint main = main.js +[0] ./chunk-a.js 27 bytes {2} [built] +[1] ./chunk-b.js 27 bytes {3} [built] +[2] ./chunk-c.js 27 bytes {4} [built] +[3] ./chunk.js 318 bytes {0} [built] [2 warnings] +[4] ./index.js 50 bytes {1} [built] + +WARNING in ./chunk.js +compilation error while processing: /* webpack Prefetch: 0, webpackChunkName: \\"notGoingToCompile-c\\" */: Unexpected identifier + @ ./index.js 4:4-90 1:0-49 + +WARNING in ./chunk.js +compilation error while processing: /* webpackPrefetch: true, webpackChunkName: notGoingToCompileChunkName */: notGoingToCompileChunkName is not defined + @ ./index.js 2:4-97 1:0-49" +`; + exports[`StatsTestCases should print correct stats for limit-chunk-count-plugin 1`] = ` "Hash: 3c127dca42ce1c13b8eae6c0ceac1aa3be512946a5969fc94d792cce5364503bf42779f704747e2d Child 1 chunks: diff --git a/test/configCases/web/valid-invalid-import-comments/chunk1-a.js b/test/configCases/web/valid-invalid-import-comments/chunk1-a.js deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/test/configCases/web/valid-invalid-import-comments/chunk1-b.js b/test/configCases/web/valid-invalid-import-comments/chunk1-b.js deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/test/configCases/web/valid-invalid-import-comments/chunk1-c.js b/test/configCases/web/valid-invalid-import-comments/chunk1-c.js deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/test/configCases/web/valid-invalid-import-comments/index.js b/test/configCases/web/valid-invalid-import-comments/index.js deleted file mode 100644 index 9231f487833..00000000000 --- a/test/configCases/web/valid-invalid-import-comments/index.js +++ /dev/null @@ -1,46 +0,0 @@ -const FakeDocument = require("../../../helpers/FakeDocument"); - -let oldNonce; -let oldPublicPath; - -beforeEach(() => { - oldNonce = __webpack_nonce__; - oldPublicPath = __webpack_public_path__; - global.document = new FakeDocument(undefined, false); - global.window = {}; -}); - -afterEach(() => { - delete global.document; - delete global.window; - __webpack_nonce__ = oldNonce; - __webpack_public_path__ = oldPublicPath; -}) - -it("should not process invalid webpack import() option comments", (done) => { - __webpack_nonce__ = "nonce"; - __webpack_public_path__ = "/public/path/"; - - const promise = import(/* webpackChunkName: "chunk1" */ "./chunk1"); - expect(document.head._children).toHaveLength(1); - const script = document.head._children[0]; - expect(script._type).toBe("script"); - expect(script.src).toBe("/public/path/chunk1.js") - expect(script.getAttribute("nonce")).toBe("nonce") - expect(script.crossOrigin).toBe("anonymous"); - expect(script.onload).toBeTypeOf("function"); - - __non_webpack_require__("./chunk1.js"); - script.onload(); - return promise.then((ex) => { - // making sure the chunk with valid options is still being loaded - expect(document.head._children).toHaveLength(2); - - let link = document.head._children[1]; - expect(link._type).toBe("link"); - expect(link.rel).toBe("prefetch"); - expect(link.href).toBe("/public/path/goingToCompileChunkName-b.js"); - done(); - }, done); -}) - diff --git a/test/configCases/web/valid-invalid-import-comments/webpack.config.js b/test/configCases/web/valid-invalid-import-comments/webpack.config.js deleted file mode 100644 index 34460c414c7..00000000000 --- a/test/configCases/web/valid-invalid-import-comments/webpack.config.js +++ /dev/null @@ -1,13 +0,0 @@ -module.exports = { - target: "web", - output: { - chunkFilename: "[name].js", - crossOriginLoading: "anonymous" - }, - performance: { - hints: false - }, - optimization: { - minimize: false - } -}; diff --git a/test/statsCases/import-with-invalid-options-comments/chunk-a.js b/test/statsCases/import-with-invalid-options-comments/chunk-a.js new file mode 100644 index 00000000000..760a62d9dfe --- /dev/null +++ b/test/statsCases/import-with-invalid-options-comments/chunk-a.js @@ -0,0 +1 @@ +module.exports = "chunk-a"; \ No newline at end of file diff --git a/test/statsCases/import-with-invalid-options-comments/chunk-b.js b/test/statsCases/import-with-invalid-options-comments/chunk-b.js new file mode 100644 index 00000000000..71dcca37235 --- /dev/null +++ b/test/statsCases/import-with-invalid-options-comments/chunk-b.js @@ -0,0 +1 @@ +module.exports = "chunk-b"; \ No newline at end of file diff --git a/test/statsCases/import-with-invalid-options-comments/chunk-c.js b/test/statsCases/import-with-invalid-options-comments/chunk-c.js new file mode 100644 index 00000000000..9daca1be5c9 --- /dev/null +++ b/test/statsCases/import-with-invalid-options-comments/chunk-c.js @@ -0,0 +1 @@ +module.exports = "chunk-c"; \ No newline at end of file diff --git a/test/configCases/web/valid-invalid-import-comments/chunk1.js b/test/statsCases/import-with-invalid-options-comments/chunk.js similarity index 69% rename from test/configCases/web/valid-invalid-import-comments/chunk1.js rename to test/statsCases/import-with-invalid-options-comments/chunk.js index 67b0a62e88a..df992d78151 100644 --- a/test/configCases/web/valid-invalid-import-comments/chunk1.js +++ b/test/statsCases/import-with-invalid-options-comments/chunk.js @@ -1,5 +1,5 @@ export default function() { - import(/* webpackPrefetch: true, webpackChunkName: notGoingToCompileChunkName */ "./chunk1-a"); - import(/* webpackPrefetch: 0, webpackChunkName: "goingToCompileChunkName-b" */ "./chunk1-b"); - import(/* webpack Prefetch: 0, webpackChunkName: "notGoingToCompile-c" */ "./chunk1-c"); + import(/* webpackPrefetch: true, webpackChunkName: notGoingToCompileChunkName */ "./chunk-a"); + import(/* webpackPrefetch: 0, webpackChunkName: "goingToCompileChunkName-b" */ "./chunk-b"); + import(/* webpack Prefetch: 0, webpackChunkName: "notGoingToCompile-c" */ "./chunk-c"); } diff --git a/test/statsCases/import-with-invalid-options-comments/index.js b/test/statsCases/import-with-invalid-options-comments/index.js new file mode 100644 index 00000000000..e7010941b37 --- /dev/null +++ b/test/statsCases/import-with-invalid-options-comments/index.js @@ -0,0 +1 @@ +import(/* webpackChunkName: "chunk" */ "./chunk"); \ No newline at end of file diff --git a/test/statsCases/import-with-invalid-options-comments/webpack.config.js b/test/statsCases/import-with-invalid-options-comments/webpack.config.js new file mode 100644 index 00000000000..69f1d9bb3e2 --- /dev/null +++ b/test/statsCases/import-with-invalid-options-comments/webpack.config.js @@ -0,0 +1,8 @@ +module.exports = { + mode: "production", + entry: "./index", + output: { + chunkFilename: "[name].js" + }, + performance: false +}; From d91e7ecafc5f52a27463db031c114a71f29c3b0a Mon Sep 17 00:00:00 2001 From: Ronan Amsterdam Date: Tue, 29 May 2018 16:25:10 +0800 Subject: [PATCH 09/36] getCommentOptions renamed to getCommentOptionsStrict and wrapped back in getCommentOptions to avoid possible breaking changes --- lib/Parser.js | 10 +++++++++- lib/dependencies/ImportParserPlugin.js | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/lib/Parser.js b/lib/Parser.js index 8f66a8b4464..e2583fc3e3e 100644 --- a/lib/Parser.js +++ b/lib/Parser.js @@ -1994,7 +1994,7 @@ class Parser extends Tapable { ); } - getCommentOptions(range) { + getCommentOptionsStrict(range) { const comments = this.getComments(range); if (comments.length === 0) return null; const options = comments.map(comment => { @@ -2015,6 +2015,14 @@ class Parser extends Tapable { return options.reduce((o, i) => Object.assign(o, i), {}); } + getCommentOptions(range) { + try { + return this.getCommentOptionsStrict(range); + } catch (e) { + return {}; + } + } + getNameForExpression(expression) { let expr = expression; const exprName = []; diff --git a/lib/dependencies/ImportParserPlugin.js b/lib/dependencies/ImportParserPlugin.js index 148a1ce28e5..67bc7617e31 100644 --- a/lib/dependencies/ImportParserPlugin.js +++ b/lib/dependencies/ImportParserPlugin.js @@ -34,7 +34,7 @@ class ImportParserPlugin { const groupOptions = {}; try { - importOptions = parser.getCommentOptions(expr.range); + importOptions = parser.getCommentOptionsStrict(expr.range); } catch (e) { parser.state.module.warnings.push( new ImportOptionsCompileWarning( From 4b1a76bdb00ebf89b977c2cc1199870d0c180c72 Mon Sep 17 00:00:00 2001 From: Florent Cailhol Date: Tue, 29 May 2018 11:09:34 +0200 Subject: [PATCH 10/36] Deprecate Parser.getCommentOptions Use Parser.parseCommentOptions(range) instead. --- lib/Parser.js | 26 +++++++++++++++----------- lib/dependencies/ImportParserPlugin.js | 2 +- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/lib/Parser.js b/lib/Parser.js index e2583fc3e3e..d7cb16f8f0e 100644 --- a/lib/Parser.js +++ b/lib/Parser.js @@ -7,8 +7,8 @@ // Syntax: https://developer.mozilla.org/en/SpiderMonkey/Parser_API const acorn = require("acorn-dynamic-import").default; -const { Tapable, SyncBailHook } = require("tapable"); -const HookMap = require("tapable/lib/HookMap"); +const { Tapable, SyncBailHook, HookMap } = require("tapable"); +const util = require("util"); const vm = require("vm"); const BasicEvaluatedExpression = require("./BasicEvaluatedExpression"); const StackedSetMap = require("./util/StackedSetMap"); @@ -1994,7 +1994,7 @@ class Parser extends Tapable { ); } - getCommentOptionsStrict(range) { + parseCommentOptions(range) { const comments = this.getComments(range); if (comments.length === 0) return null; const options = comments.map(comment => { @@ -2015,14 +2015,6 @@ class Parser extends Tapable { return options.reduce((o, i) => Object.assign(o, i), {}); } - getCommentOptions(range) { - try { - return this.getCommentOptionsStrict(range); - } catch (e) { - return {}; - } - } - getNameForExpression(expression) { let expr = expression; const exprName = []; @@ -2104,4 +2096,16 @@ class Parser extends Tapable { } } +// TODO remove in webpack 5 +Object.defineProperty(Parser.prototype, "getCommentOptions", { + configurable: false, + value: util.deprecate(function(range) { + try { + return this.parseCommentOptions(range); + } catch (e) { + return {}; + } + }, "Parser.getCommentOptions: Use Parser.parseCommentOptions(range) instead") +}); + module.exports = Parser; diff --git a/lib/dependencies/ImportParserPlugin.js b/lib/dependencies/ImportParserPlugin.js index 67bc7617e31..b9293115128 100644 --- a/lib/dependencies/ImportParserPlugin.js +++ b/lib/dependencies/ImportParserPlugin.js @@ -34,7 +34,7 @@ class ImportParserPlugin { const groupOptions = {}; try { - importOptions = parser.getCommentOptionsStrict(expr.range); + importOptions = parser.parseCommentOptions(expr.range); } catch (e) { parser.state.module.warnings.push( new ImportOptionsCompileWarning( From 25ec7e41021d785c268a14f45bebc24bfb963a78 Mon Sep 17 00:00:00 2001 From: Florent Cailhol Date: Tue, 29 May 2018 13:17:36 +0200 Subject: [PATCH 11/36] Do not stop processing on error --- lib/Parser.js | 31 ++++++++++--------- lib/dependencies/ImportParserPlugin.js | 29 ++++++++++------- .../__snapshots__/StatsTestCases.test.js.snap | 4 +-- 3 files changed, 37 insertions(+), 27 deletions(-) diff --git a/lib/Parser.js b/lib/Parser.js index d7cb16f8f0e..a92a53bf6af 100644 --- a/lib/Parser.js +++ b/lib/Parser.js @@ -43,6 +43,11 @@ const webpackImportCommentOptions = [ const webpackCommentRegExp = new RegExp(webpackImportCommentOptions.join("|")); +const EMPTY_COMMENT_OPTIONS = { + options: null, + errors: null +}; + class Parser extends Tapable { constructor(options, sourceType = "auto") { super(); @@ -1996,23 +2001,25 @@ class Parser extends Tapable { parseCommentOptions(range) { const comments = this.getComments(range); - if (comments.length === 0) return null; - const options = comments.map(comment => { + if (comments.length === 0) { + return EMPTY_COMMENT_OPTIONS; + } + let options = {}; + let errors = []; + for (const comment of comments) { const { value } = comment; if (value && webpackCommentRegExp.test(value)) { // try compile only if webpack options comment is present try { const val = vm.runInNewContext(`(function(){return {${value}};})()`); - return val; + Object.assign(options, val); } catch (e) { - throw Error( - `compilation error while processing: /*${value}*/: ${e.message}` - ); + e.comment = comment; + errors.push(e); } } - return {}; - }); - return options.reduce((o, i) => Object.assign(o, i), {}); + } + return { options, errors }; } getNameForExpression(expression) { @@ -2100,11 +2107,7 @@ class Parser extends Tapable { Object.defineProperty(Parser.prototype, "getCommentOptions", { configurable: false, value: util.deprecate(function(range) { - try { - return this.parseCommentOptions(range); - } catch (e) { - return {}; - } + return this.parseCommentOptions(range).options; }, "Parser.getCommentOptions: Use Parser.parseCommentOptions(range) instead") }); diff --git a/lib/dependencies/ImportParserPlugin.js b/lib/dependencies/ImportParserPlugin.js index b9293115128..3060d298ee6 100644 --- a/lib/dependencies/ImportParserPlugin.js +++ b/lib/dependencies/ImportParserPlugin.js @@ -30,19 +30,26 @@ class ImportParserPlugin { let mode = "lazy"; let include = null; let exclude = null; - let importOptions = null; const groupOptions = {}; - try { - importOptions = parser.parseCommentOptions(expr.range); - } catch (e) { - parser.state.module.warnings.push( - new ImportOptionsCompileWarning( - e.message, - parser.state.module, - expr.loc - ) - ); + const { + options: importOptions, + errors: commentErrors + } = parser.parseCommentOptions(expr.range); + + if (commentErrors) { + for (const e of commentErrors) { + const { comment } = e; + parser.state.module.warnings.push( + new ImportOptionsCompileWarning( + `compilation error while processing: /*${comment.value}*/: ${ + e.message + }`, + parser.state.module, + comment.loc + ) + ); + } } if (importOptions) { diff --git a/test/__snapshots__/StatsTestCases.test.js.snap b/test/__snapshots__/StatsTestCases.test.js.snap index 1f328b6aa30..7c5a1f40482 100644 --- a/test/__snapshots__/StatsTestCases.test.js.snap +++ b/test/__snapshots__/StatsTestCases.test.js.snap @@ -1026,11 +1026,11 @@ Entrypoint main = main.js WARNING in ./chunk.js compilation error while processing: /* webpack Prefetch: 0, webpackChunkName: \\"notGoingToCompile-c\\" */: Unexpected identifier - @ ./index.js 4:4-90 1:0-49 + @ ./index.js 4:11-77 1:0-49 WARNING in ./chunk.js compilation error while processing: /* webpackPrefetch: true, webpackChunkName: notGoingToCompileChunkName */: notGoingToCompileChunkName is not defined - @ ./index.js 2:4-97 1:0-49" + @ ./index.js 2:11-84 1:0-49" `; exports[`StatsTestCases should print correct stats for limit-chunk-count-plugin 1`] = ` From bdd9bc3c92a31bdcfd6daad6d82bbf0d715f04b4 Mon Sep 17 00:00:00 2001 From: Sven SAULEAU Date: Tue, 29 May 2018 15:25:10 +0200 Subject: [PATCH 12/36] chore: bump webassemblyjs --- package.json | 8 +-- yarn.lock | 183 ++++++++++++++++++++++++++------------------------- 2 files changed, 96 insertions(+), 95 deletions(-) diff --git a/package.json b/package.json index 64b64c67a13..9b99e879ceb 100644 --- a/package.json +++ b/package.json @@ -5,10 +5,10 @@ "description": "Packs CommonJs/AMD modules for the browser. Allows to split your codebase into multiple bundles, which can be loaded on demand. Support loaders to preprocess files, i.e. json, jsx, es7, css, less, ... and your custom stuff.", "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.5.8", - "@webassemblyjs/wasm-edit": "1.5.8", - "@webassemblyjs/wasm-opt": "1.5.8", - "@webassemblyjs/wasm-parser": "1.5.8", + "@webassemblyjs/ast": "1.5.9", + "@webassemblyjs/wasm-edit": "1.5.9", + "@webassemblyjs/wasm-opt": "1.5.9", + "@webassemblyjs/wasm-parser": "1.5.9", "acorn": "^5.0.0", "acorn-dynamic-import": "^3.0.0", "ajv": "^6.1.0", diff --git a/yarn.lock b/yarn.lock index 104c6ab76cf..3f36ad903b6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -34,131 +34,132 @@ version "1.0.2" resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.2.tgz#e13182e1b69871a422d7863e11a4a6f5b814a4bd" -"@webassemblyjs/ast@1.5.8": - version "1.5.8" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.5.8.tgz#f75ac7e7602b7833abd5d53951baae8a07ebb5df" +"@webassemblyjs/ast@1.5.9": + version "1.5.9" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.5.9.tgz#b2770182678691ab4949d593105c15d4074fedb6" dependencies: - "@webassemblyjs/helper-module-context" "1.5.8" - "@webassemblyjs/helper-wasm-bytecode" "1.5.8" - "@webassemblyjs/wast-parser" "1.5.8" + "@webassemblyjs/helper-module-context" "1.5.9" + "@webassemblyjs/helper-wasm-bytecode" "1.5.9" + "@webassemblyjs/wast-parser" "1.5.9" debug "^3.1.0" mamacro "^0.0.3" -"@webassemblyjs/floating-point-hex-parser@1.5.8": - version "1.5.8" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.5.8.tgz#e0604d34fab0c910e16113720a5a3c01f558fa54" +"@webassemblyjs/floating-point-hex-parser@1.5.9": + version "1.5.9" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.5.9.tgz#ee56243f6ba30781ff6f92fe7f1c377255219a7c" -"@webassemblyjs/helper-api-error@1.5.8": - version "1.5.8" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.5.8.tgz#f5570aff60090fae1b78a690a95d04cb021da9ca" +"@webassemblyjs/helper-api-error@1.5.9": + version "1.5.9" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.5.9.tgz#c80e204afe1ae102c23b0357f1ec25aeb61022a2" -"@webassemblyjs/helper-buffer@1.5.8": - version "1.5.8" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.5.8.tgz#b1405e819a2c537964682fb70551796ab9602632" +"@webassemblyjs/helper-buffer@1.5.9": + version "1.5.9" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.5.9.tgz#90d99afcb0fdc1ee11bc403894f3ae37cd926a81" dependencies: debug "^3.1.0" -"@webassemblyjs/helper-code-frame@1.5.8": - version "1.5.8" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.5.8.tgz#6439de475720198a48fa8b4c38e41987798f73cc" +"@webassemblyjs/helper-code-frame@1.5.9": + version "1.5.9" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.5.9.tgz#b56ac06a39c3e1cfefcc421ade1ee471a738a570" dependencies: - "@webassemblyjs/wast-printer" "1.5.8" + "@webassemblyjs/wast-printer" "1.5.9" -"@webassemblyjs/helper-fsm@1.5.8": - version "1.5.8" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.5.8.tgz#6169af3c9530cf9e89a8f3cf2970ed70e650ae4f" +"@webassemblyjs/helper-fsm@1.5.9": + version "1.5.9" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.5.9.tgz#8f996268eb07ee6728130a9e97fa3aac32772454" -"@webassemblyjs/helper-module-context@1.5.8": - version "1.5.8" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.5.8.tgz#73d0de45cebb774d465b5a66fef061f834d6c23c" +"@webassemblyjs/helper-module-context@1.5.9": + version "1.5.9" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.5.9.tgz#69e2eea310f755a0b750b84f8af59f890f2046ac" -"@webassemblyjs/helper-wasm-bytecode@1.5.8": - version "1.5.8" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.5.8.tgz#60df17f72d12b07e1398756e6ebfe59c03ab2e1a" +"@webassemblyjs/helper-wasm-bytecode@1.5.9": + version "1.5.9" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.5.9.tgz#467ba0f9e4d0e4a48bf1c5107b9f4abe3ca1171a" -"@webassemblyjs/helper-wasm-section@1.5.8": - version "1.5.8" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.5.8.tgz#cda7fdb6f3b7b0d215c8f92b7435d47726822f49" +"@webassemblyjs/helper-wasm-section@1.5.9": + version "1.5.9" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.5.9.tgz#aec9486ab5d56e3cb5252a7ed88777b6792ac624" dependencies: - "@webassemblyjs/ast" "1.5.8" - "@webassemblyjs/helper-buffer" "1.5.8" - "@webassemblyjs/helper-wasm-bytecode" "1.5.8" - "@webassemblyjs/wasm-gen" "1.5.8" + "@webassemblyjs/ast" "1.5.9" + "@webassemblyjs/helper-buffer" "1.5.9" + "@webassemblyjs/helper-wasm-bytecode" "1.5.9" + "@webassemblyjs/wasm-gen" "1.5.9" debug "^3.1.0" -"@webassemblyjs/ieee754@1.5.8": - version "1.5.8" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.5.8.tgz#29383c7172e90121613d5614d532f22c19255c3b" +"@webassemblyjs/ieee754@1.5.9": + version "1.5.9" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.5.9.tgz#846856ece040c7debd5b5645b319c26523613bcf" dependencies: ieee754 "^1.1.11" -"@webassemblyjs/leb128@1.5.8": - version "1.5.8" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.5.8.tgz#657c48ef2537ea2921e897a50157be700bf24eac" +"@webassemblyjs/leb128@1.5.9": + version "1.5.9" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.5.9.tgz#7249443a0fd7574a7e3c1c39532535c735390bbc" dependencies: leb "^0.3.0" -"@webassemblyjs/wasm-edit@1.5.8": - version "1.5.8" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.5.8.tgz#592d3678894eaa2ee7e7c2c6a13c2a697db1aa7e" - dependencies: - "@webassemblyjs/ast" "1.5.8" - "@webassemblyjs/helper-buffer" "1.5.8" - "@webassemblyjs/helper-wasm-bytecode" "1.5.8" - "@webassemblyjs/helper-wasm-section" "1.5.8" - "@webassemblyjs/wasm-gen" "1.5.8" - "@webassemblyjs/wasm-opt" "1.5.8" - "@webassemblyjs/wasm-parser" "1.5.8" - "@webassemblyjs/wast-printer" "1.5.8" +"@webassemblyjs/wasm-edit@1.5.9": + version "1.5.9" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.5.9.tgz#9b8e054b2d305a7e0528088571c95904bd73df48" + dependencies: + "@webassemblyjs/ast" "1.5.9" + "@webassemblyjs/helper-buffer" "1.5.9" + "@webassemblyjs/helper-wasm-bytecode" "1.5.9" + "@webassemblyjs/helper-wasm-section" "1.5.9" + "@webassemblyjs/wasm-gen" "1.5.9" + "@webassemblyjs/wasm-opt" "1.5.9" + "@webassemblyjs/wasm-parser" "1.5.9" + "@webassemblyjs/wast-printer" "1.5.9" debug "^3.1.0" -"@webassemblyjs/wasm-gen@1.5.8": - version "1.5.8" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.5.8.tgz#e94e034a45227aaa7c481b25c1aa9a0a00ab9488" +"@webassemblyjs/wasm-gen@1.5.9": + version "1.5.9" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.5.9.tgz#85e07c047fab917e06b18dee4d16342a2fd3c59c" dependencies: - "@webassemblyjs/ast" "1.5.8" - "@webassemblyjs/helper-wasm-bytecode" "1.5.8" - "@webassemblyjs/ieee754" "1.5.8" - "@webassemblyjs/leb128" "1.5.8" + "@webassemblyjs/ast" "1.5.9" + "@webassemblyjs/helper-wasm-bytecode" "1.5.9" + "@webassemblyjs/ieee754" "1.5.9" + "@webassemblyjs/leb128" "1.5.9" -"@webassemblyjs/wasm-opt@1.5.8": - version "1.5.8" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.5.8.tgz#a3a0d00d98dee0f3cf2ae41084eb62715a39242c" +"@webassemblyjs/wasm-opt@1.5.9": + version "1.5.9" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.5.9.tgz#ccac17c41a044c167bc95d3e8645cf889a137ce5" dependencies: - "@webassemblyjs/ast" "1.5.8" - "@webassemblyjs/helper-buffer" "1.5.8" - "@webassemblyjs/wasm-gen" "1.5.8" - "@webassemblyjs/wasm-parser" "1.5.8" + "@webassemblyjs/ast" "1.5.9" + "@webassemblyjs/helper-buffer" "1.5.9" + "@webassemblyjs/wasm-gen" "1.5.9" + "@webassemblyjs/wasm-parser" "1.5.9" debug "^3.1.0" -"@webassemblyjs/wasm-parser@1.5.8": - version "1.5.8" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.5.8.tgz#a258a7fd15bd57597e4211d9068639807546555b" - dependencies: - "@webassemblyjs/ast" "1.5.8" - "@webassemblyjs/helper-api-error" "1.5.8" - "@webassemblyjs/helper-wasm-bytecode" "1.5.8" - "@webassemblyjs/leb128" "1.5.8" - "@webassemblyjs/wasm-parser" "1.5.8" - -"@webassemblyjs/wast-parser@1.5.8": - version "1.5.8" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.5.8.tgz#85705659e15d19b89af38a8d6803d720bb0493cf" - dependencies: - "@webassemblyjs/ast" "1.5.8" - "@webassemblyjs/floating-point-hex-parser" "1.5.8" - "@webassemblyjs/helper-api-error" "1.5.8" - "@webassemblyjs/helper-code-frame" "1.5.8" - "@webassemblyjs/helper-fsm" "1.5.8" +"@webassemblyjs/wasm-parser@1.5.9": + version "1.5.9" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.5.9.tgz#ddab84da4957b64aafbc61e4ab706cc667082f32" + dependencies: + "@webassemblyjs/ast" "1.5.9" + "@webassemblyjs/helper-api-error" "1.5.9" + "@webassemblyjs/helper-wasm-bytecode" "1.5.9" + "@webassemblyjs/ieee754" "1.5.9" + "@webassemblyjs/leb128" "1.5.9" + "@webassemblyjs/wasm-parser" "1.5.9" + +"@webassemblyjs/wast-parser@1.5.9": + version "1.5.9" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.5.9.tgz#193d24ccf4742a5f8f1915936680ab2314011df2" + dependencies: + "@webassemblyjs/ast" "1.5.9" + "@webassemblyjs/floating-point-hex-parser" "1.5.9" + "@webassemblyjs/helper-api-error" "1.5.9" + "@webassemblyjs/helper-code-frame" "1.5.9" + "@webassemblyjs/helper-fsm" "1.5.9" long "^3.2.0" mamacro "^0.0.3" -"@webassemblyjs/wast-printer@1.5.8": - version "1.5.8" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.5.8.tgz#0f83aa67eddf377dd1d6205d4a4ac976db60e1f6" +"@webassemblyjs/wast-printer@1.5.9": + version "1.5.9" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.5.9.tgz#16605d90a481c01a130b7c4edeb2bce503787eb4" dependencies: - "@webassemblyjs/ast" "1.5.8" - "@webassemblyjs/wast-parser" "1.5.8" + "@webassemblyjs/ast" "1.5.9" + "@webassemblyjs/wast-parser" "1.5.9" long "^3.2.0" abab@^1.0.4: From cf8ae64f8a7438ff1f71dce5fc1ff067bc212a22 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Tue, 29 May 2018 19:49:56 +0200 Subject: [PATCH 13/36] fix incorrect substraction --- lib/Template.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/Template.js b/lib/Template.js index 92327ac49f0..5149a342999 100644 --- a/lib/Template.js +++ b/lib/Template.js @@ -118,9 +118,11 @@ class Template { return String.fromCharCode(START_LOWERCASE_ALPHABET_CODE + n); // upper case - n -= DELTA_A_TO_Z; - if (n < DELTA_A_TO_Z) - return String.fromCharCode(START_UPPERCASE_ALPHABET_CODE + n); + if (n < DELTA_A_TO_Z * 2) { + return String.fromCharCode( + START_UPPERCASE_ALPHABET_CODE + n - DELTA_A_TO_Z + ); + } // use multiple letters return ( From a228daec58ee41ad1edc0bb79e3086ee2e00d44c Mon Sep 17 00:00:00 2001 From: Ronan Amsterdam Date: Wed, 30 May 2018 09:24:36 +0800 Subject: [PATCH 14/36] magic comment regexp match update and statsCase test updated plus minor renamings and snapshot update --- lib/Parser.js | 13 ++-------- lib/dependencies/ImportParserPlugin.js | 12 ++++----- .../__snapshots__/StatsTestCases.test.js.snap | 25 +++++-------------- .../chunk-d.js | 1 + .../chunk.js | 1 + .../webpack.config.js | 2 +- 6 files changed, 17 insertions(+), 37 deletions(-) create mode 100644 test/statsCases/import-with-invalid-options-comments/chunk-d.js diff --git a/lib/Parser.js b/lib/Parser.js index a92a53bf6af..cac3060699b 100644 --- a/lib/Parser.js +++ b/lib/Parser.js @@ -31,17 +31,8 @@ const defaultParserOptions = { } }; -const webpackImportCommentOptions = [ - "webpackIgnore", - "webpackChunkName", - "webpackMode", - "webpackPrefetch", - "webpackPreload", - "webpackInclude", - "webpackExclude" -]; - -const webpackCommentRegExp = new RegExp(webpackImportCommentOptions.join("|")); +// regexp to match at lease one "magic comment" +const webpackCommentRegExp = new RegExp(/(^|\W)webpack[A-Z]{1,}[A-Za-z]{1,}:/); const EMPTY_COMMENT_OPTIONS = { options: null, diff --git a/lib/dependencies/ImportParserPlugin.js b/lib/dependencies/ImportParserPlugin.js index 3060d298ee6..787438277f1 100644 --- a/lib/dependencies/ImportParserPlugin.js +++ b/lib/dependencies/ImportParserPlugin.js @@ -41,10 +41,10 @@ class ImportParserPlugin { for (const e of commentErrors) { const { comment } = e; parser.state.module.warnings.push( - new ImportOptionsCompileWarning( - `compilation error while processing: /*${comment.value}*/: ${ - e.message - }`, + new CommentCompilationWarning( + `Compilation error while processing magic comment(-s): /*${ + comment.value + }*/: ${e.message}`, parser.state.module, comment.loc ) @@ -250,11 +250,11 @@ class ImportParserPlugin { } } -class ImportOptionsCompileWarning extends WebpackError { +class CommentCompilationWarning extends WebpackError { constructor(message, module, loc) { super(); - this.name = "ImportOptionsCompileWarning"; + this.name = "CommentCompilationWarning"; this.message = message; this.origin = this.module = module; diff --git a/test/__snapshots__/StatsTestCases.test.js.snap b/test/__snapshots__/StatsTestCases.test.js.snap index 7c5a1f40482..8b33f0804fa 100644 --- a/test/__snapshots__/StatsTestCases.test.js.snap +++ b/test/__snapshots__/StatsTestCases.test.js.snap @@ -1008,29 +1008,16 @@ Entrypoint entry = entry.js `; exports[`StatsTestCases should print correct stats for import-with-invalid-options-comments 1`] = ` -"Hash: 3933c30f2b0ad856b9f3 -Time: Xms -Built at: Thu Jan 01 1970 00:00:00 GMT - Asset Size Chunks Chunk Names - chunk.js 1.16 KiB 0 [emitted] chunk - main.js 7.85 KiB 1 [emitted] main - 2.js 154 bytes 2 [emitted] -goingToCompileChunkName-b.js 163 bytes 3 [emitted] goingToCompileChunkName-b - 4.js 157 bytes 4 [emitted] -Entrypoint main = main.js -[0] ./chunk-a.js 27 bytes {2} [built] -[1] ./chunk-b.js 27 bytes {3} [built] -[2] ./chunk-c.js 27 bytes {4} [built] -[3] ./chunk.js 318 bytes {0} [built] [2 warnings] -[4] ./index.js 50 bytes {1} [built] +" 6 modules + +WARNING in ./chunk.js +Compilation error while processing magic comment(-s): /* webpack Prefetch: 0, webpackChunkName: \\"notGoingToCompile-c\\" */: Unexpected identifier WARNING in ./chunk.js -compilation error while processing: /* webpack Prefetch: 0, webpackChunkName: \\"notGoingToCompile-c\\" */: Unexpected identifier - @ ./index.js 4:11-77 1:0-49 +Compilation error while processing magic comment(-s): /* webpackPrefetch: nope */: nope is not defined WARNING in ./chunk.js -compilation error while processing: /* webpackPrefetch: true, webpackChunkName: notGoingToCompileChunkName */: notGoingToCompileChunkName is not defined - @ ./index.js 2:11-84 1:0-49" +Compilation error while processing magic comment(-s): /* webpackPrefetch: true, webpackChunkName: notGoingToCompileChunkName */: notGoingToCompileChunkName is not defined" `; exports[`StatsTestCases should print correct stats for limit-chunk-count-plugin 1`] = ` diff --git a/test/statsCases/import-with-invalid-options-comments/chunk-d.js b/test/statsCases/import-with-invalid-options-comments/chunk-d.js new file mode 100644 index 00000000000..5578e7b39d9 --- /dev/null +++ b/test/statsCases/import-with-invalid-options-comments/chunk-d.js @@ -0,0 +1 @@ +module.exports = "chunk-d"; \ No newline at end of file diff --git a/test/statsCases/import-with-invalid-options-comments/chunk.js b/test/statsCases/import-with-invalid-options-comments/chunk.js index df992d78151..a30499bdecb 100644 --- a/test/statsCases/import-with-invalid-options-comments/chunk.js +++ b/test/statsCases/import-with-invalid-options-comments/chunk.js @@ -2,4 +2,5 @@ export default function() { import(/* webpackPrefetch: true, webpackChunkName: notGoingToCompileChunkName */ "./chunk-a"); import(/* webpackPrefetch: 0, webpackChunkName: "goingToCompileChunkName-b" */ "./chunk-b"); import(/* webpack Prefetch: 0, webpackChunkName: "notGoingToCompile-c" */ "./chunk-c"); + import(/* webpackPrefetch: nope */ /* webpackChunkName: "yep" */ "./chunk-d"); } diff --git a/test/statsCases/import-with-invalid-options-comments/webpack.config.js b/test/statsCases/import-with-invalid-options-comments/webpack.config.js index 69f1d9bb3e2..417955cf6f3 100644 --- a/test/statsCases/import-with-invalid-options-comments/webpack.config.js +++ b/test/statsCases/import-with-invalid-options-comments/webpack.config.js @@ -4,5 +4,5 @@ module.exports = { output: { chunkFilename: "[name].js" }, - performance: false + stats: "minimal" }; From 6390240e05eccc312c38d86e5e3177466657d1b8 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Wed, 30 May 2018 09:51:11 +0200 Subject: [PATCH 15/36] rewrite module reference correctly after replacing ConcatenatedModule fixes #7443 --- lib/optimize/ModuleConcatenationPlugin.js | 8 +++++++- test/cases/optimize/side-effects-scope-hoisting/index.js | 8 ++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 test/cases/optimize/side-effects-scope-hoisting/index.js diff --git a/lib/optimize/ModuleConcatenationPlugin.js b/lib/optimize/ModuleConcatenationPlugin.js index 498d101bc41..97e23e02b6d 100644 --- a/lib/optimize/ModuleConcatenationPlugin.js +++ b/lib/optimize/ModuleConcatenationPlugin.js @@ -286,7 +286,13 @@ class ModuleConcatenationPlugin { } compilation.modules.push(newModule); for (const reason of newModule.reasons) { - reason.dependency.module = newModule; + if (reason.dependency.module === concatConfiguration.rootModule) + reason.dependency.module = newModule; + if ( + reason.dependency.redirectedModule === + concatConfiguration.rootModule + ) + reason.dependency.redirectedModule = newModule; } // TODO: remove when LTS node version contains fixed v8 version // @see https://github.com/webpack/webpack/pull/6613 diff --git a/test/cases/optimize/side-effects-scope-hoisting/index.js b/test/cases/optimize/side-effects-scope-hoisting/index.js new file mode 100644 index 00000000000..100d58775b3 --- /dev/null +++ b/test/cases/optimize/side-effects-scope-hoisting/index.js @@ -0,0 +1,8 @@ +import { a } from "pmodule"; + +it("should not crash with null id", function() { + expect(a).toBe("a"); +}); + +if(Math === undefined) + console.log(module); // prevent scope hoisting of this module From b8266d09a9472344a4894f1d8cf4067eb452019c Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Wed, 30 May 2018 10:29:14 +0200 Subject: [PATCH 16/36] 4.10.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e39a866c290..eafde698f23 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "webpack", - "version": "4.10.1", + "version": "4.10.2", "author": "Tobias Koppers @sokra", "description": "Packs CommonJs/AMD modules for the browser. Allows to split your codebase into multiple bundles, which can be loaded on demand. Support loaders to preprocess files, i.e. json, jsx, es7, css, less, ... and your custom stuff.", "license": "MIT", From 53d26bfc963c34dd26c7eba44facdea1d5081991 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Tue, 29 May 2018 21:20:43 +0200 Subject: [PATCH 17/36] merge rewriteGlobalsReferingImportedGlobals into rewriteImportedGlobals --- lib/wasm/WebAssemblyGenerator.js | 63 ++++++++++---------------------- 1 file changed, 20 insertions(+), 43 deletions(-) diff --git a/lib/wasm/WebAssemblyGenerator.js b/lib/wasm/WebAssemblyGenerator.js index c3136a841f0..59c7fa198c0 100644 --- a/lib/wasm/WebAssemblyGenerator.js +++ b/lib/wasm/WebAssemblyGenerator.js @@ -178,6 +178,7 @@ function getNextFuncIndex(ast, countImportedFunc) { * @returns {ArrayBufferTransform} transform */ const rewriteImportedGlobals = state => bin => { + const additionalInitCode = state.additionalInitCode; const newGlobals = []; bin = editWithAST(state.ast, bin, { @@ -212,29 +213,7 @@ const rewriteImportedGlobals = state => bin => { // in order to preserve non-imported global's order we need to re-inject // those as well Global(path) { - newGlobals.push(path.node); - path.remove(); - } - }); - - // Add global declaration instructions - return addWithAST(state.ast, bin, newGlobals); -}; - -const rewriteGlobalsReferingImportedGlobals = state => bin => { - const additionalInitCode = []; - - // Track global index in the module - let globalidx = 0; - - bin = editWithAST(state.ast, bin, { - ModuleImport({ node }) { - if (isGlobalImport(node) === true) { - globalidx++; - } - }, - - Global({ node }) { + const { node } = path; const [init] = node.init; if (init.id === "get_global") { @@ -256,28 +235,18 @@ const rewriteGlobalsReferingImportedGlobals = state => bin => { * same index. */ t.instruction("get_local", [initialGlobalidx]), - t.instruction("set_global", [t.indexLiteral(globalidx)]) + t.instruction("set_global", [t.indexLiteral(newGlobals.length)]) ); } - globalidx++; + newGlobals.push(node); + + path.remove(); } }); - // Update the init with our additional runtime code - if (additionalInitCode.length > 0) { - bin = editWithAST(state.ast, bin, { - Func({ node }) { - if (node.name.value === state.initFuncId.value) { - const newBody = [...node.body, ...additionalInitCode]; - - node.body = newBody; - } - } - }); - } - - return bin; + // Add global declaration instructions + return addWithAST(state.ast, bin, newGlobals); }; /** @@ -333,6 +302,7 @@ const rewriteImports = ({ ast, usedDependencyMap }) => bin => { * @param {t.Identifier} state.initFuncId identifier of the init function * @param {t.IndexLiteral} state.startAtFuncIndex index of the start function * @param {t.ModuleImport[]} state.importedGlobals list of imported globals + * @param {t.Instruction[]} state.additionalInitCode list of addition instructions for the init function * @param {t.IndexLiteral} state.nextFuncIndex index of the next function * @param {t.IndexLiteral} state.nextTypeIndex index of the next type * @returns {ArrayBufferTransform} transform @@ -342,6 +312,7 @@ const addInitFunction = ({ initFuncId, startAtFuncIndex, importedGlobals, + additionalInitCode, nextFuncIndex, nextTypeIndex }) => bin => { @@ -366,6 +337,10 @@ const addInitFunction = ({ funcBody.push(t.callInstruction(startAtFuncIndex)); } + for (const instr of additionalInitCode) { + funcBody.push(instr); + } + const funcResults = []; // Code section @@ -429,6 +404,9 @@ class WebAssemblyGenerator extends Generator { const usedDependencyMap = getUsedDependencyMap(module); + /** @type {t.Instruction[]} */ + const additionalInitCode = []; + const transform = compose( rewriteExportNames({ ast, @@ -437,7 +415,7 @@ class WebAssemblyGenerator extends Generator { removeStartFunc({ ast }), - rewriteImportedGlobals({ ast }), + rewriteImportedGlobals({ ast, additionalInitCode }), rewriteImports({ ast, @@ -448,12 +426,11 @@ class WebAssemblyGenerator extends Generator { ast, initFuncId, importedGlobals, + additionalInitCode, startAtFuncIndex, nextFuncIndex, nextTypeIndex - }), - - rewriteGlobalsReferingImportedGlobals({ ast, initFuncId }) + }) ); const newBin = transform(bin); From 912d5bef5ce5d1ace1dd5a2c3511b4a6b8ae0730 Mon Sep 17 00:00:00 2001 From: Florent Cailhol Date: Wed, 30 May 2018 13:06:10 +0200 Subject: [PATCH 18/36] Use same settings for editorconfig and prettier --- .editorconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.editorconfig b/.editorconfig index f537e0e648f..45137161298 100644 --- a/.editorconfig +++ b/.editorconfig @@ -2,11 +2,11 @@ root = true [*] indent_style = tab -indent_size = 4 +indent_size = 2 charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true -max_line_length = 233 +max_line_length = 80 [.prettierrc] indent_style = space From 271fb7b543e017cde14186f3c7eb741bd9892c0c Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Tue, 29 May 2018 18:14:16 +0200 Subject: [PATCH 19/36] more performant changing of reasons --- lib/optimize/SideEffectsFlagPlugin.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/optimize/SideEffectsFlagPlugin.js b/lib/optimize/SideEffectsFlagPlugin.js index 7bf30b0ba21..4b618c2990b 100644 --- a/lib/optimize/SideEffectsFlagPlugin.js +++ b/lib/optimize/SideEffectsFlagPlugin.js @@ -106,6 +106,7 @@ class SideEffectsFlagPlugin { for (const pair of reexportMaps) { const module = pair[0]; const map = pair[1]; + let newReasons = undefined; for (let i = 0; i < module.reasons.length; i++) { const reason = module.reasons[i]; const dep = reason.dependency; @@ -117,7 +118,6 @@ class SideEffectsFlagPlugin { if (mapping) { dep.redirectedModule = mapping.module; dep.redirectedId = mapping.exportName; - module.reasons.splice(i--, 1); mapping.module.addReason( reason.module, dep, @@ -126,8 +126,18 @@ class SideEffectsFlagPlugin { " (skipped side-effect-free modules)" : "(skipped side-effect-free modules)" ); + // removing the currect reason, by not adding it to the newReasons array + // lazily create the newReasons array + if (newReasons === undefined) { + newReasons = i === 0 ? [] : module.reasons.slice(0, i); + } + continue; } } + if (newReasons !== undefined) newReasons.push(reason); + } + if (newReasons !== undefined) { + module.reasons = newReasons; } } } From 605064bb2edcb5aef0126dbd4cfa2884a2b296b8 Mon Sep 17 00:00:00 2001 From: Spencer Elliott Date: Tue, 29 May 2018 11:22:12 -0700 Subject: [PATCH 20/36] Add `reportProgress` function to afterEmit hook context --- lib/ProgressPlugin.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/lib/ProgressPlugin.js b/lib/ProgressPlugin.js index 137bb492ea5..5e45eddabb2 100644 --- a/lib/ProgressPlugin.js +++ b/lib/ProgressPlugin.js @@ -222,6 +222,21 @@ class ProgressPlugin { handler(0.95, "emitting", tap.name); } }); + compiler.hooks.afterEmit.intercept({ + name: "ProgressPlugin", + context: true, + call: () => { + handler(0.98, "after emitting"); + }, + tap: (context, tap) => { + if (context) { + context.reportProgress = (p, ...args) => { + handler(0.98, "after emitting", tap.name, ...args); + }; + } + handler(0.98, "after emitting", tap.name); + } + }); compiler.hooks.done.tap("ProgressPlugin", () => { handler(1, ""); }); From 761afebab21e495cc64ec398c9ef529b0af78515 Mon Sep 17 00:00:00 2001 From: Florent Cailhol Date: Fri, 1 Jun 2018 12:49:43 +0200 Subject: [PATCH 21/36] Remove dead test file --- .../harmony/auto-import-default/out/bundle.js | 784 ------------------ 1 file changed, 784 deletions(-) delete mode 100644 test/hotCases/harmony/auto-import-default/out/bundle.js diff --git a/test/hotCases/harmony/auto-import-default/out/bundle.js b/test/hotCases/harmony/auto-import-default/out/bundle.js deleted file mode 100644 index 4c9559bdc76..00000000000 --- a/test/hotCases/harmony/auto-import-default/out/bundle.js +++ /dev/null @@ -1,784 +0,0 @@ -/******/ (function(modules) { // webpackBootstrap -/******/ function hotDisposeChunk(chunkId) { -/******/ delete installedChunks[chunkId]; -/******/ } -/******/ var parentHotUpdateCallback = this["webpackHotUpdate"]; -/******/ this["webpackHotUpdate"] = function webpackHotUpdateCallback(chunkId, moreModules) { // eslint-disable-line no-unused-vars -/******/ hotAddUpdateChunk(chunkId, moreModules); -/******/ if(parentHotUpdateCallback) parentHotUpdateCallback(chunkId, moreModules); -/******/ } ; -/******/ -/******/ function hotDownloadUpdateChunk(chunkId) { // eslint-disable-line no-unused-vars -/******/ var head = document.getElementsByTagName("head")[0]; -/******/ var script = document.createElement("script"); -/******/ script.charset = "utf-8"; -/******/ script.src = __webpack_require__.p + "" + chunkId + "." + hotCurrentHash + ".hot-update.js"; -/******/ ; -/******/ head.appendChild(script); -/******/ } -/******/ -/******/ function hotDownloadManifest(requestTimeout) { // eslint-disable-line no-unused-vars -/******/ requestTimeout = requestTimeout || 10000; -/******/ return new Promise(function(resolve, reject) { -/******/ if(typeof XMLHttpRequest === "undefined") -/******/ return reject(new Error("No browser support")); -/******/ try { -/******/ var request = new XMLHttpRequest(); -/******/ var requestPath = __webpack_require__.p + "" + hotCurrentHash + ".hot-update.json"; -/******/ request.open("GET", requestPath, true); -/******/ request.timeout = requestTimeout; -/******/ request.send(null); -/******/ } catch(err) { -/******/ return reject(err); -/******/ } -/******/ request.onreadystatechange = function() { -/******/ if(request.readyState !== 4) return; -/******/ if(request.status === 0) { -/******/ // timeout -/******/ reject(new Error("Manifest request to " + requestPath + " timed out.")); -/******/ } else if(request.status === 404) { -/******/ // no update available -/******/ resolve(); -/******/ } else if(request.status !== 200 && request.status !== 304) { -/******/ // other failure -/******/ reject(new Error("Manifest request to " + requestPath + " failed.")); -/******/ } else { -/******/ // success -/******/ try { -/******/ var update = JSON.parse(request.responseText); -/******/ } catch(e) { -/******/ reject(e); -/******/ return; -/******/ } -/******/ resolve(update); -/******/ } -/******/ }; -/******/ }); -/******/ } -/******/ -/******/ -/******/ var hotApplyOnUpdate = true; -/******/ var hotCurrentHash = "9e66a96510409aa06627"; // eslint-disable-line no-unused-vars -/******/ var hotRequestTimeout = 10000; -/******/ var hotCurrentModuleData = {}; -/******/ var hotCurrentChildModule; // eslint-disable-line no-unused-vars -/******/ var hotCurrentParents = []; // eslint-disable-line no-unused-vars -/******/ var hotCurrentParentsTemp = []; // eslint-disable-line no-unused-vars -/******/ -/******/ function hotCreateRequire(moduleId) { // eslint-disable-line no-unused-vars -/******/ var me = installedModules[moduleId]; -/******/ if(!me) return __webpack_require__; -/******/ var fn = function(request) { -/******/ if(me.hot.active) { -/******/ if(installedModules[request]) { -/******/ if(installedModules[request].parents.indexOf(moduleId) < 0) -/******/ installedModules[request].parents.push(moduleId); -/******/ } else { -/******/ hotCurrentParents = [moduleId]; -/******/ hotCurrentChildModule = request; -/******/ } -/******/ if(me.children.indexOf(request) < 0) -/******/ me.children.push(request); -/******/ } else { -/******/ console.warn("[HMR] unexpected require(" + request + ") from disposed module " + moduleId); -/******/ hotCurrentParents = []; -/******/ } -/******/ return __webpack_require__(request); -/******/ }; -/******/ var ObjectFactory = function ObjectFactory(name) { -/******/ return { -/******/ configurable: true, -/******/ enumerable: true, -/******/ get: function() { -/******/ return __webpack_require__[name]; -/******/ }, -/******/ set: function(value) { -/******/ __webpack_require__[name] = value; -/******/ } -/******/ }; -/******/ }; -/******/ for(var name in __webpack_require__) { -/******/ if(Object.prototype.hasOwnProperty.call(__webpack_require__, name) && name !== "e") { -/******/ Object.defineProperty(fn, name, ObjectFactory(name)); -/******/ } -/******/ } -/******/ fn.e = function(chunkId) { -/******/ if(hotStatus === "ready") -/******/ hotSetStatus("prepare"); -/******/ hotChunksLoading++; -/******/ return __webpack_require__.e(chunkId).then(finishChunkLoading, function(err) { -/******/ finishChunkLoading(); -/******/ throw err; -/******/ }); -/******/ -/******/ function finishChunkLoading() { -/******/ hotChunksLoading--; -/******/ if(hotStatus === "prepare") { -/******/ if(!hotWaitingFilesMap[chunkId]) { -/******/ hotEnsureUpdateChunk(chunkId); -/******/ } -/******/ if(hotChunksLoading === 0 && hotWaitingFiles === 0) { -/******/ hotUpdateDownloaded(); -/******/ } -/******/ } -/******/ } -/******/ }; -/******/ return fn; -/******/ } -/******/ -/******/ function hotCreateModule(moduleId) { // eslint-disable-line no-unused-vars -/******/ var hot = { -/******/ // private stuff -/******/ _acceptedDependencies: {}, -/******/ _declinedDependencies: {}, -/******/ _selfAccepted: false, -/******/ _selfDeclined: false, -/******/ _disposeHandlers: [], -/******/ _main: hotCurrentChildModule !== moduleId, -/******/ -/******/ // Module API -/******/ active: true, -/******/ accept: function(dep, callback) { -/******/ if(typeof dep === "undefined") -/******/ hot._selfAccepted = true; -/******/ else if(typeof dep === "function") -/******/ hot._selfAccepted = dep; -/******/ else if(typeof dep === "object") -/******/ for(var i = 0; i < dep.length; i++) -/******/ hot._acceptedDependencies[dep[i]] = callback || function() {}; -/******/ else -/******/ hot._acceptedDependencies[dep] = callback || function() {}; -/******/ }, -/******/ decline: function(dep) { -/******/ if(typeof dep === "undefined") -/******/ hot._selfDeclined = true; -/******/ else if(typeof dep === "object") -/******/ for(var i = 0; i < dep.length; i++) -/******/ hot._declinedDependencies[dep[i]] = true; -/******/ else -/******/ hot._declinedDependencies[dep] = true; -/******/ }, -/******/ dispose: function(callback) { -/******/ hot._disposeHandlers.push(callback); -/******/ }, -/******/ addDisposeHandler: function(callback) { -/******/ hot._disposeHandlers.push(callback); -/******/ }, -/******/ removeDisposeHandler: function(callback) { -/******/ var idx = hot._disposeHandlers.indexOf(callback); -/******/ if(idx >= 0) hot._disposeHandlers.splice(idx, 1); -/******/ }, -/******/ -/******/ // Management API -/******/ check: hotCheck, -/******/ apply: hotApply, -/******/ status: function(l) { -/******/ if(!l) return hotStatus; -/******/ hotStatusHandlers.push(l); -/******/ }, -/******/ addStatusHandler: function(l) { -/******/ hotStatusHandlers.push(l); -/******/ }, -/******/ removeStatusHandler: function(l) { -/******/ var idx = hotStatusHandlers.indexOf(l); -/******/ if(idx >= 0) hotStatusHandlers.splice(idx, 1); -/******/ }, -/******/ -/******/ //inherit from previous dispose call -/******/ data: hotCurrentModuleData[moduleId] -/******/ }; -/******/ hotCurrentChildModule = undefined; -/******/ return hot; -/******/ } -/******/ -/******/ var hotStatusHandlers = []; -/******/ var hotStatus = "idle"; -/******/ -/******/ function hotSetStatus(newStatus) { -/******/ hotStatus = newStatus; -/******/ for(var i = 0; i < hotStatusHandlers.length; i++) -/******/ hotStatusHandlers[i].call(null, newStatus); -/******/ } -/******/ -/******/ // while downloading -/******/ var hotWaitingFiles = 0; -/******/ var hotChunksLoading = 0; -/******/ var hotWaitingFilesMap = {}; -/******/ var hotRequestedFilesMap = {}; -/******/ var hotAvailableFilesMap = {}; -/******/ var hotDeferred; -/******/ -/******/ // The update info -/******/ var hotUpdate, hotUpdateNewHash; -/******/ -/******/ function toModuleId(id) { -/******/ var isNumber = (+id) + "" === id; -/******/ return isNumber ? +id : id; -/******/ } -/******/ -/******/ function hotCheck(apply) { -/******/ if(hotStatus !== "idle") throw new Error("check() is only allowed in idle status"); -/******/ hotApplyOnUpdate = apply; -/******/ hotSetStatus("check"); -/******/ return hotDownloadManifest(hotRequestTimeout).then(function(update) { -/******/ if(!update) { -/******/ hotSetStatus("idle"); -/******/ return null; -/******/ } -/******/ hotRequestedFilesMap = {}; -/******/ hotWaitingFilesMap = {}; -/******/ hotAvailableFilesMap = update.c; -/******/ hotUpdateNewHash = update.h; -/******/ -/******/ hotSetStatus("prepare"); -/******/ var promise = new Promise(function(resolve, reject) { -/******/ hotDeferred = { -/******/ resolve: resolve, -/******/ reject: reject -/******/ }; -/******/ }); -/******/ hotUpdate = {}; -/******/ var chunkId = "main"; -/******/ { // eslint-disable-line no-lone-blocks -/******/ /*globals chunkId */ -/******/ hotEnsureUpdateChunk(chunkId); -/******/ } -/******/ if(hotStatus === "prepare" && hotChunksLoading === 0 && hotWaitingFiles === 0) { -/******/ hotUpdateDownloaded(); -/******/ } -/******/ return promise; -/******/ }); -/******/ } -/******/ -/******/ function hotAddUpdateChunk(chunkId, moreModules) { // eslint-disable-line no-unused-vars -/******/ if(!hotAvailableFilesMap[chunkId] || !hotRequestedFilesMap[chunkId]) -/******/ return; -/******/ hotRequestedFilesMap[chunkId] = false; -/******/ for(var moduleId in moreModules) { -/******/ if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) { -/******/ hotUpdate[moduleId] = moreModules[moduleId]; -/******/ } -/******/ } -/******/ if(--hotWaitingFiles === 0 && hotChunksLoading === 0) { -/******/ hotUpdateDownloaded(); -/******/ } -/******/ } -/******/ -/******/ function hotEnsureUpdateChunk(chunkId) { -/******/ if(!hotAvailableFilesMap[chunkId]) { -/******/ hotWaitingFilesMap[chunkId] = true; -/******/ } else { -/******/ hotRequestedFilesMap[chunkId] = true; -/******/ hotWaitingFiles++; -/******/ hotDownloadUpdateChunk(chunkId); -/******/ } -/******/ } -/******/ -/******/ function hotUpdateDownloaded() { -/******/ hotSetStatus("ready"); -/******/ var deferred = hotDeferred; -/******/ hotDeferred = null; -/******/ if(!deferred) return; -/******/ if(hotApplyOnUpdate) { -/******/ // Wrap deferred object in Promise to mark it as a well-handled Promise to -/******/ // avoid triggering uncaught exception warning in Chrome. -/******/ // See https://bugs.chromium.org/p/chromium/issues/detail?id=465666 -/******/ Promise.resolve().then(function() { -/******/ return hotApply(hotApplyOnUpdate); -/******/ }).then( -/******/ function(result) { -/******/ deferred.resolve(result); -/******/ }, -/******/ function(err) { -/******/ deferred.reject(err); -/******/ } -/******/ ); -/******/ } else { -/******/ var outdatedModules = []; -/******/ for(var id in hotUpdate) { -/******/ if(Object.prototype.hasOwnProperty.call(hotUpdate, id)) { -/******/ outdatedModules.push(toModuleId(id)); -/******/ } -/******/ } -/******/ deferred.resolve(outdatedModules); -/******/ } -/******/ } -/******/ -/******/ function hotApply(options) { -/******/ if(hotStatus !== "ready") throw new Error("apply() is only allowed in ready status"); -/******/ options = options || {}; -/******/ -/******/ var cb; -/******/ var i; -/******/ var j; -/******/ var module; -/******/ var moduleId; -/******/ -/******/ function getAffectedStuff(updateModuleId) { -/******/ var outdatedModules = [updateModuleId]; -/******/ var outdatedDependencies = {}; -/******/ -/******/ var queue = outdatedModules.slice().map(function(id) { -/******/ return { -/******/ chain: [id], -/******/ id: id -/******/ }; -/******/ }); -/******/ while(queue.length > 0) { -/******/ var queueItem = queue.pop(); -/******/ var moduleId = queueItem.id; -/******/ var chain = queueItem.chain; -/******/ module = installedModules[moduleId]; -/******/ if(!module || module.hot._selfAccepted) -/******/ continue; -/******/ if(module.hot._selfDeclined) { -/******/ return { -/******/ type: "self-declined", -/******/ chain: chain, -/******/ moduleId: moduleId -/******/ }; -/******/ } -/******/ if(module.hot._main) { -/******/ return { -/******/ type: "unaccepted", -/******/ chain: chain, -/******/ moduleId: moduleId -/******/ }; -/******/ } -/******/ for(var i = 0; i < module.parents.length; i++) { -/******/ var parentId = module.parents[i]; -/******/ var parent = installedModules[parentId]; -/******/ if(!parent) continue; -/******/ if(parent.hot._declinedDependencies[moduleId]) { -/******/ return { -/******/ type: "declined", -/******/ chain: chain.concat([parentId]), -/******/ moduleId: moduleId, -/******/ parentId: parentId -/******/ }; -/******/ } -/******/ if(outdatedModules.indexOf(parentId) >= 0) continue; -/******/ if(parent.hot._acceptedDependencies[moduleId]) { -/******/ if(!outdatedDependencies[parentId]) -/******/ outdatedDependencies[parentId] = []; -/******/ addAllToSet(outdatedDependencies[parentId], [moduleId]); -/******/ continue; -/******/ } -/******/ delete outdatedDependencies[parentId]; -/******/ outdatedModules.push(parentId); -/******/ queue.push({ -/******/ chain: chain.concat([parentId]), -/******/ id: parentId -/******/ }); -/******/ } -/******/ } -/******/ -/******/ return { -/******/ type: "accepted", -/******/ moduleId: updateModuleId, -/******/ outdatedModules: outdatedModules, -/******/ outdatedDependencies: outdatedDependencies -/******/ }; -/******/ } -/******/ -/******/ function addAllToSet(a, b) { -/******/ for(var i = 0; i < b.length; i++) { -/******/ var item = b[i]; -/******/ if(a.indexOf(item) < 0) -/******/ a.push(item); -/******/ } -/******/ } -/******/ -/******/ // at begin all updates modules are outdated -/******/ // the "outdated" status can propagate to parents if they don't accept the children -/******/ var outdatedDependencies = {}; -/******/ var outdatedModules = []; -/******/ var appliedUpdate = {}; -/******/ -/******/ var warnUnexpectedRequire = function warnUnexpectedRequire() { -/******/ console.warn("[HMR] unexpected require(" + result.moduleId + ") to disposed module"); -/******/ }; -/******/ -/******/ for(var id in hotUpdate) { -/******/ if(Object.prototype.hasOwnProperty.call(hotUpdate, id)) { -/******/ moduleId = toModuleId(id); -/******/ var result; -/******/ if(hotUpdate[id]) { -/******/ result = getAffectedStuff(moduleId); -/******/ } else { -/******/ result = { -/******/ type: "disposed", -/******/ moduleId: id -/******/ }; -/******/ } -/******/ var abortError = false; -/******/ var doApply = false; -/******/ var doDispose = false; -/******/ var chainInfo = ""; -/******/ if(result.chain) { -/******/ chainInfo = "\nUpdate propagation: " + result.chain.join(" -> "); -/******/ } -/******/ switch(result.type) { -/******/ case "self-declined": -/******/ if(options.onDeclined) -/******/ options.onDeclined(result); -/******/ if(!options.ignoreDeclined) -/******/ abortError = new Error("Aborted because of self decline: " + result.moduleId + chainInfo); -/******/ break; -/******/ case "declined": -/******/ if(options.onDeclined) -/******/ options.onDeclined(result); -/******/ if(!options.ignoreDeclined) -/******/ abortError = new Error("Aborted because of declined dependency: " + result.moduleId + " in " + result.parentId + chainInfo); -/******/ break; -/******/ case "unaccepted": -/******/ if(options.onUnaccepted) -/******/ options.onUnaccepted(result); -/******/ if(!options.ignoreUnaccepted) -/******/ abortError = new Error("Aborted because " + moduleId + " is not accepted" + chainInfo); -/******/ break; -/******/ case "accepted": -/******/ if(options.onAccepted) -/******/ options.onAccepted(result); -/******/ doApply = true; -/******/ break; -/******/ case "disposed": -/******/ if(options.onDisposed) -/******/ options.onDisposed(result); -/******/ doDispose = true; -/******/ break; -/******/ default: -/******/ throw new Error("Unexception type " + result.type); -/******/ } -/******/ if(abortError) { -/******/ hotSetStatus("abort"); -/******/ return Promise.reject(abortError); -/******/ } -/******/ if(doApply) { -/******/ appliedUpdate[moduleId] = hotUpdate[moduleId]; -/******/ addAllToSet(outdatedModules, result.outdatedModules); -/******/ for(moduleId in result.outdatedDependencies) { -/******/ if(Object.prototype.hasOwnProperty.call(result.outdatedDependencies, moduleId)) { -/******/ if(!outdatedDependencies[moduleId]) -/******/ outdatedDependencies[moduleId] = []; -/******/ addAllToSet(outdatedDependencies[moduleId], result.outdatedDependencies[moduleId]); -/******/ } -/******/ } -/******/ } -/******/ if(doDispose) { -/******/ addAllToSet(outdatedModules, [result.moduleId]); -/******/ appliedUpdate[moduleId] = warnUnexpectedRequire; -/******/ } -/******/ } -/******/ } -/******/ -/******/ // Store self accepted outdated modules to require them later by the module system -/******/ var outdatedSelfAcceptedModules = []; -/******/ for(i = 0; i < outdatedModules.length; i++) { -/******/ moduleId = outdatedModules[i]; -/******/ if(installedModules[moduleId] && installedModules[moduleId].hot._selfAccepted) -/******/ outdatedSelfAcceptedModules.push({ -/******/ module: moduleId, -/******/ errorHandler: installedModules[moduleId].hot._selfAccepted -/******/ }); -/******/ } -/******/ -/******/ // Now in "dispose" phase -/******/ hotSetStatus("dispose"); -/******/ Object.keys(hotAvailableFilesMap).forEach(function(chunkId) { -/******/ if(hotAvailableFilesMap[chunkId] === false) { -/******/ hotDisposeChunk(chunkId); -/******/ } -/******/ }); -/******/ -/******/ var idx; -/******/ var queue = outdatedModules.slice(); -/******/ while(queue.length > 0) { -/******/ moduleId = queue.pop(); -/******/ module = installedModules[moduleId]; -/******/ if(!module) continue; -/******/ -/******/ var data = {}; -/******/ -/******/ // Call dispose handlers -/******/ var disposeHandlers = module.hot._disposeHandlers; -/******/ for(j = 0; j < disposeHandlers.length; j++) { -/******/ cb = disposeHandlers[j]; -/******/ cb(data); -/******/ } -/******/ hotCurrentModuleData[moduleId] = data; -/******/ -/******/ // disable module (this disables requires from this module) -/******/ module.hot.active = false; -/******/ -/******/ // remove module from cache -/******/ delete installedModules[moduleId]; -/******/ -/******/ // when disposing there is no need to call dispose handler -/******/ delete outdatedDependencies[moduleId]; -/******/ -/******/ // remove "parents" references from all children -/******/ for(j = 0; j < module.children.length; j++) { -/******/ var child = installedModules[module.children[j]]; -/******/ if(!child) continue; -/******/ idx = child.parents.indexOf(moduleId); -/******/ if(idx >= 0) { -/******/ child.parents.splice(idx, 1); -/******/ } -/******/ } -/******/ } -/******/ -/******/ // remove outdated dependency from module children -/******/ var dependency; -/******/ var moduleOutdatedDependencies; -/******/ for(moduleId in outdatedDependencies) { -/******/ if(Object.prototype.hasOwnProperty.call(outdatedDependencies, moduleId)) { -/******/ module = installedModules[moduleId]; -/******/ if(module) { -/******/ moduleOutdatedDependencies = outdatedDependencies[moduleId]; -/******/ for(j = 0; j < moduleOutdatedDependencies.length; j++) { -/******/ dependency = moduleOutdatedDependencies[j]; -/******/ idx = module.children.indexOf(dependency); -/******/ if(idx >= 0) module.children.splice(idx, 1); -/******/ } -/******/ } -/******/ } -/******/ } -/******/ -/******/ // Not in "apply" phase -/******/ hotSetStatus("apply"); -/******/ -/******/ hotCurrentHash = hotUpdateNewHash; -/******/ -/******/ // insert new code -/******/ for(moduleId in appliedUpdate) { -/******/ if(Object.prototype.hasOwnProperty.call(appliedUpdate, moduleId)) { -/******/ modules[moduleId] = appliedUpdate[moduleId]; -/******/ } -/******/ } -/******/ -/******/ // call accept handlers -/******/ var error = null; -/******/ for(moduleId in outdatedDependencies) { -/******/ if(Object.prototype.hasOwnProperty.call(outdatedDependencies, moduleId)) { -/******/ module = installedModules[moduleId]; -/******/ if(module) { -/******/ moduleOutdatedDependencies = outdatedDependencies[moduleId]; -/******/ var callbacks = []; -/******/ for(i = 0; i < moduleOutdatedDependencies.length; i++) { -/******/ dependency = moduleOutdatedDependencies[i]; -/******/ cb = module.hot._acceptedDependencies[dependency]; -/******/ if(cb) { -/******/ if(callbacks.indexOf(cb) >= 0) continue; -/******/ callbacks.push(cb); -/******/ } -/******/ } -/******/ for(i = 0; i < callbacks.length; i++) { -/******/ cb = callbacks[i]; -/******/ try { -/******/ cb(moduleOutdatedDependencies); -/******/ } catch(err) { -/******/ if(options.onErrored) { -/******/ options.onErrored({ -/******/ type: "accept-errored", -/******/ moduleId: moduleId, -/******/ dependencyId: moduleOutdatedDependencies[i], -/******/ error: err -/******/ }); -/******/ } -/******/ if(!options.ignoreErrored) { -/******/ if(!error) -/******/ error = err; -/******/ } -/******/ } -/******/ } -/******/ } -/******/ } -/******/ } -/******/ -/******/ // Load self accepted modules -/******/ for(i = 0; i < outdatedSelfAcceptedModules.length; i++) { -/******/ var item = outdatedSelfAcceptedModules[i]; -/******/ moduleId = item.module; -/******/ hotCurrentParents = [moduleId]; -/******/ try { -/******/ __webpack_require__(moduleId); -/******/ } catch(err) { -/******/ if(typeof item.errorHandler === "function") { -/******/ try { -/******/ item.errorHandler(err); -/******/ } catch(err2) { -/******/ if(options.onErrored) { -/******/ options.onErrored({ -/******/ type: "self-accept-error-handler-errored", -/******/ moduleId: moduleId, -/******/ error: err2, -/******/ originalError: err -/******/ }); -/******/ } -/******/ if(!options.ignoreErrored) { -/******/ if(!error) -/******/ error = err2; -/******/ } -/******/ if(!error) -/******/ error = err; -/******/ } -/******/ } else { -/******/ if(options.onErrored) { -/******/ options.onErrored({ -/******/ type: "self-accept-errored", -/******/ moduleId: moduleId, -/******/ error: err -/******/ }); -/******/ } -/******/ if(!options.ignoreErrored) { -/******/ if(!error) -/******/ error = err; -/******/ } -/******/ } -/******/ } -/******/ } -/******/ -/******/ // handle errors in accept handlers and self accepted module load -/******/ if(error) { -/******/ hotSetStatus("fail"); -/******/ return Promise.reject(error); -/******/ } -/******/ -/******/ hotSetStatus("idle"); -/******/ return new Promise(function(resolve) { -/******/ resolve(outdatedModules); -/******/ }); -/******/ } -/******/ -/******/ // The module cache -/******/ var installedModules = {}; -/******/ -/******/ // 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: {}, -/******/ hot: hotCreateModule(moduleId), -/******/ parents: (hotCurrentParentsTemp = hotCurrentParents, hotCurrentParents = [], hotCurrentParentsTemp), -/******/ children: [] -/******/ }; -/******/ -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, hotCreateRequire(moduleId)); -/******/ -/******/ // Flag the module as loaded -/******/ module.l = true; -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/******/ -/******/ // expose the modules object (__webpack_modules__) -/******/ __webpack_require__.m = modules; -/******/ -/******/ // expose the module cache -/******/ __webpack_require__.c = installedModules; -/******/ -/******/ // define getter function for harmony exports -/******/ __webpack_require__.d = function(exports, name, getter) { -/******/ if(!__webpack_require__.o(exports, name)) { -/******/ Object.defineProperty(exports, name, { -/******/ configurable: false, -/******/ enumerable: true, -/******/ get: getter -/******/ }); -/******/ } -/******/ }; -/******/ -/******/ // getDefaultExport function for compatibility with non-harmony modules -/******/ __webpack_require__.n = function(module) { -/******/ var getter = module && module.__esModule ? -/******/ function getDefault() { return module['default']; } : -/******/ function getModuleExports() { return module; }; -/******/ __webpack_require__.d(getter, 'a', getter); -/******/ return getter; -/******/ }; -/******/ -/******/ // Object.prototype.hasOwnProperty.call -/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; -/******/ -/******/ // __webpack_public_path__ -/******/ __webpack_require__.p = ""; -/******/ -/******/ // __webpack_hash__ -/******/ __webpack_require__.h = function() { return hotCurrentHash; }; -/******/ -/******/ // Load entry module and return exports -/******/ return hotCreateRequire("./index.js")(__webpack_require__.s = "./index.js"); -/******/ }) -/************************************************************************/ -/******/ ({ - -/***/ "../../update.js": -/*!*****************************************!*\ - !*** (webpack)/test/hotCases/update.js ***! - \*****************************************/ -/***/ (function(module, exports) { - -module.exports = function(done, options, callback) { - return function(stats) { - module.hot.check(options || true).then(function() { - if(callback) - callback(stats); - }).catch(function(err) { - done(err); - }); - } -}; - - -/***/ }), - -/***/ "./file.js": -/*!*****************!*\ - !*** ./file.js ***! - \*****************/ -/***/ (function(module, exports) { - -throw new Error("Module parse failed: Unexpected token (3:0)\nYou may need an appropriate loader to handle this file type.\n| export var value = 1;\r\n| ---\r\n| export var value = 2;\r\n| "); - -/***/ }), - -/***/ "./index.js": -/*!******************!*\ - !*** ./index.js ***! - \******************/ -/***/ (function(module, __webpack_exports__, __webpack_require__) { - -"use strict"; -/* harmony import */ var _file__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./file */"./file.js"); -/* harmony import */ var _file__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_file__WEBPACK_IMPORTED_MODULE_0__); - - -it("should auto-import a ES6 imported value on accept", function(done) { - expect(_file__WEBPACK_IMPORTED_MODULE_0__["value"]).toEqual(1); - module.hot.accept(/*! ./file */ "./file.js", function(__WEBPACK_OUTDATED_DEPENDENCIES__) { /* harmony import */ _file__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./file */"./file.js"); /* harmony import */ _file__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_file__WEBPACK_IMPORTED_MODULE_0__); (function() { - expect(_file__WEBPACK_IMPORTED_MODULE_0__["value"]).toEqual(2); - outside(); - done(); - })(__WEBPACK_OUTDATED_DEPENDENCIES__); }); - NEXT(__webpack_require__(/*! ../../update */ "../../update.js")(done)); -}); - -function outside() { - expect(_file__WEBPACK_IMPORTED_MODULE_0__["value"]).toEqual(2); -} - - -/***/ }) - -/******/ }); \ No newline at end of file From deaafc9dead9956f8b966aacd6c0382347bd2bd5 Mon Sep 17 00:00:00 2001 From: Sven SAULEAU Date: Fri, 1 Jun 2018 15:24:16 +0200 Subject: [PATCH 22/36] chore: bump webassemblyjs --- package.json | 8 +-- yarn.lock | 191 ++++++++++++++++++++++++++------------------------- 2 files changed, 103 insertions(+), 96 deletions(-) diff --git a/package.json b/package.json index eafde698f23..361e9c691ee 100644 --- a/package.json +++ b/package.json @@ -5,10 +5,10 @@ "description": "Packs CommonJs/AMD modules for the browser. Allows to split your codebase into multiple bundles, which can be loaded on demand. Support loaders to preprocess files, i.e. json, jsx, es7, css, less, ... and your custom stuff.", "license": "MIT", "dependencies": { - "@webassemblyjs/ast": "1.5.9", - "@webassemblyjs/wasm-edit": "1.5.9", - "@webassemblyjs/wasm-opt": "1.5.9", - "@webassemblyjs/wasm-parser": "1.5.9", + "@webassemblyjs/ast": "1.5.10", + "@webassemblyjs/wasm-edit": "1.5.10", + "@webassemblyjs/wasm-opt": "1.5.10", + "@webassemblyjs/wasm-parser": "1.5.10", "acorn": "^5.0.0", "acorn-dynamic-import": "^3.0.0", "ajv": "^6.1.0", diff --git a/yarn.lock b/yarn.lock index 7207c7e698d..a6580f4704b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -34,132 +34,139 @@ version "1.0.2" resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.2.tgz#e13182e1b69871a422d7863e11a4a6f5b814a4bd" -"@webassemblyjs/ast@1.5.9": - version "1.5.9" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.5.9.tgz#b2770182678691ab4949d593105c15d4074fedb6" +"@webassemblyjs/ast@1.5.10": + version "1.5.10" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.5.10.tgz#7f1e81149ca4e103c9e7cc321ea0dcb83a392512" dependencies: - "@webassemblyjs/helper-module-context" "1.5.9" - "@webassemblyjs/helper-wasm-bytecode" "1.5.9" - "@webassemblyjs/wast-parser" "1.5.9" + "@webassemblyjs/helper-module-context" "1.5.10" + "@webassemblyjs/helper-wasm-bytecode" "1.5.10" + "@webassemblyjs/wast-parser" "1.5.10" debug "^3.1.0" mamacro "^0.0.3" -"@webassemblyjs/floating-point-hex-parser@1.5.9": - version "1.5.9" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.5.9.tgz#ee56243f6ba30781ff6f92fe7f1c377255219a7c" +"@webassemblyjs/floating-point-hex-parser@1.5.10": + version "1.5.10" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.5.10.tgz#ae48705fd58927df62023f114520b8215330ff86" -"@webassemblyjs/helper-api-error@1.5.9": - version "1.5.9" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.5.9.tgz#c80e204afe1ae102c23b0357f1ec25aeb61022a2" +"@webassemblyjs/helper-api-error@1.5.10": + version "1.5.10" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.5.10.tgz#0baf9453ce2fd8db58f0fdb4fb2852557c71d5a7" -"@webassemblyjs/helper-buffer@1.5.9": - version "1.5.9" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.5.9.tgz#90d99afcb0fdc1ee11bc403894f3ae37cd926a81" +"@webassemblyjs/helper-buffer@1.5.10": + version "1.5.10" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.5.10.tgz#abee4284161e9cd6ba7619785ca277bfcb8052ce" dependencies: debug "^3.1.0" -"@webassemblyjs/helper-code-frame@1.5.9": - version "1.5.9" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.5.9.tgz#b56ac06a39c3e1cfefcc421ade1ee471a738a570" +"@webassemblyjs/helper-code-frame@1.5.10": + version "1.5.10" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.5.10.tgz#4e23c05431665f16322104580af7c06253d4b4e0" dependencies: - "@webassemblyjs/wast-printer" "1.5.9" + "@webassemblyjs/wast-printer" "1.5.10" -"@webassemblyjs/helper-fsm@1.5.9": - version "1.5.9" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.5.9.tgz#8f996268eb07ee6728130a9e97fa3aac32772454" +"@webassemblyjs/helper-fsm@1.5.10": + version "1.5.10" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.5.10.tgz#490bab613ea255a9272b764826d3cc9d15170676" -"@webassemblyjs/helper-module-context@1.5.9": - version "1.5.9" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.5.9.tgz#69e2eea310f755a0b750b84f8af59f890f2046ac" +"@webassemblyjs/helper-module-context@1.5.10": + version "1.5.10" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.5.10.tgz#6fca93585228bf33e6da076d0a1373db1fdd6580" + dependencies: + mamacro "^0.0.3" -"@webassemblyjs/helper-wasm-bytecode@1.5.9": - version "1.5.9" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.5.9.tgz#467ba0f9e4d0e4a48bf1c5107b9f4abe3ca1171a" +"@webassemblyjs/helper-wasm-bytecode@1.5.10": + version "1.5.10" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.5.10.tgz#90f6da93c7a186bfb2f587de442982ff533c4b44" -"@webassemblyjs/helper-wasm-section@1.5.9": - version "1.5.9" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.5.9.tgz#aec9486ab5d56e3cb5252a7ed88777b6792ac624" +"@webassemblyjs/helper-wasm-section@1.5.10": + version "1.5.10" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.5.10.tgz#d64292a19f7f357c49719461065efdf7ec975d66" dependencies: - "@webassemblyjs/ast" "1.5.9" - "@webassemblyjs/helper-buffer" "1.5.9" - "@webassemblyjs/helper-wasm-bytecode" "1.5.9" - "@webassemblyjs/wasm-gen" "1.5.9" + "@webassemblyjs/ast" "1.5.10" + "@webassemblyjs/helper-buffer" "1.5.10" + "@webassemblyjs/helper-wasm-bytecode" "1.5.10" + "@webassemblyjs/wasm-gen" "1.5.10" debug "^3.1.0" -"@webassemblyjs/ieee754@1.5.9": - version "1.5.9" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.5.9.tgz#846856ece040c7debd5b5645b319c26523613bcf" +"@webassemblyjs/ieee754@1.5.10": + version "1.5.10" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.5.10.tgz#257cad440dd6c8a339402d31e035ba2e38e9c245" dependencies: ieee754 "^1.1.11" -"@webassemblyjs/leb128@1.5.9": - version "1.5.9" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.5.9.tgz#7249443a0fd7574a7e3c1c39532535c735390bbc" +"@webassemblyjs/leb128@1.5.10": + version "1.5.10" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.5.10.tgz#a8e4fe5f4b16daadb241fcc44d9735e9f27b05a3" dependencies: leb "^0.3.0" -"@webassemblyjs/wasm-edit@1.5.9": - version "1.5.9" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.5.9.tgz#9b8e054b2d305a7e0528088571c95904bd73df48" - dependencies: - "@webassemblyjs/ast" "1.5.9" - "@webassemblyjs/helper-buffer" "1.5.9" - "@webassemblyjs/helper-wasm-bytecode" "1.5.9" - "@webassemblyjs/helper-wasm-section" "1.5.9" - "@webassemblyjs/wasm-gen" "1.5.9" - "@webassemblyjs/wasm-opt" "1.5.9" - "@webassemblyjs/wasm-parser" "1.5.9" - "@webassemblyjs/wast-printer" "1.5.9" +"@webassemblyjs/utf8@1.5.10": + version "1.5.10" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.5.10.tgz#0b3b6bc86b7619c5dc7b2789db6665aa35689983" + +"@webassemblyjs/wasm-edit@1.5.10": + version "1.5.10" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.5.10.tgz#0fe80f19e57f669eab1caa8c1faf9690b259d5b9" + dependencies: + "@webassemblyjs/ast" "1.5.10" + "@webassemblyjs/helper-buffer" "1.5.10" + "@webassemblyjs/helper-wasm-bytecode" "1.5.10" + "@webassemblyjs/helper-wasm-section" "1.5.10" + "@webassemblyjs/wasm-gen" "1.5.10" + "@webassemblyjs/wasm-opt" "1.5.10" + "@webassemblyjs/wasm-parser" "1.5.10" + "@webassemblyjs/wast-printer" "1.5.10" debug "^3.1.0" -"@webassemblyjs/wasm-gen@1.5.9": - version "1.5.9" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.5.9.tgz#85e07c047fab917e06b18dee4d16342a2fd3c59c" +"@webassemblyjs/wasm-gen@1.5.10": + version "1.5.10" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.5.10.tgz#8b29ddd3651259408ae5d5c816a011fb3f3f3584" dependencies: - "@webassemblyjs/ast" "1.5.9" - "@webassemblyjs/helper-wasm-bytecode" "1.5.9" - "@webassemblyjs/ieee754" "1.5.9" - "@webassemblyjs/leb128" "1.5.9" + "@webassemblyjs/ast" "1.5.10" + "@webassemblyjs/helper-wasm-bytecode" "1.5.10" + "@webassemblyjs/ieee754" "1.5.10" + "@webassemblyjs/leb128" "1.5.10" + "@webassemblyjs/utf8" "1.5.10" -"@webassemblyjs/wasm-opt@1.5.9": - version "1.5.9" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.5.9.tgz#ccac17c41a044c167bc95d3e8645cf889a137ce5" +"@webassemblyjs/wasm-opt@1.5.10": + version "1.5.10" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.5.10.tgz#569e45ab1b2bf0a7706cdf6d1b51d1188e9e4c7b" dependencies: - "@webassemblyjs/ast" "1.5.9" - "@webassemblyjs/helper-buffer" "1.5.9" - "@webassemblyjs/wasm-gen" "1.5.9" - "@webassemblyjs/wasm-parser" "1.5.9" + "@webassemblyjs/ast" "1.5.10" + "@webassemblyjs/helper-buffer" "1.5.10" + "@webassemblyjs/wasm-gen" "1.5.10" + "@webassemblyjs/wasm-parser" "1.5.10" debug "^3.1.0" -"@webassemblyjs/wasm-parser@1.5.9": - version "1.5.9" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.5.9.tgz#ddab84da4957b64aafbc61e4ab706cc667082f32" - dependencies: - "@webassemblyjs/ast" "1.5.9" - "@webassemblyjs/helper-api-error" "1.5.9" - "@webassemblyjs/helper-wasm-bytecode" "1.5.9" - "@webassemblyjs/ieee754" "1.5.9" - "@webassemblyjs/leb128" "1.5.9" - "@webassemblyjs/wasm-parser" "1.5.9" - -"@webassemblyjs/wast-parser@1.5.9": - version "1.5.9" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.5.9.tgz#193d24ccf4742a5f8f1915936680ab2314011df2" - dependencies: - "@webassemblyjs/ast" "1.5.9" - "@webassemblyjs/floating-point-hex-parser" "1.5.9" - "@webassemblyjs/helper-api-error" "1.5.9" - "@webassemblyjs/helper-code-frame" "1.5.9" - "@webassemblyjs/helper-fsm" "1.5.9" +"@webassemblyjs/wasm-parser@1.5.10": + version "1.5.10" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.5.10.tgz#3e1017e49f833f46b840db7cf9d194d4f00037ff" + dependencies: + "@webassemblyjs/ast" "1.5.10" + "@webassemblyjs/helper-api-error" "1.5.10" + "@webassemblyjs/helper-wasm-bytecode" "1.5.10" + "@webassemblyjs/ieee754" "1.5.10" + "@webassemblyjs/leb128" "1.5.10" + "@webassemblyjs/wasm-parser" "1.5.10" + +"@webassemblyjs/wast-parser@1.5.10": + version "1.5.10" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.5.10.tgz#1a3235926483c985a00ee8ebca856ffda9544934" + dependencies: + "@webassemblyjs/ast" "1.5.10" + "@webassemblyjs/floating-point-hex-parser" "1.5.10" + "@webassemblyjs/helper-api-error" "1.5.10" + "@webassemblyjs/helper-code-frame" "1.5.10" + "@webassemblyjs/helper-fsm" "1.5.10" long "^3.2.0" mamacro "^0.0.3" -"@webassemblyjs/wast-printer@1.5.9": - version "1.5.9" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.5.9.tgz#16605d90a481c01a130b7c4edeb2bce503787eb4" +"@webassemblyjs/wast-printer@1.5.10": + version "1.5.10" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.5.10.tgz#adb38831ba45efd0a5c7971b666e179b64f68bba" dependencies: - "@webassemblyjs/ast" "1.5.9" - "@webassemblyjs/wast-parser" "1.5.9" + "@webassemblyjs/ast" "1.5.10" + "@webassemblyjs/wast-parser" "1.5.10" long "^3.2.0" abab@^1.0.4: From 530e1fb172be65c4a4107f4d48961c7a19cf2632 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Fri, 1 Jun 2018 14:54:54 +0200 Subject: [PATCH 23/36] Add matchResource feature (for loaders) Match rules with custom resource name Also use this name as rule.issuer or splitChunks test Show nicely in stats --- lib/NormalModule.js | 28 ++++++++--- lib/NormalModuleFactory.js | 49 ++++++++++++++----- lib/RequestShortener.js | 2 + lib/RuleSet.js | 12 +++++ test/NormalModule.unittest.js | 16 +++--- test/cases/wasm/two-files-loader/index.js | 11 +++++ test/cases/wasm/two-files-loader/src/wasm.dat | 8 +++ .../wasm/two-files-loader/test.filter.js | 5 ++ .../wasm/two-files-loader/wrapper-loader.js | 17 +++++++ .../wasm/two-files-loader/wrapper-loader2.js | 18 +++++++ 10 files changed, 140 insertions(+), 26 deletions(-) create mode 100644 test/cases/wasm/two-files-loader/index.js create mode 100644 test/cases/wasm/two-files-loader/src/wasm.dat create mode 100644 test/cases/wasm/two-files-loader/test.filter.js create mode 100644 test/cases/wasm/two-files-loader/wrapper-loader.js create mode 100644 test/cases/wasm/two-files-loader/wrapper-loader2.js diff --git a/lib/NormalModule.js b/lib/NormalModule.js index 26ed491f944..974e5be54f0 100644 --- a/lib/NormalModule.js +++ b/lib/NormalModule.js @@ -43,9 +43,18 @@ const contextify = (context, request) => { .split("!") .map(r => { const splitPath = r.split("?"); - splitPath[0] = path.relative(context, splitPath[0]); - if (path.sep === "\\") splitPath[0] = splitPath[0].replace(/\\/g, "/"); - if (splitPath[0].indexOf("../") !== 0) splitPath[0] = "./" + splitPath[0]; + if (/^[a-zA-Z]:\\/.test(splitPath[0])) { + splitPath[0] = path.win32.relative(context, splitPath[0]); + if (!/^[a-zA-Z]:\\/.test(splitPath[0])) { + splitPath[0] = splitPath[0].replace(/\\/g, "/"); + } + } + if (/^\//.test(splitPath[0])) { + splitPath[0] = path.posix.relative(context, splitPath[0]); + } + if (!/^(\.\.\/|\/|[a-zA-Z]:\\)/.test(splitPath[0])) { + splitPath[0] = "./" + splitPath[0]; + } return splitPath.join("?"); }) .join("!"); @@ -76,6 +85,7 @@ class NormalModule extends Module { rawRequest, loaders, resource, + matchResource, parser, generator, resolveOptions @@ -90,6 +100,7 @@ class NormalModule extends Module { this.parser = parser; this.generator = generator; this.resource = resource; + this.matchResource = matchResource; this.loaders = loaders; if (resolveOptions !== undefined) this.resolveOptions = resolveOptions; @@ -123,16 +134,21 @@ class NormalModule extends Module { } nameForCondition() { - const idx = this.resource.indexOf("?"); - if (idx >= 0) return this.resource.substr(0, idx); - return this.resource; + const resource = this.matchResource || this.resource; + const idx = resource.indexOf("?"); + if (idx >= 0) return resource.substr(0, idx); + return resource; } updateCacheModule(module) { + this.type = module.type; + this.request = module.request; this.userRequest = module.userRequest; + this.rawRequest = module.rawRequest; this.parser = module.parser; this.generator = module.generator; this.resource = module.resource; + this.matchResource = module.matchResource; this.loaders = module.loaders; this.resolveOptions = module.resolveOptions; } diff --git a/lib/NormalModuleFactory.js b/lib/NormalModuleFactory.js index 11dc42c75c1..23ef0ae1dde 100644 --- a/lib/NormalModuleFactory.js +++ b/lib/NormalModuleFactory.js @@ -4,6 +4,7 @@ */ "use strict"; +const path = require("path"); const asyncLib = require("neo-async"); const { Tapable, @@ -20,6 +21,8 @@ const cachedMerge = require("./util/cachedMerge"); const EMPTY_RESOLVE_OPTIONS = {}; +const MATCH_RESOURCE_REGEX = /^([^!]+)!=!/; + const loaderToIdent = data => { if (!data.options) { return data.loader; @@ -158,19 +161,33 @@ class NormalModuleFactory extends Tapable { const context = data.context; const request = data.request; - const noPreAutoLoaders = request.startsWith("-!"); - const noAutoLoaders = noPreAutoLoaders || request.startsWith("!"); - const noPrePostAutoLoaders = request.startsWith("!!"); - let elements = request + const loaderResolver = this.getResolver("loader"); + const normalResolver = this.getResolver("normal", data.resolveOptions); + + let matchResource = undefined; + let requestWithoutMatchResource = request; + const matchResourceMatch = MATCH_RESOURCE_REGEX.exec(request); + if (matchResourceMatch) { + matchResource = matchResourceMatch[1]; + if (/^\.\.?\//.test(matchResource)) { + matchResource = path.join(context, matchResource); + } + requestWithoutMatchResource = request.substr( + matchResourceMatch[0].length + ); + } + + const noPreAutoLoaders = requestWithoutMatchResource.startsWith("-!"); + const noAutoLoaders = + noPreAutoLoaders || requestWithoutMatchResource.startsWith("!"); + const noPrePostAutoLoaders = requestWithoutMatchResource.startsWith("!!"); + let elements = requestWithoutMatchResource .replace(/^-?!+/, "") .replace(/!!+/g, "!") .split("!"); let resource = elements.pop(); elements = elements.map(identToLoaderRequest); - const loaderResolver = this.getResolver("loader"); - const normalResolver = this.getResolver("normal", data.resolveOptions); - asyncLib.parallel( [ callback => @@ -234,12 +251,15 @@ class NormalModuleFactory extends Tapable { ); } - const userRequest = loaders - .map(loaderToIdent) - .concat([resource]) - .join("!"); + const userRequest = + (matchResource !== undefined ? `${matchResource}!=!` : "") + + loaders + .map(loaderToIdent) + .concat([resource]) + .join("!"); - let resourcePath = resource; + let resourcePath = + matchResource !== undefined ? matchResource : resource; let resourceQuery = ""; const queryIndex = resourcePath.indexOf("?"); if (queryIndex >= 0) { @@ -249,6 +269,10 @@ class NormalModuleFactory extends Tapable { const result = this.ruleSet.exec({ resource: resourcePath, + realResource: + matchResource !== undefined + ? resource.replace(/\?.*/, "") + : resourcePath, resourceQuery, issuer: contextInfo.issuer, compiler: contextInfo.compiler @@ -326,6 +350,7 @@ class NormalModuleFactory extends Tapable { rawRequest: request, loaders, resource, + matchResource, resourceResolveData, settings, type, diff --git a/lib/RequestShortener.js b/lib/RequestShortener.js index e3e080b9ff3..7b007816a8c 100644 --- a/lib/RequestShortener.js +++ b/lib/RequestShortener.js @@ -10,6 +10,7 @@ const PATH_CHARS_REGEXP = /[-[\]{}()*+?.,\\^$|#\s]/g; const SEPARATOR_REGEXP = /[/\\]$/; const FRONT_OR_BACK_BANG_REGEXP = /^!|!$/g; const INDEX_JS_REGEXP = /\/index.js(!|\?|\(query\))/g; +const MATCH_RESOURCE_REGEXP = /!=!/; const normalizeBackSlashDirection = request => { return request.replace(NORMALIZE_SLASH_DIRECTION_REGEXP, "/"); @@ -73,6 +74,7 @@ class RequestShortener { } result = result.replace(INDEX_JS_REGEXP, "$1"); result = result.replace(FRONT_OR_BACK_BANG_REGEXP, ""); + result = result.replace(MATCH_RESOURCE_REGEXP, " = "); this.cache.set(request, result); return result; } diff --git a/lib/RuleSet.js b/lib/RuleSet.js index 2013a26d7e0..abc44c1a9b4 100644 --- a/lib/RuleSet.js +++ b/lib/RuleSet.js @@ -203,6 +203,14 @@ module.exports = class RuleSet { } } + if (rule.realResource) { + try { + newRule.realResource = RuleSet.normalizeCondition(rule.realResource); + } catch (error) { + throw new Error(RuleSet.buildErrorMessage(rule.realResource, error)); + } + } + if (rule.resourceQuery) { try { newRule.resourceQuery = RuleSet.normalizeCondition(rule.resourceQuery); @@ -477,10 +485,13 @@ module.exports = class RuleSet { _run(data, rule, result) { // test conditions if (rule.resource && !data.resource) return false; + if (rule.realResource && !data.realResource) return false; if (rule.resourceQuery && !data.resourceQuery) return false; if (rule.compiler && !data.compiler) return false; if (rule.issuer && !data.issuer) return false; if (rule.resource && !rule.resource(data.resource)) return false; + if (rule.realResource && !rule.realResource(data.realResource)) + return false; if (data.issuer && rule.issuer && !rule.issuer(data.issuer)) return false; if ( data.resourceQuery && @@ -497,6 +508,7 @@ module.exports = class RuleSet { const keys = Object.keys(rule).filter(key => { return ![ "resource", + "realResource", "resourceQuery", "compiler", "issuer", diff --git a/test/NormalModule.unittest.js b/test/NormalModule.unittest.js index a635b1c2df1..329001bc23b 100644 --- a/test/NormalModule.unittest.js +++ b/test/NormalModule.unittest.js @@ -16,11 +16,11 @@ describe("NormalModule", () => { let resource; let parser; beforeEach(() => { - request = "some/request"; - userRequest = "some/userRequest"; + request = "/some/request"; + userRequest = "/some/userRequest"; rawRequest = "some/rawRequest"; loaders = []; - resource = "some/resource"; + resource = "/some/resource"; parser = { parse() {} }; @@ -66,14 +66,14 @@ describe("NormalModule", () => { it("contextifies the userRequest of the module", () => { expect( normalModule.libIdent({ - context: "some/context" + context: "/some/context" }) ).toBe("../userRequest"); }); describe("given a userRequest containing loaders", () => { beforeEach(() => { userRequest = - "some/userRequest!some/other/userRequest!some/thing/is/off/here"; + "/some/userRequest!/some/other/userRequest!/some/thing/is/off/here"; normalModule = new NormalModule({ type: "javascript/auto", request, @@ -87,7 +87,7 @@ describe("NormalModule", () => { it("contextifies every path in the userRequest", () => { expect( normalModule.libIdent({ - context: "some/context" + context: "/some/context" }) ).toBe("../userRequest!../other/userRequest!../thing/is/off/here"); }); @@ -95,7 +95,7 @@ describe("NormalModule", () => { describe("given a userRequest containing query parameters", () => { it("ignores paths in query parameters", () => { userRequest = - "some/context/loader?query=foo\\bar&otherPath=testpath/other"; + "F:\\some\\context\\loader?query=foo\\bar&otherPath=testpath/other"; normalModule = new NormalModule({ type: "javascript/auto", request, @@ -107,7 +107,7 @@ describe("NormalModule", () => { }); expect( normalModule.libIdent({ - context: "some/context" + context: "F:\\some\\context" }) ).toBe("./loader?query=foo\\bar&otherPath=testpath/other"); }); diff --git a/test/cases/wasm/two-files-loader/index.js b/test/cases/wasm/two-files-loader/index.js new file mode 100644 index 00000000000..36682a4ad1d --- /dev/null +++ b/test/cases/wasm/two-files-loader/index.js @@ -0,0 +1,11 @@ +it("should be able to create two modules from loader", function() { + return import("./wrapper-loader!./src/wasm.dat").then(function(wasm) { + expect(wasm.getString()).toEqual("Hello World"); + }); +}); + +it("should be able to create two modules from loader with remaining request", function() { + return import("./wrapper-loader2!./src/wasm.dat?2").then(function(wasm) { + expect(wasm.getString()).toEqual("Hello World"); + }); +}); diff --git a/test/cases/wasm/two-files-loader/src/wasm.dat b/test/cases/wasm/two-files-loader/src/wasm.dat new file mode 100644 index 00000000000..50335ed4944 --- /dev/null +++ b/test/cases/wasm/two-files-loader/src/wasm.dat @@ -0,0 +1,8 @@ +(module + (memory (export "memory") 1) + (data (i32.const 16) "Hello World\00") + (func (export "getString") (result i32) + (i32.const 16) + ) +) + diff --git a/test/cases/wasm/two-files-loader/test.filter.js b/test/cases/wasm/two-files-loader/test.filter.js new file mode 100644 index 00000000000..23177349638 --- /dev/null +++ b/test/cases/wasm/two-files-loader/test.filter.js @@ -0,0 +1,5 @@ +var supportsWebAssembly = require("../../../helpers/supportsWebAssembly"); + +module.exports = function(config) { + return supportsWebAssembly(); +}; diff --git a/test/cases/wasm/two-files-loader/wrapper-loader.js b/test/cases/wasm/two-files-loader/wrapper-loader.js new file mode 100644 index 00000000000..544fc1a789c --- /dev/null +++ b/test/cases/wasm/two-files-loader/wrapper-loader.js @@ -0,0 +1,17 @@ +const stringifyRequest = require("loader-utils").stringifyRequest; + +module.exports.pitch = function(remainingRequest) { + return ` + import { getString as _getString, memory } from ${stringifyRequest(this, + `${this.resourcePath}.wat!=!${remainingRequest}` + )}; + + export function getString() { + const strBuf = new Uint8Array(memory.buffer, _getString()); + const idx = strBuf.indexOf(0); + const strBuf2 = strBuf.slice(0, idx); + const str = Buffer.from(strBuf2).toString("utf-8"); + return str; + }; + `; +}; diff --git a/test/cases/wasm/two-files-loader/wrapper-loader2.js b/test/cases/wasm/two-files-loader/wrapper-loader2.js new file mode 100644 index 00000000000..6cd67a7258f --- /dev/null +++ b/test/cases/wasm/two-files-loader/wrapper-loader2.js @@ -0,0 +1,18 @@ +const stringifyRequest = require("loader-utils").stringifyRequest; + +module.exports.pitch = function(remainingRequest) { + return ` + import { getString as _getString, memory } from ${stringifyRequest( + this, + `${this.resourcePath}.wasm!=!wast-loader!${remainingRequest}` + )}; + + export function getString() { + const strBuf = new Uint8Array(memory.buffer, _getString()); + const idx = strBuf.indexOf(0); + const strBuf2 = strBuf.slice(0, idx); + const str = Buffer.from(strBuf2).toString("utf-8"); + return str; + }; + `; +}; From 8a6c722ca634148292b07007b33abcb41ffbecef Mon Sep 17 00:00:00 2001 From: Sven SAULEAU Date: Sat, 2 Jun 2018 15:51:26 +0200 Subject: [PATCH 24/36] fix(wasm): keep imports --- lib/wasm/WebAssemblyGenerator.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/wasm/WebAssemblyGenerator.js b/lib/wasm/WebAssemblyGenerator.js index 59c7fa198c0..415ec59db0e 100644 --- a/lib/wasm/WebAssemblyGenerator.js +++ b/lib/wasm/WebAssemblyGenerator.js @@ -282,9 +282,8 @@ const rewriteImports = ({ ast, usedDependencyMap }) => bin => { const result = usedDependencyMap.get( path.node.module + ":" + path.node.name ); - if (result === undefined) { - path.remove(); - } else { + + if (typeof result !== "undefined") { path.node.module = WebAssemblyUtils.MANGLED_MODULE; path.node.name = result.name; } From 9d1a3f75cc8d26bfccce1f1cb9b3b8ed44e3f2fd Mon Sep 17 00:00:00 2001 From: Sven SAULEAU Date: Tue, 29 May 2018 15:09:19 +0200 Subject: [PATCH 25/36] feat: add failing test --- test/cases/wasm/export-imported-global/env.js | 1 + test/cases/wasm/export-imported-global/index.js | 5 +++++ test/cases/wasm/export-imported-global/module.wat | 4 ++++ test/cases/wasm/export-imported-global/test.filter.js | 5 +++++ 4 files changed, 15 insertions(+) create mode 100644 test/cases/wasm/export-imported-global/env.js create mode 100644 test/cases/wasm/export-imported-global/index.js create mode 100644 test/cases/wasm/export-imported-global/module.wat create mode 100644 test/cases/wasm/export-imported-global/test.filter.js diff --git a/test/cases/wasm/export-imported-global/env.js b/test/cases/wasm/export-imported-global/env.js new file mode 100644 index 00000000000..39a36559da0 --- /dev/null +++ b/test/cases/wasm/export-imported-global/env.js @@ -0,0 +1 @@ +export const n = 1; diff --git a/test/cases/wasm/export-imported-global/index.js b/test/cases/wasm/export-imported-global/index.js new file mode 100644 index 00000000000..b5c32a260fe --- /dev/null +++ b/test/cases/wasm/export-imported-global/index.js @@ -0,0 +1,5 @@ +it("should export imported global", function() { + return import("./module.wat").then(function({v}) { + expect(v).toBe(1); + }); +}); diff --git a/test/cases/wasm/export-imported-global/module.wat b/test/cases/wasm/export-imported-global/module.wat new file mode 100644 index 00000000000..fc559c5b77b --- /dev/null +++ b/test/cases/wasm/export-imported-global/module.wat @@ -0,0 +1,4 @@ +(module + (import "./env.js" "n" (global i32)) + (export "v" (global 0)) +) diff --git a/test/cases/wasm/export-imported-global/test.filter.js b/test/cases/wasm/export-imported-global/test.filter.js new file mode 100644 index 00000000000..23177349638 --- /dev/null +++ b/test/cases/wasm/export-imported-global/test.filter.js @@ -0,0 +1,5 @@ +var supportsWebAssembly = require("../../../helpers/supportsWebAssembly"); + +module.exports = function(config) { + return supportsWebAssembly(); +}; From 1e4d2b7fe71a2633df6816b82411402136064159 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Sat, 2 Jun 2018 09:53:35 +0200 Subject: [PATCH 26/36] handle reexported wasm globals in JS wrapper code --- declarations.d.ts | 20 ++- .../WebAssemblyExportImportedDependency.js | 29 ++++ lib/wasm/WebAssemblyGenerator.js | 28 +++- lib/wasm/WebAssemblyJavascriptGenerator.js | 141 ++++++++++++------ lib/wasm/WebAssemblyModulesPlugin.js | 6 + lib/wasm/WebAssemblyParser.js | 49 +++++- .../wasm/export-imported-global/index.js | 3 +- .../wasm/export-imported-global/module.js | 1 + .../wasm/export-imported-global/module.wat | 2 + 9 files changed, 218 insertions(+), 61 deletions(-) create mode 100644 lib/dependencies/WebAssemblyExportImportedDependency.js create mode 100644 test/cases/wasm/export-imported-global/module.js diff --git a/declarations.d.ts b/declarations.d.ts index af1065ef3bd..5212d6c3256 100644 --- a/declarations.d.ts +++ b/declarations.d.ts @@ -36,6 +36,7 @@ declare module "@webassemblyjs/ast" { ModuleImport?: (p: NodePath) => void; ModuleExport?: (p: NodePath) => void; Start?: (p: NodePath) => void; + Global?: (p: NodePath) => void; } ); export class NodePath { @@ -60,16 +61,29 @@ declare module "@webassemblyjs/ast" { } export class ModuleExport extends Node { name: string; + descr: { + type: string; + exportType: string; + id?: Identifier; + }; } export class ModuleExportDescr extends Node {} export class IndexLiteral extends Node {} - export class NumberLiteral extends Node {} + export class NumberLiteral extends Node { + value: number; + raw: string; + } export class FloatLiteral extends Node {} - export class Global extends Node {} + export class Global extends Node { + init: Instruction[]; + } export class FuncParam extends Node { valtype: string; } - export class Instruction extends Node {} + export class Instruction extends Node { + id: string; + args: NumberLiteral[]; + } export class CallInstruction extends Instruction {} export class ObjectInstruction extends Instruction {} export class Func extends Node { diff --git a/lib/dependencies/WebAssemblyExportImportedDependency.js b/lib/dependencies/WebAssemblyExportImportedDependency.js new file mode 100644 index 00000000000..ddf3aa35b60 --- /dev/null +++ b/lib/dependencies/WebAssemblyExportImportedDependency.js @@ -0,0 +1,29 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ +"use strict"; + +const DependencyReference = require("./DependencyReference"); +const ModuleDependency = require("./ModuleDependency"); + +class WebAssemblyExportImportedDependency extends ModuleDependency { + constructor(exportName, request, name) { + super(request); + /** @type {string} */ + this.exportName = exportName; + /** @type {string} */ + this.name = name; + } + + getReference() { + if (!this.module) return null; + return new DependencyReference(this.module, [this.name], false); + } + + get type() { + return "wasm export import"; + } +} + +module.exports = WebAssemblyExportImportedDependency; diff --git a/lib/wasm/WebAssemblyGenerator.js b/lib/wasm/WebAssemblyGenerator.js index 59c7fa198c0..9c3ee5002f1 100644 --- a/lib/wasm/WebAssemblyGenerator.js +++ b/lib/wasm/WebAssemblyGenerator.js @@ -14,6 +14,8 @@ const { editWithAST, addWithAST } = require("@webassemblyjs/wasm-edit"); const { decode } = require("@webassemblyjs/wasm-parser"); const t = require("@webassemblyjs/ast"); +const WebAssemblyExportImportedDependency = require("../dependencies/WebAssemblyExportImportedDependency"); + /** @typedef {import("../Module")} Module */ /** @typedef {import("./WebAssemblyUtils").UsedWasmDependency} UsedWasmDependency */ @@ -225,7 +227,7 @@ const rewriteImportedGlobals = state => bin => { node.init = [ // Poisong globals, they are meant to be rewritten - t.objectInstruction("const", valtype, [t.numberLiteralFromRaw(666)]) + t.objectInstruction("const", valtype, [t.numberLiteralFromRaw(0)]) ]; additionalInitCode.push( @@ -253,18 +255,24 @@ const rewriteImportedGlobals = state => bin => { * Rewrite the export names * @param {Object} state state * @param {Object} state.ast Module's ast - * @param {Object} state.module Module + * @param {Module} state.module Module + * @param {Set} state.invalidExports Module * @returns {ArrayBufferTransform} transform */ -const rewriteExportNames = ({ ast, module }) => bin => { +const rewriteExportNames = ({ ast, module, invalidExports }) => bin => { return editWithAST(ast, bin, { ModuleExport(path) { + const isInvalid = invalidExports.has(path.node.name); + if (isInvalid) { + path.remove(); + return; + } const usedName = module.isUsed(path.node.name); - if (usedName) { - path.node.name = usedName; - } else { + if (!usedName) { path.remove(); + return; } + path.node.name = usedName; } }); }; @@ -403,6 +411,11 @@ class WebAssemblyGenerator extends Generator { const nextTypeIndex = getNextTypeIndex(ast); const usedDependencyMap = getUsedDependencyMap(module); + const invalidExports = new Set( + module.dependencies + .filter(d => d instanceof WebAssemblyExportImportedDependency) + .map(d => d.exportName) + ); /** @type {t.Instruction[]} */ const additionalInitCode = []; @@ -410,7 +423,8 @@ class WebAssemblyGenerator extends Generator { const transform = compose( rewriteExportNames({ ast, - module + module, + invalidExports }), removeStartFunc({ ast }), diff --git a/lib/wasm/WebAssemblyJavascriptGenerator.js b/lib/wasm/WebAssemblyJavascriptGenerator.js index 8bf15854fe4..994036d3680 100644 --- a/lib/wasm/WebAssemblyJavascriptGenerator.js +++ b/lib/wasm/WebAssemblyJavascriptGenerator.js @@ -8,34 +8,7 @@ const Generator = require("../Generator"); const Template = require("../Template"); const { RawSource } = require("webpack-sources"); const WebAssemblyImportDependency = require("../dependencies/WebAssemblyImportDependency"); - -function generateInitParams(module) { - const list = []; - - for (const dep of module.dependencies) { - if (dep instanceof WebAssemblyImportDependency) { - if (dep.description.type === "GlobalType") { - const exportName = dep.name; - const usedName = dep.module && dep.module.isUsed(exportName); - - if (dep.module === null) { - // Dependency was not found, an error will be thrown later - continue; - } - - if (usedName !== false) { - list.push( - `__webpack_require__(${JSON.stringify( - dep.module.id - )})[${JSON.stringify(usedName)}]` - ); - } - } - } - } - - return list; -} +const WebAssemblyExportImportedDependency = require("../dependencies/WebAssemblyExportImportedDependency"); class WebAssemblyJavascriptGenerator extends Generator { generate(module, dependencyTemplates, runtimeTemplate) { @@ -43,24 +16,88 @@ class WebAssemblyJavascriptGenerator extends Generator { ? Template.numberToIdentifer(module.usedExports.length) : "__webpack_init__"; - const generateImports = () => { - const modules = new Map(); - for (const dep of module.dependencies) { - if (dep.module) modules.set(dep.module, dep.userRequest); - } - return Template.asString( - Array.from(modules, ([m, r]) => { - return `${runtimeTemplate.moduleRaw({ - module: m, - request: r - })};`; - }) - ); - }; + let needExportsCopy = false; + const importedModules = new Map(); + const initParams = []; + let index = 0; + for (const dep of module.dependencies) { + if (dep.module) { + let importData = importedModules.get(dep.module); + if (importData === undefined) { + importedModules.set( + dep.module, + (importData = { + importVar: `m${index}`, + index, + request: dep.userRequest, + names: new Set(), + reexports: [] + }) + ); + index++; + } + if (dep instanceof WebAssemblyImportDependency) { + importData.names.add(dep.name); + if (dep.description.type === "GlobalType") { + const exportName = dep.name; + const usedName = dep.module && dep.module.isUsed(exportName); - // FIXME(sven): assert that the exports exists in the modules - // otherwise it will default to i32 0 - const initParams = generateInitParams(module).join(","); + if (dep.module) { + if (usedName) { + initParams.push( + runtimeTemplate.exportFromImport({ + module: dep.module, + request: dep.request, + importVar: importData.importVar, + originModule: module, + exportName: dep.name, + asiSafe: true, + isCall: false, + callContext: null + }) + ); + } + } + } + } + if (dep instanceof WebAssemblyExportImportedDependency) { + importData.names.add(dep.name); + const usedName = module.isUsed(dep.exportName); + if (usedName) { + const defineStatement = Template.asString([ + `${module.exportsArgument}[${JSON.stringify( + usedName + )}] = ${runtimeTemplate.exportFromImport({ + module: dep.module, + request: dep.request, + importVar: importData.importVar, + originModule: module, + exportName: dep.name, + asiSafe: true, + isCall: false, + callContext: null + })};` + ]); + importData.reexports.push(defineStatement); + needExportsCopy = true; + } + } + } + } + const importsCode = Template.asString( + Array.from( + importedModules, + ([module, { importVar, request, reexports }]) => { + const importStatement = runtimeTemplate.importStatement({ + module, + request, + importVar, + originModule: module + }); + return importStatement + reexports.join("\n"); + } + ) + ); // create source const source = new RawSource( @@ -69,18 +106,24 @@ class WebAssemblyJavascriptGenerator extends Generator { "// Instantiate WebAssembly module", "var wasmExports = __webpack_require__.w[module.i];", + !Array.isArray(module.usedExports) + ? `__webpack_require__.r(${module.exportsArgument});` + : "", + // this must be before import for circular dependencies "// export exports from WebAssembly module", - Array.isArray(module.usedExports) + Array.isArray(module.usedExports) && !needExportsCopy ? `${module.moduleArgument}.exports = wasmExports;` : "for(var name in wasmExports) " + `if(name != ${JSON.stringify(initIdentifer)}) ` + `${module.exportsArgument}[name] = wasmExports[name];`, "// exec imports from WebAssembly module (for esm order)", - generateImports(), - + importsCode, + "", "// exec wasm module", - `wasmExports[${JSON.stringify(initIdentifer)}](${initParams})` + `wasmExports[${JSON.stringify(initIdentifer)}](${initParams.join( + ", " + )})` ].join("\n") ); return source; diff --git a/lib/wasm/WebAssemblyModulesPlugin.js b/lib/wasm/WebAssemblyModulesPlugin.js index 5acdf6d1f51..ede7acc82b3 100644 --- a/lib/wasm/WebAssemblyModulesPlugin.js +++ b/lib/wasm/WebAssemblyModulesPlugin.js @@ -9,6 +9,7 @@ const WebAssemblyParser = require("./WebAssemblyParser"); const WebAssemblyGenerator = require("./WebAssemblyGenerator"); const WebAssemblyJavascriptGenerator = require("./WebAssemblyJavascriptGenerator"); const WebAssemblyImportDependency = require("../dependencies/WebAssemblyImportDependency"); +const WebAssemblyExportImportedDependency = require("../dependencies/WebAssemblyExportImportedDependency"); class WebAssemblyModulesPlugin { apply(compiler) { @@ -20,6 +21,11 @@ class WebAssemblyModulesPlugin { normalModuleFactory ); + compilation.dependencyFactories.set( + WebAssemblyExportImportedDependency, + normalModuleFactory + ); + normalModuleFactory.hooks.createParser .for("webassembly/experimental") .tap("WebAssemblyModulesPlugin", () => { diff --git a/lib/wasm/WebAssemblyParser.js b/lib/wasm/WebAssemblyParser.js index 16103074491..9a8ec44eb6b 100644 --- a/lib/wasm/WebAssemblyParser.js +++ b/lib/wasm/WebAssemblyParser.js @@ -9,6 +9,7 @@ const { decode } = require("@webassemblyjs/wasm-parser"); const { Tapable } = require("tapable"); const WebAssemblyImportDependency = require("../dependencies/WebAssemblyImportDependency"); +const WebAssemblyExportImportedDependency = require("../dependencies/WebAssemblyExportImportedDependency"); /** @typedef {import("../Module")} Module */ @@ -24,6 +25,18 @@ const isMemoryImport = n => n.descr.type === "Memory"; */ const isTableImport = n => n.descr.type === "Table"; +/** + * @param {t.ModuleImport} n the import + * @returns {boolean} true, if a func was imported + */ +const isFuncImport = n => n.descr.type === "FuncImportDescr"; + +/** + * @param {t.ModuleImport} n the import + * @returns {boolean} true, if a global was imported + */ +const isGlobalImport = n => n.descr.type === "GlobalType"; + const JS_COMPAT_TYPES = new Set(["i32", "f32", "f64"]); /** @@ -64,9 +77,39 @@ class WebAssemblyParser extends Tapable { // extract imports and exports const exports = (state.module.buildMeta.providedExports = []); + const importedGlobals = []; t.traverse(ast, { ModuleExport({ node }) { exports.push(node.name); + + if (node.descr && node.descr.exportType === "Global") { + const refNode = importedGlobals[node.descr.id.value]; + if (refNode) { + const dep = new WebAssemblyExportImportedDependency( + node.name, + refNode.module, + refNode.name + ); + + state.module.addDependency(dep); + } + } + }, + + Global({ node }) { + const init = node.init[0]; + + let importNode = null; + + if (init.id === "get_global") { + const globalIdx = init.args[0].value; + + if (globalIdx < importedGlobals.length) { + importNode = importedGlobals[globalIdx]; + } + } + + importedGlobals.push(importNode); }, ModuleImport({ node }) { @@ -77,7 +120,7 @@ class WebAssemblyParser extends Tapable { onlyDirectImport = "Memory"; } else if (isTableImport(node) === true) { onlyDirectImport = "Table"; - } else { + } else if (isFuncImport(node) === true) { const incompatibleType = getJsIncompatibleType(node); if (incompatibleType) { onlyDirectImport = `Non-JS-compatible Func Sigurature (${incompatibleType})`; @@ -92,6 +135,10 @@ class WebAssemblyParser extends Tapable { ); state.module.addDependency(dep); + + if (isGlobalImport(node)) { + importedGlobals.push(node); + } } }); diff --git a/test/cases/wasm/export-imported-global/index.js b/test/cases/wasm/export-imported-global/index.js index b5c32a260fe..51ff200b114 100644 --- a/test/cases/wasm/export-imported-global/index.js +++ b/test/cases/wasm/export-imported-global/index.js @@ -1,5 +1,6 @@ it("should export imported global", function() { - return import("./module.wat").then(function({v}) { + return import("./module").then(function({ v, w }) { expect(v).toBe(1); + expect(w).toBe(1); }); }); diff --git a/test/cases/wasm/export-imported-global/module.js b/test/cases/wasm/export-imported-global/module.js new file mode 100644 index 00000000000..bd82c8f8b1c --- /dev/null +++ b/test/cases/wasm/export-imported-global/module.js @@ -0,0 +1 @@ +export * from "./module.wat"; diff --git a/test/cases/wasm/export-imported-global/module.wat b/test/cases/wasm/export-imported-global/module.wat index fc559c5b77b..8b44a4191fe 100644 --- a/test/cases/wasm/export-imported-global/module.wat +++ b/test/cases/wasm/export-imported-global/module.wat @@ -1,4 +1,6 @@ (module (import "./env.js" "n" (global i32)) (export "v" (global 0)) + (global $g i32 (get_global 0)) + (export "w" (global $g)) ) From 1e4b1c72125e826aba32e99d62464db4613ed64f Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Sat, 2 Jun 2018 17:57:58 +0200 Subject: [PATCH 27/36] create correct init for float types --- lib/wasm/WebAssemblyGenerator.js | 44 ++++++++++--------- test/cases/wasm/export-imported-global/env.js | 1 + .../wasm/export-imported-global/index.js | 4 +- .../wasm/export-imported-global/module.wat | 11 +++++ 4 files changed, 38 insertions(+), 22 deletions(-) diff --git a/lib/wasm/WebAssemblyGenerator.js b/lib/wasm/WebAssemblyGenerator.js index 9c3ee5002f1..c01ede68bbb 100644 --- a/lib/wasm/WebAssemblyGenerator.js +++ b/lib/wasm/WebAssemblyGenerator.js @@ -166,6 +166,27 @@ function getNextFuncIndex(ast, countImportedFunc) { return t.indexLiteral(vectorOfSize + countImportedFunc); } +/** + * Create a init instruction for a global + * @param {t.GlobalType} globalType the global type + * @returns {t.Instruction} init expression + */ +const createDefaultInitForGlobal = globalType => { + if (globalType.valtype[0] === "i") { + // create NumberLiteral global initializer + return t.objectInstruction("const", globalType.valtype, [ + t.numberLiteralFromRaw(66) + ]); + } else if (globalType.valtype[0] === "f") { + // create FloatLiteral global initializer + return t.objectInstruction("const", globalType.valtype, [ + t.floatLiteral(66, false, false, "66") + ]); + } else { + throw new Error("unknown type: " + globalType.valtype); + } +}; + /** * Rewrite the import globals: * - removes the ModuleImport instruction @@ -190,21 +211,7 @@ const rewriteImportedGlobals = state => bin => { globalType.mutability = "var"; - let init; - - if (globalType.valtype[0] === "i") { - // create NumberLiteral global initializer - init = t.objectInstruction("const", globalType.valtype, [ - t.numberLiteralFromRaw(0) - ]); - } else if (globalType.valtype[0] === "f") { - // create FloatLiteral global initializer - init = t.objectInstruction("const", globalType.valtype, [ - t.floatLiteral(0, false, false, "0") - ]); - } else { - throw new Error("unknown type: " + globalType.valtype); - } + const init = createDefaultInitForGlobal(globalType); newGlobals.push(t.global(globalType, [init])); @@ -223,12 +230,7 @@ const rewriteImportedGlobals = state => bin => { const initialGlobalidx = init.args[0]; - const valtype = node.globalType.valtype; - - node.init = [ - // Poisong globals, they are meant to be rewritten - t.objectInstruction("const", valtype, [t.numberLiteralFromRaw(0)]) - ]; + node.init = [createDefaultInitForGlobal(node.globalType)]; additionalInitCode.push( /** diff --git a/test/cases/wasm/export-imported-global/env.js b/test/cases/wasm/export-imported-global/env.js index 39a36559da0..baa33171481 100644 --- a/test/cases/wasm/export-imported-global/env.js +++ b/test/cases/wasm/export-imported-global/env.js @@ -1 +1,2 @@ export const n = 1; +export const m = 1.25 diff --git a/test/cases/wasm/export-imported-global/index.js b/test/cases/wasm/export-imported-global/index.js index 51ff200b114..3db7fee9e5d 100644 --- a/test/cases/wasm/export-imported-global/index.js +++ b/test/cases/wasm/export-imported-global/index.js @@ -1,6 +1,8 @@ it("should export imported global", function() { - return import("./module").then(function({ v, w }) { + return import("./module").then(function({ v, w, x, test }) { expect(v).toBe(1); expect(w).toBe(1); + expect(x).toBe(1.25); + expect(test()).toBe(2); }); }); diff --git a/test/cases/wasm/export-imported-global/module.wat b/test/cases/wasm/export-imported-global/module.wat index 8b44a4191fe..c20daa39864 100644 --- a/test/cases/wasm/export-imported-global/module.wat +++ b/test/cases/wasm/export-imported-global/module.wat @@ -1,6 +1,17 @@ (module (import "./env.js" "n" (global i32)) + (import "./env.js" "m" (global $g2 f64)) (export "v" (global 0)) (global $g i32 (get_global 0)) (export "w" (global $g)) + (export "x" (global $g2)) + (func (export "test") (result i32) + get_global $g2 + get_global $g2 + f64.add + drop + get_global 0 + get_global $g + i32.add + ) ) From 9cf25b10be675cf03a9362c99b8a3277d3fcb68b Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Sat, 2 Jun 2018 18:00:10 +0200 Subject: [PATCH 28/36] add Globaltype --- declarations.d.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/declarations.d.ts b/declarations.d.ts index 5212d6c3256..3b614e308fe 100644 --- a/declarations.d.ts +++ b/declarations.d.ts @@ -74,8 +74,12 @@ declare module "@webassemblyjs/ast" { raw: string; } export class FloatLiteral extends Node {} + export class GlobalType extends Node { + valtype: string; + } export class Global extends Node { init: Instruction[]; + globalType: GlobalType; } export class FuncParam extends Node { valtype: string; From 9a6d9c7a061b07b286534526a49b949c823ce1a5 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Sat, 2 Jun 2018 18:00:22 +0200 Subject: [PATCH 29/36] rename to externalExports --- lib/wasm/WebAssemblyGenerator.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/wasm/WebAssemblyGenerator.js b/lib/wasm/WebAssemblyGenerator.js index c01ede68bbb..ac791f08644 100644 --- a/lib/wasm/WebAssemblyGenerator.js +++ b/lib/wasm/WebAssemblyGenerator.js @@ -258,14 +258,14 @@ const rewriteImportedGlobals = state => bin => { * @param {Object} state state * @param {Object} state.ast Module's ast * @param {Module} state.module Module - * @param {Set} state.invalidExports Module + * @param {Set} state.externalExports Module * @returns {ArrayBufferTransform} transform */ -const rewriteExportNames = ({ ast, module, invalidExports }) => bin => { +const rewriteExportNames = ({ ast, module, externalExports }) => bin => { return editWithAST(ast, bin, { ModuleExport(path) { - const isInvalid = invalidExports.has(path.node.name); - if (isInvalid) { + const isExternal = externalExports.has(path.node.name); + if (isExternal) { path.remove(); return; } @@ -413,7 +413,7 @@ class WebAssemblyGenerator extends Generator { const nextTypeIndex = getNextTypeIndex(ast); const usedDependencyMap = getUsedDependencyMap(module); - const invalidExports = new Set( + const externalExports = new Set( module.dependencies .filter(d => d instanceof WebAssemblyExportImportedDependency) .map(d => d.exportName) @@ -426,7 +426,7 @@ class WebAssemblyGenerator extends Generator { rewriteExportNames({ ast, module, - invalidExports + externalExports }), removeStartFunc({ ast }), From 2ca1161ad53829dddb951db1b0401db1bd6d05ca Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Mon, 4 Jun 2018 07:16:15 +0200 Subject: [PATCH 30/36] Improve CI log cleanup --- open-bot.yaml | 49 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 13 deletions(-) diff --git a/open-bot.yaml b/open-bot.yaml index 17efe8708c0..3247a6fb3ad 100644 --- a/open-bot.yaml +++ b/open-bot.yaml @@ -77,25 +77,32 @@ rules: id: logResult value: "{{{fetch}}}" remove: + - "\\m\\[2K\\m\\[1G|\\m\\[999D\\m\\[K" - "^[\\s\\S]+?\\$ yarn travis:\\$JOB_PART.*\n" - "\\$ node --max-old-space-size=4096.*\n" - - "^yarn run.+\n" - - "\\(node:\\d+\\) \\[DEP0005\\].+\n" + - ".+rimraf coverage" + - "yarn run.+\n" + - "\\(node:\\d+\\) (\\[DEP0005\\]|DeprecationWarning).+\n" - "\\$ yarn (cover|test):.+\n" - "Ran all test suites.\n[\\s\\S]*" - - "PASS test/.*\n" + - "error Command failed with exit code \\d+.\n" + - "info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.\n" + - "Force exiting Jest\n\nHave you considered.+" + - "=============================== Coverage summary ===============================[\\s\\S]+?================================================================================" + - " *PASS *test/.*\n" + - "^\\s+|\\s+$" string_cleanup_1: id: firstError value: "{{{logResult}}}" remove: - - "\n\n ●[\\s\\S]*" + - "\n\n( ●| FAIL)[\\s\\S]*" - "Test Suites:[\\s\\S]*" - "\\s+$" string_cleanup_2: id: remainingErrors value: "{{{logResult}}}" remove: - - "^[\\s\\S]+?(?=\n\n ●|$)" + - "^[\\s\\S]+?(?=\n\n( ●| FAIL)|$)" - "^\n+" - "Test Suites:[\\s\\S]*" - "\\s+$" @@ -155,25 +162,33 @@ rules: id: logResult value: "{{{fetch}}}" remove: + - "\\m\\[2K\\m\\[1G|\\m\\[999D\\m\\[K" - "^[\\s\\S]+?\\$ yarn travis:\\$JOB_PART.*\n" - "\\$ node --max-old-space-size=4096.*\n" - - "^yarn run.+\n" - - "\\(node:\\d+\\) \\[DEP0005\\].+\n" + - ".+rimraf coverage" + - "yarn run.+\n" + - "\\(node:\\d+\\) (\\[DEP0005\\]|DeprecationWarning).+\n" - "\\$ yarn (cover|test):.+\n" - "The command \"yarn travis:\\$JOB_PART\" exited[\\s\\S]*" - - "PASS test/.*\n" + - "Ran all test suites.+\n" + - "error Command failed with exit code \\d+.\n" + - "info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.\n" + - "Force exiting Jest\n\nHave you considered.+" + - "=============================== Coverage summary ===============================[\\s\\S]+?================================================================================" + - " *PASS *test/.*\n" + - "^\\s+|\\s+$" string_cleanup_1: id: firstError value: "{{{logResult}}}" remove: - - "\n\n ●[\\s\\S]*" + - "\n\n( ●| FAIL)[\\s\\S]*" - "Test Suites:[\\s\\S]*" - "\\s+$" string_cleanup_2: id: remainingErrors value: "{{{logResult}}}" remove: - - "^[\\s\\S]+?(?=\n\n ●|$)" + - "^[\\s\\S]+?(?=\n\n( ●| FAIL)|$)" - "^\n+" - "Test Suites:[\\s\\S]*" - "\\s+$" @@ -233,13 +248,21 @@ rules: id: logResult value: "{{{fetch}}}" remove: + - "\\m\\[2K\\m\\[1G|\\m\\[999D\\m\\[K" - "^[\\s\\S]+?\\$ yarn travis:\\$JOB_PART.*\n" - "\\$ node --max-old-space-size=4096.*\n" - - "^yarn run.+\n" - - "\\(node:\\d+\\) \\[DEP0005\\].+\n" + - ".+rimraf coverage" + - "yarn run.+\n" + - "\\(node:\\d+\\) (\\[DEP0005\\]|DeprecationWarning).+\n" - "\\$ yarn (unit|lint).+\n" - "The command \"yarn travis:\\$JOB_PART\" exited[\\s\\S]*" - - "PASS test/.*\n" + - "Ran all test suites.+\n" + - "error Command failed with exit code \\d+.\n" + - "info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.\n" + - "Force exiting Jest\n\nHave you considered.+" + - "=============================== Coverage summary ===============================[\\s\\S]+?================================================================================" + - " *PASS *test/.*\n" + - "^\\s+|\\s+$" actions: comment: identifier: "ci-result" From 53f7debdc96ea7aaaf7b87da69122454e4c02164 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Mon, 4 Jun 2018 07:24:12 +0200 Subject: [PATCH 31/36] Improve CI log cleanup further --- open-bot.yaml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/open-bot.yaml b/open-bot.yaml index 3247a6fb3ad..d40075be241 100644 --- a/open-bot.yaml +++ b/open-bot.yaml @@ -77,7 +77,7 @@ rules: id: logResult value: "{{{fetch}}}" remove: - - "\\m\\[2K\\m\\[1G|\\m\\[999D\\m\\[K" + - ".\\[2K.\\[1G|.\\[999D.\\[K" - "^[\\s\\S]+?\\$ yarn travis:\\$JOB_PART.*\n" - "\\$ node --max-old-space-size=4096.*\n" - ".+rimraf coverage" @@ -90,7 +90,7 @@ rules: - "Force exiting Jest\n\nHave you considered.+" - "=============================== Coverage summary ===============================[\\s\\S]+?================================================================================" - " *PASS *test/.*\n" - - "^\\s+|\\s+$" + - "^\\s+\n|\\s+$" string_cleanup_1: id: firstError value: "{{{logResult}}}" @@ -162,7 +162,7 @@ rules: id: logResult value: "{{{fetch}}}" remove: - - "\\m\\[2K\\m\\[1G|\\m\\[999D\\m\\[K" + - ".\\[2K.\\[1G|.\\[999D.\\[K" - "^[\\s\\S]+?\\$ yarn travis:\\$JOB_PART.*\n" - "\\$ node --max-old-space-size=4096.*\n" - ".+rimraf coverage" @@ -176,7 +176,7 @@ rules: - "Force exiting Jest\n\nHave you considered.+" - "=============================== Coverage summary ===============================[\\s\\S]+?================================================================================" - " *PASS *test/.*\n" - - "^\\s+|\\s+$" + - "^\\s+\n|\\s+$" string_cleanup_1: id: firstError value: "{{{logResult}}}" @@ -248,7 +248,7 @@ rules: id: logResult value: "{{{fetch}}}" remove: - - "\\m\\[2K\\m\\[1G|\\m\\[999D\\m\\[K" + - ".\\[2K.\\[1G|.\\[999D.\\[K" - "^[\\s\\S]+?\\$ yarn travis:\\$JOB_PART.*\n" - "\\$ node --max-old-space-size=4096.*\n" - ".+rimraf coverage" @@ -262,7 +262,7 @@ rules: - "Force exiting Jest\n\nHave you considered.+" - "=============================== Coverage summary ===============================[\\s\\S]+?================================================================================" - " *PASS *test/.*\n" - - "^\\s+|\\s+$" + - "^\\s+\n|\\s+$" actions: comment: identifier: "ci-result" From 0743250281b233efc202ea6ff65a1b8debdc63fe Mon Sep 17 00:00:00 2001 From: Florent Cailhol Date: Mon, 4 Jun 2018 09:49:08 +0200 Subject: [PATCH 32/36] Add a test case about nodeEnv --- lib/WebpackOptionsDefaulter.js | 9 ++++---- test/configCases/issues/issue-7470/index.js | 3 +++ .../issues/issue-7470/webpack.config.js | 21 +++++++++++++++++++ 3 files changed, 28 insertions(+), 5 deletions(-) create mode 100644 test/configCases/issues/issue-7470/index.js create mode 100644 test/configCases/issues/issue-7470/webpack.config.js diff --git a/lib/WebpackOptionsDefaulter.js b/lib/WebpackOptionsDefaulter.js index e709b402ecb..70678c867ba 100644 --- a/lib/WebpackOptionsDefaulter.js +++ b/lib/WebpackOptionsDefaulter.js @@ -294,11 +294,10 @@ class WebpackOptionsDefaulter extends OptionsDefaulter { } } ]); - this.set( - "optimization.nodeEnv", - "make", - options => options.mode || "production" - ); + this.set("optimization.nodeEnv", "make", options => { + // TODO: In webpack 5, it should return `false` when mode is `none` + return options.mode || "production"; + }); this.set("resolve", "call", value => Object.assign({}, value)); this.set("resolve.unsafeCache", true); diff --git a/test/configCases/issues/issue-7470/index.js b/test/configCases/issues/issue-7470/index.js new file mode 100644 index 00000000000..6267ef7b114 --- /dev/null +++ b/test/configCases/issues/issue-7470/index.js @@ -0,0 +1,3 @@ +it("should set NODE_ENV according to mode", () => { + expect(process.env.NODE_ENV).toBe(__MODE__); +}); diff --git a/test/configCases/issues/issue-7470/webpack.config.js b/test/configCases/issues/issue-7470/webpack.config.js new file mode 100644 index 00000000000..4d4a87ba768 --- /dev/null +++ b/test/configCases/issues/issue-7470/webpack.config.js @@ -0,0 +1,21 @@ +"use strict"; + +const DefinePlugin = require("../../../../lib/DefinePlugin"); + +module.exports = [ + { + name: "development", + mode: "development", + plugins: [new DefinePlugin({ __MODE__: `"development"` })] + }, + { + name: "production", + mode: "production", + plugins: [new DefinePlugin({ __MODE__: `"production"` })] + }, + { + name: "none", + mode: "none", + plugins: [new DefinePlugin({ __MODE__: `"none"` })] + } +]; From 53103a9690d653daf1de405756f5638999c36f22 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Mon, 4 Jun 2018 10:10:23 +0200 Subject: [PATCH 33/36] Cleanup error location and origin information --- lib/AsyncDependencyToInitialChunkError.js | 8 +- lib/CaseSensitiveModulesWarning.js | 86 +++++++++---------- lib/Compilation.js | 3 +- lib/EntryModuleNotFoundError.js | 3 +- lib/HarmonyLinkingError.js | 3 +- lib/ModuleBuildError.js | 23 ++--- lib/ModuleDependencyError.js | 7 +- lib/ModuleDependencyWarning.js | 7 +- lib/ModuleError.js | 4 +- lib/ModuleNotFoundError.js | 7 +- lib/ModuleParseError.js | 41 ++++++--- lib/ModuleWarning.js | 10 +-- lib/ParserHelpers.js | 2 +- lib/RemovedPluginError.js | 4 +- lib/Stats.js | 13 ++- lib/UnsupportedFeatureWarning.js | 9 +- lib/WebpackOptionsValidationError.js | 30 +++---- ...AMDRequireDependenciesBlockParserPlugin.js | 3 +- lib/dependencies/ImportParserPlugin.js | 27 ++++-- lib/dependencies/SystemPlugin.js | 12 +-- lib/performance/AssetsOverSizeLimitWarning.js | 14 +-- .../EntrypointsOverSizeLimitWarning.js | 13 ++- lib/performance/NoAsyncChunksWarning.js | 10 +-- .../UnsupportedWebAssemblyFeatureError.js | 3 +- test/ModuleDependencyError.unittest.js | 10 ++- test/Stats.unittest.js | 2 +- .../__snapshots__/StatsTestCases.test.js.snap | 4 +- test/cases/parsing/issue-2942/warnings.js | 2 +- 28 files changed, 191 insertions(+), 169 deletions(-) diff --git a/lib/AsyncDependencyToInitialChunkError.js b/lib/AsyncDependencyToInitialChunkError.js index 78eeb81346c..a0631aa3d50 100644 --- a/lib/AsyncDependencyToInitialChunkError.js +++ b/lib/AsyncDependencyToInitialChunkError.js @@ -16,13 +16,13 @@ class AsyncDependencyToInitialChunkError extends WebpackError { * @param {TODO} loc location of dependency */ constructor(chunkName, module, loc) { - super(); + super( + `It's not allowed to load an initial chunk on demand. The chunk name "${chunkName}" is already used by an entrypoint.` + ); this.name = "AsyncDependencyToInitialChunkError"; - this.message = `It's not allowed to load an initial chunk on demand. The chunk name "${chunkName}" is already used by an entrypoint.`; this.module = module; - this.origin = module; - this.originLoc = loc; + this.loc = loc; Error.captureStackTrace(this, this.constructor); } diff --git a/lib/CaseSensitiveModulesWarning.js b/lib/CaseSensitiveModulesWarning.js index 98237cfcb8d..b64caf868bb 100644 --- a/lib/CaseSensitiveModulesWarning.js +++ b/lib/CaseSensitiveModulesWarning.js @@ -8,64 +8,60 @@ const WebpackError = require("./WebpackError"); /** @typedef {import("./Module")} Module */ +/** + * @param {Module[]} modules the modules to be sorted + * @returns {Module[]} sorted version of original modules + */ +const sortModules = modules => { + return modules.slice().sort((a, b) => { + a = a.identifier(); + b = b.identifier(); + /* istanbul ignore next */ + if (a < b) return -1; + /* istanbul ignore next */ + if (a > b) return 1; + /* istanbul ignore next */ + return 0; + }); +}; + +/** + * @param {Module[]} modules each module from throw + * @returns {string} each message from provided moduels + */ +const createModulesListMessage = modules => { + return modules + .map(m => { + let message = `* ${m.identifier()}`; + const validReasons = m.reasons.filter(reason => reason.module); + + if (validReasons.length > 0) { + message += `\n Used by ${validReasons.length} module(s), i. e.`; + message += `\n ${validReasons[0].module.identifier()}`; + } + return message; + }) + .join("\n"); +}; + class CaseSensitiveModulesWarning extends WebpackError { /** * Creates an instance of CaseSensitiveModulesWarning. * @param {Module[]} modules modules that were detected */ constructor(modules) { - super(); - - this.name = "CaseSensitiveModulesWarning"; - const sortedModules = this._sort(modules); - const modulesList = this._moduleMessages(sortedModules); - this.message = `There are multiple modules with names that only differ in casing. + const sortedModules = sortModules(modules); + const modulesList = createModulesListMessage(sortedModules); + super(`There are multiple modules with names that only differ in casing. This can lead to unexpected behavior when compiling on a filesystem with other case-semantic. Use equal casing. Compare these module identifiers: -${modulesList}`; +${modulesList}`); + this.name = "CaseSensitiveModulesWarning"; this.origin = this.module = sortedModules[0]; Error.captureStackTrace(this, this.constructor); } - - /** - * @private - * @param {Module[]} modules the modules to be sorted - * @returns {Module[]} sorted version of original modules - */ - _sort(modules) { - return modules.slice().sort((a, b) => { - a = a.identifier(); - b = b.identifier(); - /* istanbul ignore next */ - if (a < b) return -1; - /* istanbul ignore next */ - if (a > b) return 1; - /* istanbul ignore next */ - return 0; - }); - } - - /** - * @private - * @param {Module[]} modules each module from throw - * @returns {string} each message from provided moduels - */ - _moduleMessages(modules) { - return modules - .map(m => { - let message = `* ${m.identifier()}`; - const validReasons = m.reasons.filter(reason => reason.module); - - if (validReasons.length > 0) { - message += `\n Used by ${validReasons.length} module(s), i. e.`; - message += `\n ${validReasons[0].module.identifier()}`; - } - return message; - }) - .join("\n"); - } } module.exports = CaseSensitiveModulesWarning; diff --git a/lib/Compilation.js b/lib/Compilation.js index 71e35e747ca..1fd02ed4f6f 100644 --- a/lib/Compilation.js +++ b/lib/Compilation.js @@ -487,6 +487,7 @@ class Compilation extends Tapable { const errorAndCallback = err => { err.origin = module; + err.dependencies = dependencies; this.errors.push(err); if (bail) { callback(err); @@ -531,7 +532,7 @@ class Compilation extends Tapable { if (err) { semaphore.release(); return errorOrWarningAndCallback( - new ModuleNotFoundError(module, err, dependencies) + new ModuleNotFoundError(module, err) ); } if (!dependentModule) { diff --git a/lib/EntryModuleNotFoundError.js b/lib/EntryModuleNotFoundError.js index aea9343aea9..b2458d6f24f 100644 --- a/lib/EntryModuleNotFoundError.js +++ b/lib/EntryModuleNotFoundError.js @@ -8,10 +8,9 @@ const WebpackError = require("./WebpackError"); class EntryModuleNotFoundError extends WebpackError { constructor(err) { - super(); + super("Entry module not found: " + err); this.name = "EntryModuleNotFoundError"; - this.message = "Entry module not found: " + err; this.details = err.details; this.error = err; diff --git a/lib/HarmonyLinkingError.js b/lib/HarmonyLinkingError.js index 28befc6a46b..78ce16dde45 100644 --- a/lib/HarmonyLinkingError.js +++ b/lib/HarmonyLinkingError.js @@ -8,9 +8,8 @@ const WebpackError = require("./WebpackError"); module.exports = class HarmonyLinkingError extends WebpackError { /** @param {string} message Error message */ constructor(message) { - super(); + super(message); this.name = "HarmonyLinkingError"; - this.message = message; this.hideStack = true; Error.captureStackTrace(this, this.constructor); diff --git a/lib/ModuleBuildError.js b/lib/ModuleBuildError.js index 13504344cbf..1247c4143d2 100644 --- a/lib/ModuleBuildError.js +++ b/lib/ModuleBuildError.js @@ -9,29 +9,32 @@ const { cutOffLoaderExecution } = require("./ErrorHelpers"); class ModuleBuildError extends WebpackError { constructor(module, err) { - super(); - - this.name = "ModuleBuildError"; - this.message = "Module build failed: "; + let message = "Module build failed: "; + let details = undefined; if (err !== null && typeof err === "object") { if (typeof err.stack === "string" && err.stack) { var stack = cutOffLoaderExecution(err.stack); if (!err.hideStack) { - this.message += stack; + message += stack; } else { - this.details = stack; + details = stack; if (typeof err.message === "string" && err.message) { - this.message += err.message; + message += err.message; } else { - this.message += err; + message += err; } } } else if (typeof err.message === "string" && err.message) { - this.message += err.message; + message += err.message; } else { - this.message += err; + message += err; } } + + super(message); + + this.name = "ModuleBuildError"; + this.details = details; this.module = module; this.error = err; diff --git a/lib/ModuleDependencyError.js b/lib/ModuleDependencyError.js index f52092021a3..1cf6142e6aa 100644 --- a/lib/ModuleDependencyError.js +++ b/lib/ModuleDependencyError.js @@ -5,7 +5,6 @@ "use strict"; const WebpackError = require("./WebpackError"); -const formatLocation = require("./formatLocation"); /** @typedef {import("./Module")} Module */ @@ -17,15 +16,15 @@ class ModuleDependencyError extends WebpackError { * @param {TODO} loc location of dependency */ constructor(module, err, loc) { - super(); + super(err.message); this.name = "ModuleDependencyError"; - this.message = `${formatLocation(loc)} ${err.message}`; this.details = err.stack .split("\n") .slice(1) .join("\n"); - this.origin = this.module = module; + this.module = module; + this.loc = loc; this.error = err; Error.captureStackTrace(this, this.constructor); diff --git a/lib/ModuleDependencyWarning.js b/lib/ModuleDependencyWarning.js index 395fbd5a17f..6c5245055f8 100644 --- a/lib/ModuleDependencyWarning.js +++ b/lib/ModuleDependencyWarning.js @@ -5,19 +5,18 @@ "use strict"; const WebpackError = require("./WebpackError"); -const formatLocation = require("./formatLocation"); module.exports = class ModuleDependencyWarning extends WebpackError { constructor(module, err, loc) { - super(); + super(err.message); this.name = "ModuleDependencyWarning"; - this.message = `${formatLocation(loc)} ${err.message}`; this.details = err.stack .split("\n") .slice(1) .join("\n"); - this.origin = this.module = module; + this.module = module; + this.loc = loc; this.error = err; Error.captureStackTrace(this, this.constructor); diff --git a/lib/ModuleError.js b/lib/ModuleError.js index 750d4182d99..49917fba9e4 100644 --- a/lib/ModuleError.js +++ b/lib/ModuleError.js @@ -9,12 +9,10 @@ const { cleanUp } = require("./ErrorHelpers"); class ModuleError extends WebpackError { constructor(module, err) { - super(); + super(err && typeof err === "object" && err.message ? err.message : err); this.name = "ModuleError"; this.module = module; - this.message = - err && typeof err === "object" && err.message ? err.message : err; this.error = err; this.details = err && typeof err === "object" && err.stack diff --git a/lib/ModuleNotFoundError.js b/lib/ModuleNotFoundError.js index 53ba47d0c0e..cdfc3147b16 100644 --- a/lib/ModuleNotFoundError.js +++ b/lib/ModuleNotFoundError.js @@ -7,16 +7,13 @@ const WebpackError = require("./WebpackError"); class ModuleNotFoundError extends WebpackError { - constructor(module, err, dependencies) { - super(); + constructor(module, err) { + super("Module not found: " + err); this.name = "ModuleNotFoundError"; - this.message = "Module not found: " + err; this.details = err.details; this.missing = err.missing; this.module = module; - this.origin = module; - this.dependencies = dependencies; this.error = err; Error.captureStackTrace(this, this.constructor); diff --git a/lib/ModuleParseError.js b/lib/ModuleParseError.js index c8c6429ed2f..32c7a69c116 100644 --- a/lib/ModuleParseError.js +++ b/lib/ModuleParseError.js @@ -6,14 +6,18 @@ const WebpackError = require("./WebpackError"); +/** @typedef {import("./Module")} Module */ + class ModuleParseError extends WebpackError { + /** + * @param {Module} module the errored module + * @param {string} source source code + * @param {Error&any} err the parse error + */ constructor(module, source, err) { - super(); - - this.name = "ModuleParseError"; - this.message = "Module parse failed: " + err.message; - this.message += - "\nYou may need an appropriate loader to handle this file type."; + let message = "Module parse failed: " + err.message; + let loc = undefined; + message += "\nYou may need an appropriate loader to handle this file type."; if ( err.loc && typeof err.loc === "object" && @@ -22,19 +26,28 @@ class ModuleParseError extends WebpackError { var lineNumber = err.loc.line; if (/[\0\u0001\u0002\u0003\u0004\u0005\u0006\u0007]/.test(source)) { // binary file - this.message += "\n(Source code omitted for this binary file)"; + message += "\n(Source code omitted for this binary file)"; } else { - source = source.split("\n"); - this.message += - "\n| " + - source - .slice(Math.max(0, lineNumber - 3), lineNumber + 2) - .join("\n| "); + const sourceLines = source.split("\n"); + const start = Math.max(0, lineNumber - 3); + const linesBefore = sourceLines.slice(start, lineNumber - 1); + const theLine = sourceLines[lineNumber - 1]; + const linesAfter = sourceLines.slice(lineNumber, lineNumber + 2); + message += + linesBefore.map(l => `\n| ${l}`).join("") + + `\n> ${theLine}` + + linesAfter.map(l => `\n| ${l}`).join(""); } + loc = err.loc; } else { - this.message += "\n" + err.stack; + message += "\n" + err.stack; } + + super(message); + + this.name = "ModuleParseError"; this.module = module; + this.loc = loc; this.error = err; Error.captureStackTrace(this, this.constructor); diff --git a/lib/ModuleWarning.js b/lib/ModuleWarning.js index ee161046134..8eaad8bb578 100644 --- a/lib/ModuleWarning.js +++ b/lib/ModuleWarning.js @@ -9,14 +9,14 @@ const { cleanUp } = require("./ErrorHelpers"); class ModuleWarning extends WebpackError { constructor(module, warning) { - super(); + super( + warning && typeof warning === "object" && warning.message + ? warning.message + : warning + ); this.name = "ModuleWarning"; this.module = module; - this.message = - warning && typeof warning === "object" && warning.message - ? warning.message - : warning; this.warning = warning; this.details = warning && typeof warning === "object" && warning.stack diff --git a/lib/ParserHelpers.js b/lib/ParserHelpers.js index 9552182dace..5248f12fe55 100644 --- a/lib/ParserHelpers.js +++ b/lib/ParserHelpers.js @@ -88,7 +88,7 @@ ParserHelpers.expressionIsUnsupported = (parser, message) => { parser.state.current.addDependency(dep); if (!parser.state.module) return; parser.state.module.warnings.push( - new UnsupportedFeatureWarning(parser.state.module, message) + new UnsupportedFeatureWarning(parser.state.module, message, expr.loc) ); return true; }; diff --git a/lib/RemovedPluginError.js b/lib/RemovedPluginError.js index 772464fb008..626c3b4fb2c 100644 --- a/lib/RemovedPluginError.js +++ b/lib/RemovedPluginError.js @@ -4,9 +4,7 @@ const WebpackError = require("./WebpackError"); module.exports = class RemovedPluginError extends WebpackError { constructor(message) { - super(); - - this.message = message; + super(message); Error.captureStackTrace(this, this.constructor); } diff --git a/lib/Stats.js b/lib/Stats.js index 9ece0f3bc48..5179c8108a0 100644 --- a/lib/Stats.js +++ b/lib/Stats.js @@ -56,8 +56,8 @@ class Stats { formatFilePath(filePath) { const OPTIONS_REGEXP = /^(\s|\S)*!/; return filePath.includes("!") - ? `${filePath.replace(OPTIONS_REGEXP, "")} (${filePath})\n` - : `${filePath}\n`; + ? `${filePath.replace(OPTIONS_REGEXP, "")} (${filePath})` + : `${filePath}`; } hasWarnings() { @@ -288,6 +288,11 @@ class Stats { text += this.formatFilePath( e.module.readableIdentifier(requestShortener) ); + if (typeof e.loc === "object") { + const locInfo = formatLocation(e.loc); + if (locInfo) text += ` ${locInfo}`; + } + text += "\n"; } text += e.message; if (showErrorDetails && e.details) { @@ -297,7 +302,9 @@ class Stats { text += e.missing.map(item => `\n[${item}]`).join(""); } if (showModuleTrace && e.origin) { - text += `\n @ ${e.origin.readableIdentifier(requestShortener)}`; + text += `\n @ ${this.formatFilePath( + e.origin.readableIdentifier(requestShortener) + )}`; if (typeof e.originLoc === "object") { const locInfo = formatLocation(e.originLoc); if (locInfo) text += ` ${locInfo}`; diff --git a/lib/UnsupportedFeatureWarning.js b/lib/UnsupportedFeatureWarning.js index e7b536e6f03..284429ea94d 100644 --- a/lib/UnsupportedFeatureWarning.js +++ b/lib/UnsupportedFeatureWarning.js @@ -7,12 +7,13 @@ const WebpackError = require("./WebpackError"); class UnsupportedFeatureWarning extends WebpackError { - constructor(module, message) { - super(); + constructor(module, message, loc) { + super(message); this.name = "UnsupportedFeatureWarning"; - this.message = message; - this.origin = this.module = module; + this.module = module; + this.loc = loc; + this.hideStack = true; Error.captureStackTrace(this, this.constructor); } diff --git a/lib/WebpackOptionsValidationError.js b/lib/WebpackOptionsValidationError.js index 0475991a45a..3fdbd0df6ba 100644 --- a/lib/WebpackOptionsValidationError.js +++ b/lib/WebpackOptionsValidationError.js @@ -69,23 +69,23 @@ const indent = (str, prefix, firstLine) => { class WebpackOptionsValidationError extends WebpackError { constructor(validationErrors) { - super(); + super( + "Invalid configuration object. " + + "Webpack has been initialised using a configuration object that does not match the API schema.\n" + + validationErrors + .map( + err => + " - " + + indent( + WebpackOptionsValidationError.formatValidationError(err), + " ", + false + ) + ) + .join("\n") + ); this.name = "WebpackOptionsValidationError"; - this.message = - "Invalid configuration object. " + - "Webpack has been initialised using a configuration object that does not match the API schema.\n" + - validationErrors - .map( - err => - " - " + - indent( - WebpackOptionsValidationError.formatValidationError(err), - " ", - false - ) - ) - .join("\n"); this.validationErrors = validationErrors; Error.captureStackTrace(this, this.constructor); diff --git a/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js b/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js index a5745b98bb8..1173f982e89 100644 --- a/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js +++ b/lib/dependencies/AMDRequireDependenciesBlockParserPlugin.js @@ -219,7 +219,8 @@ class AMDRequireDependenciesBlockParserPlugin { new UnsupportedFeatureWarning( parser.state.module, "Cannot statically analyse 'require(…, …)' in line " + - expr.loc.start.line + expr.loc.start.line, + expr.loc ) ); } diff --git a/lib/dependencies/ImportParserPlugin.js b/lib/dependencies/ImportParserPlugin.js index cb3d996efa8..580e065b0e1 100644 --- a/lib/dependencies/ImportParserPlugin.js +++ b/lib/dependencies/ImportParserPlugin.js @@ -41,7 +41,8 @@ class ImportParserPlugin { parser.state.module, `\`webpackIgnore\` expected a boolean, but received: ${ importOptions.webpackIgnore - }.` + }.`, + expr.loc ) ); } else { @@ -58,7 +59,8 @@ class ImportParserPlugin { parser.state.module, `\`webpackChunkName\` expected a string, but received: ${ importOptions.webpackChunkName - }.` + }.`, + expr.loc ) ); } else { @@ -72,7 +74,8 @@ class ImportParserPlugin { parser.state.module, `\`webpackMode\` expected a string, but received: ${ importOptions.webpackMode - }.` + }.`, + expr.loc ) ); } else { @@ -90,7 +93,8 @@ class ImportParserPlugin { parser.state.module, `\`webpackPrefetch\` expected true or a number, but received: ${ importOptions.webpackPrefetch - }.` + }.`, + expr.loc ) ); } @@ -106,7 +110,8 @@ class ImportParserPlugin { parser.state.module, `\`webpackPreload\` expected true or a number, but received: ${ importOptions.webpackPreload - }.` + }.`, + expr.loc ) ); } @@ -121,7 +126,8 @@ class ImportParserPlugin { parser.state.module, `\`webpackInclude\` expected a regular expression, but received: ${ importOptions.webpackInclude - }.` + }.`, + expr.loc ) ); } else { @@ -138,7 +144,8 @@ class ImportParserPlugin { parser.state.module, `\`webpackExclude\` expected a regular expression, but received: ${ importOptions.webpackExclude - }.` + }.`, + expr.loc ) ); } else { @@ -152,7 +159,8 @@ class ImportParserPlugin { parser.state.module.warnings.push( new UnsupportedFeatureWarning( parser.state.module, - `\`webpackMode\` expected 'lazy', 'eager' or 'weak', but received: ${mode}.` + `\`webpackMode\` expected 'lazy', 'eager' or 'weak', but received: ${mode}.`, + expr.loc ) ); } @@ -195,7 +203,8 @@ class ImportParserPlugin { parser.state.module.warnings.push( new UnsupportedFeatureWarning( parser.state.module, - `\`webpackMode\` expected 'lazy', 'lazy-once', 'eager' or 'weak', but received: ${mode}.` + `\`webpackMode\` expected 'lazy', 'lazy-once', 'eager' or 'weak', but received: ${mode}.`, + expr.loc ) ); mode = "lazy"; diff --git a/lib/dependencies/SystemPlugin.js b/lib/dependencies/SystemPlugin.js index f20af45c6d6..69f3e8dc017 100644 --- a/lib/dependencies/SystemPlugin.js +++ b/lib/dependencies/SystemPlugin.js @@ -108,15 +108,15 @@ class SystemPlugin { class SystemImportDeprecationWarning extends WebpackError { constructor(module, loc) { - super(); + super( + "System.import() is deprecated and will be removed soon. Use import() instead.\n" + + "For more info visit https://webpack.js.org/guides/code-splitting/" + ); this.name = "SystemImportDeprecationWarning"; - this.message = - "System.import() is deprecated and will be removed soon. Use import() instead.\n" + - "For more info visit https://webpack.js.org/guides/code-splitting/"; - this.origin = this.module = module; - this.originLoc = loc; + this.module = module; + this.loc = loc; Error.captureStackTrace(this, this.constructor); } diff --git a/lib/performance/AssetsOverSizeLimitWarning.js b/lib/performance/AssetsOverSizeLimitWarning.js index 55c0220cd1e..aac8b65a9ee 100644 --- a/lib/performance/AssetsOverSizeLimitWarning.js +++ b/lib/performance/AssetsOverSizeLimitWarning.js @@ -9,21 +9,21 @@ const SizeFormatHelpers = require("../SizeFormatHelpers"); module.exports = class AssetsOverSizeLimitWarning extends WebpackError { constructor(assetsOverSizeLimit, assetLimit) { - super(); - - this.name = "AssetsOverSizeLimitWarning"; - this.assets = assetsOverSizeLimit; - const assetLists = this.assets + const assetLists = assetsOverSizeLimit .map( asset => `\n ${asset.name} (${SizeFormatHelpers.formatSize(asset.size)})` ) .join(""); - this.message = `asset size limit: The following asset(s) exceed the recommended size limit (${SizeFormatHelpers.formatSize( + + super(`asset size limit: The following asset(s) exceed the recommended size limit (${SizeFormatHelpers.formatSize( assetLimit )}). This can impact web performance. -Assets: ${assetLists}`; +Assets: ${assetLists}`); + + this.name = "AssetsOverSizeLimitWarning"; + this.assets = assetsOverSizeLimit; Error.captureStackTrace(this, this.constructor); } diff --git a/lib/performance/EntrypointsOverSizeLimitWarning.js b/lib/performance/EntrypointsOverSizeLimitWarning.js index e81ea1e29f8..3c29553d207 100644 --- a/lib/performance/EntrypointsOverSizeLimitWarning.js +++ b/lib/performance/EntrypointsOverSizeLimitWarning.js @@ -9,11 +9,7 @@ const SizeFormatHelpers = require("../SizeFormatHelpers"); module.exports = class EntrypointsOverSizeLimitWarning extends WebpackError { constructor(entrypoints, entrypointLimit) { - super(); - - this.name = "EntrypointsOverSizeLimitWarning"; - this.entrypoints = entrypoints; - const entrypointList = this.entrypoints + const entrypointList = entrypoints .map( entrypoint => `\n ${entrypoint.name} (${SizeFormatHelpers.formatSize( @@ -21,10 +17,13 @@ module.exports = class EntrypointsOverSizeLimitWarning extends WebpackError { )})\n${entrypoint.files.map(asset => ` ${asset}`).join("\n")}` ) .join(""); - this.message = `entrypoint size limit: The following entrypoint(s) combined asset size exceeds the recommended limit (${SizeFormatHelpers.formatSize( + super(`entrypoint size limit: The following entrypoint(s) combined asset size exceeds the recommended limit (${SizeFormatHelpers.formatSize( entrypointLimit )}). This can impact web performance. -Entrypoints:${entrypointList}\n`; +Entrypoints:${entrypointList}\n`); + + this.name = "EntrypointsOverSizeLimitWarning"; + this.entrypoints = entrypoints; Error.captureStackTrace(this, this.constructor); } diff --git a/lib/performance/NoAsyncChunksWarning.js b/lib/performance/NoAsyncChunksWarning.js index 9687d5056c4..c64475f9712 100644 --- a/lib/performance/NoAsyncChunksWarning.js +++ b/lib/performance/NoAsyncChunksWarning.js @@ -8,13 +8,13 @@ const WebpackError = require("../WebpackError"); module.exports = class NoAsyncChunksWarning extends WebpackError { constructor() { - super(); + super( + "webpack performance recommendations: \n" + + "You can limit the size of your bundles by using import() or require.ensure to lazy load some parts of your application.\n" + + "For more info visit https://webpack.js.org/guides/code-splitting/" + ); this.name = "NoAsyncChunksWarning"; - this.message = - "webpack performance recommendations: \n" + - "You can limit the size of your bundles by using import() or require.ensure to lazy load some parts of your application.\n" + - "For more info visit https://webpack.js.org/guides/code-splitting/"; Error.captureStackTrace(this, this.constructor); } diff --git a/lib/wasm/UnsupportedWebAssemblyFeatureError.js b/lib/wasm/UnsupportedWebAssemblyFeatureError.js index 132d2a190c7..fede4eb21d4 100644 --- a/lib/wasm/UnsupportedWebAssemblyFeatureError.js +++ b/lib/wasm/UnsupportedWebAssemblyFeatureError.js @@ -8,9 +8,8 @@ const WebpackError = require("../WebpackError"); module.exports = class UnsupportedWebAssemblyFeatureError extends WebpackError { /** @param {string} message Error message */ constructor(message) { - super(); + super(message); this.name = "UnsupportedWebAssemblyFeatureError"; - this.message = message; this.hideStack = true; Error.captureStackTrace(this, this.constructor); diff --git a/test/ModuleDependencyError.unittest.js b/test/ModuleDependencyError.unittest.js index 3412b437d4b..3e54fd79c7f 100644 --- a/test/ModuleDependencyError.unittest.js +++ b/test/ModuleDependencyError.unittest.js @@ -29,7 +29,11 @@ describe("ModuleDependencyError", () => { }); it("has a message property", () => { - expect(env.moduleDependencyError.message).toBe("Location Error Message"); + expect(env.moduleDependencyError.message).toBe("Error Message"); + }); + + it("has a loc property", () => { + expect(env.moduleDependencyError.loc).toBe("Location"); }); it("has a details property", () => { @@ -38,8 +42,8 @@ describe("ModuleDependencyError", () => { ); }); - it("has an origin property", () => { - expect(env.moduleDependencyError.origin).toBe("myModule"); + it("has an module property", () => { + expect(env.moduleDependencyError.module).toBe("myModule"); }); it("has an error property", () => { diff --git a/test/Stats.unittest.js b/test/Stats.unittest.js index c8f1f5d108d..9ee873f1656 100644 --- a/test/Stats.unittest.js +++ b/test/Stats.unittest.js @@ -19,7 +19,7 @@ describe( }); const inputPath = "./node_modules/ts-loader!./node_modules/vue-loader/lib/selector.js?type=script&index=0!./src/app.vue"; - const expectPath = `./src/app.vue (${inputPath})\n`; + const expectPath = `./src/app.vue (${inputPath})`; expect(mockStats.formatFilePath(inputPath)).toBe(expectPath); }); diff --git a/test/__snapshots__/StatsTestCases.test.js.snap b/test/__snapshots__/StatsTestCases.test.js.snap index cdd63b243ca..98e89ccc10a 100644 --- a/test/__snapshots__/StatsTestCases.test.js.snap +++ b/test/__snapshots__/StatsTestCases.test.js.snap @@ -1425,12 +1425,12 @@ Entrypoint main = main.js | ./index.js 15 bytes [built] | ./a.js 15 bytes [built] -ERROR in ./b.js +ERROR in ./b.js 6:7 Module parse failed: Unexpected token (6:7) You may need an appropriate loader to handle this file type. | includes | a -| parser ) +> parser ) | error | in @ ./a.js 2:0-13 diff --git a/test/cases/parsing/issue-2942/warnings.js b/test/cases/parsing/issue-2942/warnings.js index f831b6a05b1..217c81ed03a 100644 --- a/test/cases/parsing/issue-2942/warnings.js +++ b/test/cases/parsing/issue-2942/warnings.js @@ -1,5 +1,5 @@ module.exports = [ - [/System.get is not supported by webpack/], [/System.register is not supported by webpack/], + [/System.get is not supported by webpack/], [/System.set is not supported by webpack/], ]; From 34b6b13616b76f8a80a0ab96e6ccb0224199b900 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Mon, 4 Jun 2018 09:23:58 +0200 Subject: [PATCH 34/36] Pass message to base class --- lib/dependencies/ImportParserPlugin.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/dependencies/ImportParserPlugin.js b/lib/dependencies/ImportParserPlugin.js index 7bcad851fe7..f583fc6950c 100644 --- a/lib/dependencies/ImportParserPlugin.js +++ b/lib/dependencies/ImportParserPlugin.js @@ -262,10 +262,9 @@ class ImportParserPlugin { class CommentCompilationWarning extends WebpackError { constructor(message, module, loc) { - super(); + super(message); this.name = "CommentCompilationWarning"; - this.message = message; this.origin = this.module = module; this.originLoc = loc; From 9528aa5cbdad445e0578de05ab58770dfe850a03 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Mon, 4 Jun 2018 10:11:12 +0200 Subject: [PATCH 35/36] fixup test and error --- lib/dependencies/ImportParserPlugin.js | 4 ++-- .../__snapshots__/StatsTestCases.test.js.snap | 21 +++++++++++++------ .../webpack.config.js | 9 +++++++- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/lib/dependencies/ImportParserPlugin.js b/lib/dependencies/ImportParserPlugin.js index f583fc6950c..ed97658937f 100644 --- a/lib/dependencies/ImportParserPlugin.js +++ b/lib/dependencies/ImportParserPlugin.js @@ -266,8 +266,8 @@ class CommentCompilationWarning extends WebpackError { this.name = "CommentCompilationWarning"; - this.origin = this.module = module; - this.originLoc = loc; + this.module = module; + this.loc = loc; Error.captureStackTrace(this, this.constructor); } diff --git a/test/__snapshots__/StatsTestCases.test.js.snap b/test/__snapshots__/StatsTestCases.test.js.snap index 374f8599576..d796bb98ecf 100644 --- a/test/__snapshots__/StatsTestCases.test.js.snap +++ b/test/__snapshots__/StatsTestCases.test.js.snap @@ -1008,16 +1008,25 @@ Entrypoint entry = entry.js `; exports[`StatsTestCases should print correct stats for import-with-invalid-options-comments 1`] = ` -" 6 modules - -WARNING in ./chunk.js +"Built at: Thu Jan 01 1970 00:00:00 GMT +[0] ./chunk-a.js 27 bytes {2} [built] +[1] ./chunk-b.js 27 bytes {3} [built] +[2] ./chunk-c.js 27 bytes {4} [built] +[3] ./chunk-d.js 27 bytes {5} [built] +[4] ./chunk.js 401 bytes {0} [built] [3 warnings] +[5] ./index.js 50 bytes {1} [built] + +WARNING in ./chunk.js 4:11-77 Compilation error while processing magic comment(-s): /* webpack Prefetch: 0, webpackChunkName: \\"notGoingToCompile-c\\" */: Unexpected identifier + @ ./index.js 1:0-49 -WARNING in ./chunk.js +WARNING in ./chunk.js 5:11-38 Compilation error while processing magic comment(-s): /* webpackPrefetch: nope */: nope is not defined + @ ./index.js 1:0-49 -WARNING in ./chunk.js -Compilation error while processing magic comment(-s): /* webpackPrefetch: true, webpackChunkName: notGoingToCompileChunkName */: notGoingToCompileChunkName is not defined" +WARNING in ./chunk.js 2:11-84 +Compilation error while processing magic comment(-s): /* webpackPrefetch: true, webpackChunkName: notGoingToCompileChunkName */: notGoingToCompileChunkName is not defined + @ ./index.js 1:0-49" `; exports[`StatsTestCases should print correct stats for limit-chunk-count-plugin 1`] = ` diff --git a/test/statsCases/import-with-invalid-options-comments/webpack.config.js b/test/statsCases/import-with-invalid-options-comments/webpack.config.js index 417955cf6f3..7e5b36607b2 100644 --- a/test/statsCases/import-with-invalid-options-comments/webpack.config.js +++ b/test/statsCases/import-with-invalid-options-comments/webpack.config.js @@ -4,5 +4,12 @@ module.exports = { output: { chunkFilename: "[name].js" }, - stats: "minimal" + stats: { + timings: false, + hash: false, + entrypoints: false, + assets: false, + errorDetails: true, + moduleTrace: true + } }; From f65a24d9dbc7a3642b1f019b0ed37216b83438d1 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Mon, 4 Jun 2018 11:20:43 +0200 Subject: [PATCH 36/36] move warning into separate file --- lib/CommentCompilationWarning.js | 22 ++++++++++++++++++++++ lib/dependencies/ImportParserPlugin.js | 15 +-------------- 2 files changed, 23 insertions(+), 14 deletions(-) create mode 100644 lib/CommentCompilationWarning.js diff --git a/lib/CommentCompilationWarning.js b/lib/CommentCompilationWarning.js new file mode 100644 index 00000000000..29377e94692 --- /dev/null +++ b/lib/CommentCompilationWarning.js @@ -0,0 +1,22 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Tobias Koppers @sokra +*/ +"use strict"; + +const WebpackError = require("./WebpackError"); + +class CommentCompilationWarning extends WebpackError { + constructor(message, module, loc) { + super(message); + + this.name = "CommentCompilationWarning"; + + this.module = module; + this.loc = loc; + + Error.captureStackTrace(this, this.constructor); + } +} + +module.exports = CommentCompilationWarning; diff --git a/lib/dependencies/ImportParserPlugin.js b/lib/dependencies/ImportParserPlugin.js index ed97658937f..14043851965 100644 --- a/lib/dependencies/ImportParserPlugin.js +++ b/lib/dependencies/ImportParserPlugin.js @@ -10,7 +10,7 @@ const ImportDependenciesBlock = require("./ImportDependenciesBlock"); const ImportEagerDependency = require("./ImportEagerDependency"); const ContextDependencyHelpers = require("./ContextDependencyHelpers"); const UnsupportedFeatureWarning = require("../UnsupportedFeatureWarning"); -const WebpackError = require("../WebpackError"); +const CommentCompilationWarning = require("../CommentCompilationWarning"); class ImportParserPlugin { constructor(options) { @@ -260,17 +260,4 @@ class ImportParserPlugin { } } -class CommentCompilationWarning extends WebpackError { - constructor(message, module, loc) { - super(message); - - this.name = "CommentCompilationWarning"; - - this.module = module; - this.loc = loc; - - Error.captureStackTrace(this, this.constructor); - } -} - module.exports = ImportParserPlugin;