From cb553050c304d344ae88643ef58c68b42fc963c1 Mon Sep 17 00:00:00 2001 From: reduckted Date: Sat, 30 Jun 2018 17:54:47 +1000 Subject: [PATCH 1/3] Catch errors while parsing DLL manifest If the DLL manifest is blank or malformed, parsing it will throw an error, and if left uncaught will kill the process if webpack is in watch mode. Catching the error and adding it to the compilation's errors will result in a failed compilation, but will keep the process running while in watch mode. --- lib/DllReferencePlugin.js | 40 +++++++++++++++++-- .../__snapshots__/StatsTestCases.test.js.snap | 23 +++++++++++ .../blank-manifest.json | 0 .../entry.js | 1 + .../webpack.config.js | 15 +++++++ .../dll-reference-plugin-issue-7624/entry.js | 1 + .../non-blank-manifest.json | 11 +++++ .../webpack.config.js | 15 +++++++ 8 files changed, 103 insertions(+), 3 deletions(-) create mode 100644 test/statsCases/dll-reference-plugin-issue-7624-error/blank-manifest.json create mode 100644 test/statsCases/dll-reference-plugin-issue-7624-error/entry.js create mode 100644 test/statsCases/dll-reference-plugin-issue-7624-error/webpack.config.js create mode 100644 test/statsCases/dll-reference-plugin-issue-7624/entry.js create mode 100644 test/statsCases/dll-reference-plugin-issue-7624/non-blank-manifest.json create mode 100644 test/statsCases/dll-reference-plugin-issue-7624/webpack.config.js diff --git a/lib/DllReferencePlugin.js b/lib/DllReferencePlugin.js index b8cf3013be3..d7ea58f079e 100644 --- a/lib/DllReferencePlugin.js +++ b/lib/DllReferencePlugin.js @@ -10,6 +10,7 @@ const DelegatedModuleFactoryPlugin = require("./DelegatedModuleFactoryPlugin"); const ExternalModuleFactoryPlugin = require("./ExternalModuleFactoryPlugin"); const DelegatedExportsDependency = require("./dependencies/DelegatedExportsDependency"); const NullFactory = require("./NullFactory"); +const makePathsRelative = require("./util/identifier").makePathsRelative; const validateOptions = require("schema-utils"); const schema = require("../schemas/plugins/DllReferencePlugin.json"); @@ -43,9 +44,21 @@ class DllReferencePlugin { params.compilationDependencies.add(manifest); compiler.inputFileSystem.readFile(manifest, (err, result) => { if (err) return callback(err); - params["dll reference " + manifest] = parseJson( - result.toString("utf-8") - ); + // Catch errors parsing the manifest so that blank + // or malformed manifest files don't kill the process. + try { + params["dll reference " + manifest] = parseJson( + result.toString("utf-8") + ); + } catch (e) { + // Store the error in the params so that it can + // be added as a compilation error later on. + const manifestPath = this.options.context + ? makePathsRelative(this.options.context, manifest) + : manifest; + e.message = `Dll manifest ${manifestPath}\n${e.message}`; + params["dll reference parse error " + manifest] = e; + } return callback(); }); } else { @@ -57,6 +70,12 @@ class DllReferencePlugin { compiler.hooks.compile.tap("DllReferencePlugin", params => { let manifest = this.options.manifest; if (typeof manifest === "string") { + // If there was an error parsing the manifest + // file, exit now because the error will be added + // as a compilation error in the "compilation" hook. + if (params["dll reference parse error " + manifest]) { + return; + } manifest = params["dll reference " + manifest]; } const name = this.options.name || manifest.name; @@ -78,6 +97,21 @@ class DllReferencePlugin { extensions: this.options.extensions }).apply(normalModuleFactory); }); + + compiler.hooks.compilation.tap( + "DllReferencePlugin", + (compilation, params) => { + let manifest = this.options.manifest; + if (typeof manifest === "string") { + // If there was an error parsing the manifest file, add the + // error as a compilation error to make the compilation fail. + let e = params["dll reference parse error " + manifest]; + if (e) { + compilation.errors.push(e); + } + } + } + ); } } diff --git a/test/__snapshots__/StatsTestCases.test.js.snap b/test/__snapshots__/StatsTestCases.test.js.snap index 0dfae7d176a..b0c48a4a925 100644 --- a/test/__snapshots__/StatsTestCases.test.js.snap +++ b/test/__snapshots__/StatsTestCases.test.js.snap @@ -720,6 +720,29 @@ Child [0] ./index.js 24 bytes {0} [built]" `; +exports[`StatsTestCases should print correct stats for dll-reference-plugin-issue-7624 1`] = ` +"Hash: 29b62432962bce4c54c0 +Time: Xms +Built at: Thu Jan 01 1970 00:00:00 GMT + Asset Size Chunks Chunk Names +bundle.js 3.6 KiB 0 [emitted] main +Entrypoint main = bundle.js +[0] ./entry.js 29 bytes {0} [built]" +`; + +exports[`StatsTestCases should print correct stats for dll-reference-plugin-issue-7624-error 1`] = ` +"Hash: db465df0da5d95ebf88f +Time: Xms +Built at: Thu Jan 01 1970 00:00:00 GMT + Asset Size Chunks Chunk Names +bundle.js 3.6 KiB 0 main +Entrypoint main = bundle.js +[0] ./entry.js 29 bytes {0} [built] + +ERROR in Dll manifest Xdir/dll-reference-plugin-issue-7624-error/blank-manifest.json +Unexpected end of JSON input while parsing near ''" +`; + exports[`StatsTestCases should print correct stats for exclude-with-loader 1`] = ` "Hash: 52eadc5de721f000106b Time: Xms diff --git a/test/statsCases/dll-reference-plugin-issue-7624-error/blank-manifest.json b/test/statsCases/dll-reference-plugin-issue-7624-error/blank-manifest.json new file mode 100644 index 00000000000..e69de29bb2d diff --git a/test/statsCases/dll-reference-plugin-issue-7624-error/entry.js b/test/statsCases/dll-reference-plugin-issue-7624-error/entry.js new file mode 100644 index 00000000000..7215576fcc1 --- /dev/null +++ b/test/statsCases/dll-reference-plugin-issue-7624-error/entry.js @@ -0,0 +1 @@ +// Intentionally left blank. diff --git a/test/statsCases/dll-reference-plugin-issue-7624-error/webpack.config.js b/test/statsCases/dll-reference-plugin-issue-7624-error/webpack.config.js new file mode 100644 index 00000000000..aa0403c269b --- /dev/null +++ b/test/statsCases/dll-reference-plugin-issue-7624-error/webpack.config.js @@ -0,0 +1,15 @@ +var webpack = require("../../../"); + +module.exports = { + mode: "production", + entry: "./entry.js", + output: { + filename: "bundle.js" + }, + plugins: [ + new webpack.DllReferencePlugin({ + manifest: __dirname + "/blank-manifest.json", + name: "blank-manifest" + }) + ] +}; diff --git a/test/statsCases/dll-reference-plugin-issue-7624/entry.js b/test/statsCases/dll-reference-plugin-issue-7624/entry.js new file mode 100644 index 00000000000..7215576fcc1 --- /dev/null +++ b/test/statsCases/dll-reference-plugin-issue-7624/entry.js @@ -0,0 +1 @@ +// Intentionally left blank. diff --git a/test/statsCases/dll-reference-plugin-issue-7624/non-blank-manifest.json b/test/statsCases/dll-reference-plugin-issue-7624/non-blank-manifest.json new file mode 100644 index 00000000000..6f0100bea85 --- /dev/null +++ b/test/statsCases/dll-reference-plugin-issue-7624/non-blank-manifest.json @@ -0,0 +1,11 @@ +{ + "name": "foo", + "content": { + "./foo.js": { + "id": 0, + "buildMeta": { + "providedExports": true + } + } + } +} diff --git a/test/statsCases/dll-reference-plugin-issue-7624/webpack.config.js b/test/statsCases/dll-reference-plugin-issue-7624/webpack.config.js new file mode 100644 index 00000000000..cfd2bfe9301 --- /dev/null +++ b/test/statsCases/dll-reference-plugin-issue-7624/webpack.config.js @@ -0,0 +1,15 @@ +var webpack = require("../../../"); + +module.exports = { + mode: "production", + entry: "./entry.js", + output: { + filename: "bundle.js" + }, + plugins: [ + new webpack.DllReferencePlugin({ + manifest: __dirname + "/non-blank-manifest.json", + name: "non-blank-manifest" + }) + ] +}; From 8f748e266bf587f84c7370484f720936f9be1f94 Mon Sep 17 00:00:00 2001 From: reduckted Date: Mon, 2 Jul 2018 19:58:45 +1000 Subject: [PATCH 2/3] Created a new WebpackError derived class for dll manifest errors. --- lib/DllReferencePlugin.js | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/lib/DllReferencePlugin.js b/lib/DllReferencePlugin.js index d7ea58f079e..1071ac6e22e 100644 --- a/lib/DllReferencePlugin.js +++ b/lib/DllReferencePlugin.js @@ -11,6 +11,7 @@ const ExternalModuleFactoryPlugin = require("./ExternalModuleFactoryPlugin"); const DelegatedExportsDependency = require("./dependencies/DelegatedExportsDependency"); const NullFactory = require("./NullFactory"); const makePathsRelative = require("./util/identifier").makePathsRelative; +const WebpackError = require("./WebpackError"); const validateOptions = require("schema-utils"); const schema = require("../schemas/plugins/DllReferencePlugin.json"); @@ -56,8 +57,9 @@ class DllReferencePlugin { const manifestPath = this.options.context ? makePathsRelative(this.options.context, manifest) : manifest; - e.message = `Dll manifest ${manifestPath}\n${e.message}`; - params["dll reference parse error " + manifest] = e; + params[ + "dll reference parse error " + manifest + ] = new DllManifestError(manifestPath, e.message); } return callback(); }); @@ -115,4 +117,15 @@ class DllReferencePlugin { } } +class DllManifestError extends WebpackError { + constructor(filename, message) { + super(); + + this.name = "DllManifestError"; + this.message = `Dll manifest ${filename}\n${message}`; + + Error.captureStackTrace(this, this.constructor); + } +} + module.exports = DllReferencePlugin; From 5b6f99b8d40af5f7bb6e3be570e13d8c1d81c9ee Mon Sep 17 00:00:00 2001 From: reduckted Date: Mon, 2 Jul 2018 21:50:30 +1000 Subject: [PATCH 3/3] Used the compiler's context to get a relative path to the manifest file. --- lib/DllReferencePlugin.js | 7 ++++--- test/__snapshots__/StatsTestCases.test.js.snap | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/DllReferencePlugin.js b/lib/DllReferencePlugin.js index 1071ac6e22e..151862e5f19 100644 --- a/lib/DllReferencePlugin.js +++ b/lib/DllReferencePlugin.js @@ -54,9 +54,10 @@ class DllReferencePlugin { } catch (e) { // Store the error in the params so that it can // be added as a compilation error later on. - const manifestPath = this.options.context - ? makePathsRelative(this.options.context, manifest) - : manifest; + const manifestPath = makePathsRelative( + compiler.options.context, + manifest + ); params[ "dll reference parse error " + manifest ] = new DllManifestError(manifestPath, e.message); diff --git a/test/__snapshots__/StatsTestCases.test.js.snap b/test/__snapshots__/StatsTestCases.test.js.snap index b0c48a4a925..65c621947a2 100644 --- a/test/__snapshots__/StatsTestCases.test.js.snap +++ b/test/__snapshots__/StatsTestCases.test.js.snap @@ -731,7 +731,7 @@ Entrypoint main = bundle.js `; exports[`StatsTestCases should print correct stats for dll-reference-plugin-issue-7624-error 1`] = ` -"Hash: db465df0da5d95ebf88f +"Hash: 701dcf62b26d0347b899 Time: Xms Built at: Thu Jan 01 1970 00:00:00 GMT Asset Size Chunks Chunk Names @@ -739,7 +739,7 @@ bundle.js 3.6 KiB 0 main Entrypoint main = bundle.js [0] ./entry.js 29 bytes {0} [built] -ERROR in Dll manifest Xdir/dll-reference-plugin-issue-7624-error/blank-manifest.json +ERROR in Dll manifest blank-manifest.json Unexpected end of JSON input while parsing near ''" `;