From 296542ed79d8f466177ea7777f7f8a5c0b0e65fc Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Thu, 22 Mar 2018 19:52:11 +0100 Subject: [PATCH 1/5] add [contenthash] support --- lib/Chunk.js | 8 +++ lib/Compilation.js | 11 +++-- lib/JavascriptModulesPlugin.js | 26 +++++++++- lib/SourceMapDevToolPlugin.js | 13 ++--- lib/TemplatedPathPlugin.js | 31 +++++++++++- lib/node/NodeMainTemplatePlugin.js | 49 ++++++++++++++++++- lib/web/JsonpMainTemplatePlugin.js | 26 +++++++++- lib/webpack.js | 3 ++ lib/webworker/WebWorkerMainTemplatePlugin.js | 25 +++++++++- .../output-filename/webpack.config.js | 24 +++++++++ 10 files changed, 194 insertions(+), 22 deletions(-) diff --git a/lib/Chunk.js b/lib/Chunk.js index 296f09b9c8e..6a317a63703 100644 --- a/lib/Chunk.js +++ b/lib/Chunk.js @@ -55,6 +55,7 @@ class Chunk { this.files = []; this.rendered = false; this.hash = undefined; + this.contentHash = Object.create(null); this.renderedHash = undefined; this.chunkReason = undefined; this.extraAsync = false; @@ -340,15 +341,22 @@ class Chunk { getChunkMaps(realHash) { const chunkHashMap = Object.create(null); + const chunkContentHashMap = Object.create(null); const chunkNameMap = Object.create(null); for (const chunk of this.getAllAsyncChunks()) { chunkHashMap[chunk.id] = realHash ? chunk.hash : chunk.renderedHash; + for (const key of Object.keys(chunk.contentHash)) { + if (!chunkContentHashMap[key]) + chunkContentHashMap[key] = Object.create(null); + chunkContentHashMap[key][chunk.id] = chunk.contentHash[key]; + } if (chunk.name) chunkNameMap[chunk.id] = chunk.name; } return { hash: chunkHashMap, + contentHash: chunkContentHashMap, name: chunkNameMap }; } diff --git a/lib/Compilation.js b/lib/Compilation.js index cb6542790c2..7ea061cfc50 100644 --- a/lib/Compilation.js +++ b/lib/Compilation.js @@ -146,6 +146,7 @@ class Compilation extends Tapable { recordChunks: new SyncHook(["chunks", "records"]), beforeHash: new SyncHook([]), + contentHash: new SyncHook(["chunk"]), afterHash: new SyncHook([]), recordHash: new SyncHook(["records"]), @@ -1680,15 +1681,15 @@ class Compilation extends Tapable { const chunkHash = createHash(hashFunction); if (outputOptions.hashSalt) chunkHash.update(outputOptions.hashSalt); chunk.updateHash(chunkHash); - if (chunk.hasRuntime()) { - this.mainTemplate.updateHashForChunk(chunkHash, chunk); - } else { - this.chunkTemplate.updateHashForChunk(chunkHash, chunk); - } + const template = chunk.hasRuntime() + ? this.mainTemplate + : this.chunkTemplate; + template.updateHashForChunk(chunkHash, chunk); this.hooks.chunkHash.call(chunk, chunkHash); chunk.hash = chunkHash.digest(hashDigest); hash.update(chunk.hash); chunk.renderedHash = chunk.hash.substr(0, hashDigestLength); + this.hooks.contentHash.call(chunk); } this.fullHash = hash.digest(hashDigest); this.hash = this.fullHash.substr(0, hashDigestLength); diff --git a/lib/JavascriptModulesPlugin.js b/lib/JavascriptModulesPlugin.js index 4e7db264287..a3ff8bc2257 100644 --- a/lib/JavascriptModulesPlugin.js +++ b/lib/JavascriptModulesPlugin.js @@ -8,6 +8,7 @@ const Parser = require("./Parser"); const Template = require("./Template"); const { ConcatSource } = require("webpack-sources"); const JavascriptGenerator = require("./JavascriptGenerator"); +const createHash = require("./util/createHash"); class JavascriptModulesPlugin { apply(compiler) { @@ -72,6 +73,7 @@ class JavascriptModulesPlugin { filenameTemplate, pathOptions: { noChunkHash: !useChunkHash, + contentHashType: "javascript", chunk }, identifier: `chunk${chunk.id}`, @@ -115,7 +117,8 @@ class JavascriptModulesPlugin { ), filenameTemplate, pathOptions: { - chunk + chunk, + contentHashType: "javascript" }, identifier: `chunk${chunk.id}`, hash: chunk.hash @@ -124,6 +127,27 @@ class JavascriptModulesPlugin { return result; } ); + compilation.hooks.contentHash.tap("JavascriptModulesPlugin", chunk => { + const outputOptions = compilation.outputOptions; + const hashFunction = outputOptions.hashFunction; + const hashSalt = outputOptions.hashSalt; + const hashDigest = outputOptions.hashDigest; + const hashDigestLength = outputOptions.hashDigestLength; + const hash = createHash(hashFunction); + if (hashSalt) hash.update(hashSalt); + const template = chunk.hasRuntime() + ? compilation.mainTemplate + : compilation.chunkTemplate; + template.updateHashForChunk(hash, chunk); + for (const m of chunk.modulesIterable) { + if (typeof m.source === "function") { + hash.update(m.hash); + } + } + chunk.contentHash.javascript = hash + .digest(hashDigest) + .substr(0, hashDigestLength); + }); } ); } diff --git a/lib/SourceMapDevToolPlugin.js b/lib/SourceMapDevToolPlugin.js index b207f7a0aa1..6fd4408e35c 100644 --- a/lib/SourceMapDevToolPlugin.js +++ b/lib/SourceMapDevToolPlugin.js @@ -249,16 +249,11 @@ class SourceMapDevToolPlugin { ? path.relative(options.fileContext, filename) : filename, query, - basename: basename(filename) + basename: basename(filename), + contentHash: createHash("md4") + .update(sourceMapString) + .digest("hex") }); - if (sourceMapFile.includes("[contenthash]")) { - sourceMapFile = sourceMapFile.replace( - /\[contenthash\]/g, - createHash("md4") - .update(sourceMapString) - .digest("hex") - ); - } const sourceMapUrl = options.publicPath ? options.publicPath + sourceMapFile.replace(/\\/g, "/") : path diff --git a/lib/TemplatedPathPlugin.js b/lib/TemplatedPathPlugin.js index 40b8033e53d..2438432dc97 100644 --- a/lib/TemplatedPathPlugin.js +++ b/lib/TemplatedPathPlugin.js @@ -7,6 +7,7 @@ const REGEXP_HASH = /\[hash(?::(\d+))?\]/gi, REGEXP_CHUNKHASH = /\[chunkhash(?::(\d+))?\]/gi, REGEXP_MODULEHASH = /\[modulehash(?::(\d+))?\]/gi, + REGEXP_CONTENTHASH = /\[contenthash(?::(\d+))?\]/gi, REGEXP_NAME = /\[name\]/gi, REGEXP_ID = /\[id\]/gi, REGEXP_MODULEID = /\[moduleid\]/gi, @@ -18,6 +19,7 @@ const REGEXP_HASH = /\[hash(?::(\d+))?\]/gi, // We use a normal RegExp instead of .test const REGEXP_HASH_FOR_TEST = new RegExp(REGEXP_HASH.source, "i"), REGEXP_CHUNKHASH_FOR_TEST = new RegExp(REGEXP_CHUNKHASH.source, "i"), + REGEXP_CONTENTHASH_FOR_TEST = new RegExp(REGEXP_CONTENTHASH.source, "i"), REGEXP_NAME_FOR_TEST = new RegExp(REGEXP_NAME.source, "i"); const withHashLength = (replacer, handlerFn) => { @@ -55,6 +57,15 @@ const replacePathVariables = (path, data) => { const chunkName = chunk && (chunk.name || chunk.id); const chunkHash = chunk && (chunk.renderedHash || chunk.hash); const chunkHashWithLength = chunk && chunk.hashWithLength; + const contentHashType = data.contentHashType; + const contentHash = + (chunk && chunk.contentHash && chunk.contentHash[contentHashType]) || + data.contentHash; + const contentHashWithLength = + (chunk && + chunk.contentHashWithLength && + chunk.contentHashWithLength[contentHashType]) || + data.contentHashWithLength; const module = data.module; const moduleId = module && module.id; const moduleHash = module && (module.renderedHash || module.hash); @@ -64,9 +75,15 @@ const replacePathVariables = (path, data) => { path = path(data); } - if (data.noChunkHash && REGEXP_CHUNKHASH_FOR_TEST.test(path)) { + if ( + data.noChunkHash && + (REGEXP_CHUNKHASH_FOR_TEST.test(path) || + REGEXP_CONTENTHASH_FOR_TEST.test(path)) + ) { throw new Error( - `Cannot use [chunkhash] for chunk in '${path}' (use [hash] instead)` + `Cannot use [chunkhash] or [contenthash] for chunk in '${ + path + }' (use [hash] instead)` ); } @@ -80,6 +97,10 @@ const replacePathVariables = (path, data) => { REGEXP_CHUNKHASH, withHashLength(getReplacer(chunkHash), chunkHashWithLength) ) + .replace( + REGEXP_CONTENTHASH, + withHashLength(getReplacer(contentHash), contentHashWithLength) + ) .replace( REGEXP_MODULEHASH, withHashLength(getReplacer(moduleHash), moduleHashWithLength) @@ -115,6 +136,7 @@ class TemplatedPathPlugin { if ( REGEXP_HASH_FOR_TEST.test(publicPath) || REGEXP_CHUNKHASH_FOR_TEST.test(publicPath) || + REGEXP_CONTENTHASH_FOR_TEST.test(publicPath) || REGEXP_NAME_FOR_TEST.test(publicPath) ) return true; @@ -132,6 +154,11 @@ class TemplatedPathPlugin { outputOptions.chunkFilename || outputOptions.filename; if (REGEXP_CHUNKHASH_FOR_TEST.test(chunkFilename)) hash.update(JSON.stringify(chunk.getChunkMaps(true).hash)); + if (REGEXP_CONTENTHASH_FOR_TEST.test(chunkFilename)) { + hash.update( + JSON.stringify(chunk.getChunkMaps(true).contentHash.javascript) + ); + } if (REGEXP_NAME_FOR_TEST.test(chunkFilename)) hash.update(JSON.stringify(chunk.getChunkMaps(true).name)); } diff --git a/lib/node/NodeMainTemplatePlugin.js b/lib/node/NodeMainTemplatePlugin.js index 139a8a404e1..54ede089ec6 100644 --- a/lib/node/NodeMainTemplatePlugin.js +++ b/lib/node/NodeMainTemplatePlugin.js @@ -125,10 +125,33 @@ module.exports = class NodeMainTemplatePlugin { shortChunkHashMap )}[chunkId] + "`; }, + contentHash: { + javascript: `" + ${JSON.stringify( + chunkMaps.contentHash.javascript + )}[chunkId] + "` + }, + contentHashWithLength: { + javascript: length => { + const shortContentHashMap = {}; + const contentHash = + chunkMaps.contentHash.javascript; + for (const chunkId of Object.keys(contentHash)) { + if (typeof contentHash[chunkId] === "string") { + shortContentHashMap[chunkId] = contentHash[ + chunkId + ].substr(0, length); + } + } + return `" + ${JSON.stringify( + shortContentHashMap + )}[chunkId] + "`; + } + }, name: `" + (${JSON.stringify( chunkMaps.name )}[chunkId]||chunkId) + "` - } + }, + contentHashType: "javascript" } ) + ";", @@ -187,10 +210,32 @@ module.exports = class NodeMainTemplatePlugin { shortChunkHashMap )}[chunkId] + "`; }, + contentHash: { + javascript: `" + ${JSON.stringify( + chunkMaps.contentHash.javascript + )}[chunkId] + "` + }, + contentHashWithLength: { + javascript: length => { + const shortContentHashMap = {}; + const contentHash = chunkMaps.contentHash.javascript; + for (const chunkId of Object.keys(contentHash)) { + if (typeof contentHash[chunkId] === "string") { + shortContentHashMap[chunkId] = contentHash[ + chunkId + ].substr(0, length); + } + } + return `" + ${JSON.stringify( + shortContentHashMap + )}[chunkId] + "`; + } + }, name: `" + (${JSON.stringify( chunkMaps.name )}[chunkId]||chunkId) + "` - } + }, + contentHashType: "javascript" } ); return Template.asString([ diff --git a/lib/web/JsonpMainTemplatePlugin.js b/lib/web/JsonpMainTemplatePlugin.js index c5ec864d045..344fb9752d2 100644 --- a/lib/web/JsonpMainTemplatePlugin.js +++ b/lib/web/JsonpMainTemplatePlugin.js @@ -88,8 +88,30 @@ class JsonpMainTemplatePlugin { }, name: `" + (${JSON.stringify( chunkMaps.name - )}[chunkId]||chunkId) + "` - } + )}[chunkId]||chunkId) + "`, + contentHash: { + javascript: `" + ${JSON.stringify( + chunkMaps.contentHash.javascript + )}[chunkId] + "` + }, + contentHashWithLength: { + javascript: length => { + const shortContentHashMap = {}; + const contentHash = chunkMaps.contentHash.javascript; + for (const chunkId of Object.keys(contentHash)) { + if (typeof contentHash[chunkId] === "string") { + shortContentHashMap[chunkId] = contentHash[ + chunkId + ].substr(0, length); + } + } + return `" + ${JSON.stringify( + shortContentHashMap + )}[chunkId] + "`; + } + } + }, + contentHashType: "javascript" } ); return Template.asString([ diff --git a/lib/webpack.js b/lib/webpack.js index 73bcbc6bd67..f49d7964965 100644 --- a/lib/webpack.js +++ b/lib/webpack.js @@ -153,6 +153,9 @@ exportPlugins((exports.node = {}), { exportPlugins((exports.debug = {}), { ProfilingPlugin: () => require("./debug/ProfilingPlugin") }); +exportPlugins((exports.util = {}), { + createHash: () => require("./util/createHash") +}); const defineMissingPluginError = (namespace, pluginName, errorMessage) => { Reflect.defineProperty(namespace, pluginName, { diff --git a/lib/webworker/WebWorkerMainTemplatePlugin.js b/lib/webworker/WebWorkerMainTemplatePlugin.js index aee10e38fa6..f5881475bcd 100644 --- a/lib/webworker/WebWorkerMainTemplatePlugin.js +++ b/lib/webworker/WebWorkerMainTemplatePlugin.js @@ -35,6 +35,7 @@ class WebWorkerMainTemplatePlugin { "WebWorkerMainTemplatePlugin", (_, chunk, hash) => { const chunkFilename = mainTemplate.outputOptions.chunkFilename; + const chunkMaps = chunk.getChunkMaps(); return Template.asString([ "promises.push(Promise.resolve().then(function() {", Template.indent([ @@ -51,7 +52,29 @@ class WebWorkerMainTemplatePlugin { )} + "`, chunk: { id: '" + chunkId + "' - } + }, + contentHash: { + javascript: `" + ${JSON.stringify( + chunkMaps.contentHash.javascript + )}[chunkId] + "` + }, + contentHashWithLength: { + javascript: length => { + const shortContentHashMap = {}; + const contentHash = chunkMaps.contentHash.javascript; + for (const chunkId of Object.keys(contentHash)) { + if (typeof contentHash[chunkId] === "string") { + shortContentHashMap[chunkId] = contentHash[ + chunkId + ].substr(0, length); + } + } + return `" + ${JSON.stringify( + shortContentHashMap + )}[chunkId] + "`; + } + }, + contentHashType: "javascript" }) + ");" ]), diff --git a/test/configCases/hash-length/output-filename/webpack.config.js b/test/configCases/hash-length/output-filename/webpack.config.js index b158b7f0bf2..5b480e34b82 100644 --- a/test/configCases/hash-length/output-filename/webpack.config.js +++ b/test/configCases/hash-length/output-filename/webpack.config.js @@ -115,6 +115,30 @@ module.exports = [ expectedFilenameLength: 31, expectedChunkFilenameLength: 20 } + }, + { + name: "contenthash in node", + output: { + filename: "bundle10.[contenthash].js", + chunkFilename: "[id].bundle10.[contenthash].js" + }, + target: "node", + amd: { + expectedFilenameLength: 32, + expectedChunkFilenameLength: 34 + } + }, + { + name: "contenthash in node with length", + output: { + filename: "bundle11.[contenthash:7].js", + chunkFilename: "[id].bundle11.[contenthash:7].js" + }, + target: "node", + amd: { + expectedFilenameLength: 9 + 7 + 3, + expectedChunkFilenameLength: 2 + 9 + 7 + 3 + } } ]; From c328c653712e7bd08bb985b5ee69dcc49cc41b4d Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Sat, 24 Mar 2018 11:21:41 +0100 Subject: [PATCH 2/5] use destructing for more readable code --- lib/JavascriptModulesPlugin.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/JavascriptModulesPlugin.js b/lib/JavascriptModulesPlugin.js index a3ff8bc2257..1ea30667d13 100644 --- a/lib/JavascriptModulesPlugin.js +++ b/lib/JavascriptModulesPlugin.js @@ -129,10 +129,12 @@ class JavascriptModulesPlugin { ); compilation.hooks.contentHash.tap("JavascriptModulesPlugin", chunk => { const outputOptions = compilation.outputOptions; - const hashFunction = outputOptions.hashFunction; - const hashSalt = outputOptions.hashSalt; - const hashDigest = outputOptions.hashDigest; - const hashDigestLength = outputOptions.hashDigestLength; + const { + hashSalt, + hashDigest, + hashDigestLength, + hashFunction + } = outputOptions; const hash = createHash(hashFunction); if (hashSalt) hash.update(hashSalt); const template = chunk.hasRuntime() From d7a0fc341bc2284fdd70f59251cead352b0fc238 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Sat, 24 Mar 2018 11:22:22 +0100 Subject: [PATCH 3/5] fix bug without async chunks, add more tests --- lib/TemplatedPathPlugin.js | 4 +- .../hash-length/output-filename/no-async.js | 5 ++ .../output-filename/test.config.js | 33 +++++++----- .../output-filename/webpack.config.js | 52 +++++++++++++++++++ 4 files changed, 80 insertions(+), 14 deletions(-) create mode 100644 test/configCases/hash-length/output-filename/no-async.js diff --git a/lib/TemplatedPathPlugin.js b/lib/TemplatedPathPlugin.js index 2438432dc97..27273bd6316 100644 --- a/lib/TemplatedPathPlugin.js +++ b/lib/TemplatedPathPlugin.js @@ -156,7 +156,9 @@ class TemplatedPathPlugin { hash.update(JSON.stringify(chunk.getChunkMaps(true).hash)); if (REGEXP_CONTENTHASH_FOR_TEST.test(chunkFilename)) { hash.update( - JSON.stringify(chunk.getChunkMaps(true).contentHash.javascript) + JSON.stringify( + chunk.getChunkMaps(true).contentHash.javascript || {} + ) ); } if (REGEXP_NAME_FOR_TEST.test(chunkFilename)) diff --git a/test/configCases/hash-length/output-filename/no-async.js b/test/configCases/hash-length/output-filename/no-async.js new file mode 100644 index 00000000000..e3bce91d575 --- /dev/null +++ b/test/configCases/hash-length/output-filename/no-async.js @@ -0,0 +1,5 @@ +it("should compile and run the test " + NAME, function() {}); + +if (Math.random() < -1) { + require(["./chunk"], function() {}); +} diff --git a/test/configCases/hash-length/output-filename/test.config.js b/test/configCases/hash-length/output-filename/test.config.js index 5ed043b07e1..db9bb3bf1ec 100644 --- a/test/configCases/hash-length/output-filename/test.config.js +++ b/test/configCases/hash-length/output-filename/test.config.js @@ -3,7 +3,7 @@ require("should"); var findFile = function(files, regex) { return files.find(function(file) { - if(regex.test(file)) { + if (regex.test(file)) { return true; } }); @@ -17,23 +17,30 @@ module.exports = { findBundle: function(i, options) { var files = fs.readdirSync(options.output.path); - var bundleDetects = [{ - regex: new RegExp("^0.bundle" + i, "i"), - expectedNameLength: options.amd.expectedChunkFilenameLength - }, { - regex: new RegExp("^bundle" + i, "i"), - expectedNameLength: options.amd.expectedFilenameLength - }]; + var bundleDetects = [ + options.amd.expectedChunkFilenameLength && { + regex: new RegExp("^0.bundle" + i, "i"), + expectedNameLength: options.amd.expectedChunkFilenameLength + }, + { + regex: new RegExp("^bundle" + i, "i"), + expectedNameLength: options.amd.expectedFilenameLength + } + ].filter(Boolean); var bundleDetect; var filename; - for(bundleDetect of bundleDetects) { + for (bundleDetect of bundleDetects) { filename = findFile(files, bundleDetect.regex); - verifyFilenameLength( - filename, - bundleDetect.expectedNameLength - ); + if (!filename) { + throw new Error( + `No file found with correct name (regex: ${ + bundleDetect.regex.source + }, files: ${files.join(", ")})` + ); + } + verifyFilenameLength(filename, bundleDetect.expectedNameLength); } return "./" + filename; diff --git a/test/configCases/hash-length/output-filename/webpack.config.js b/test/configCases/hash-length/output-filename/webpack.config.js index 5b480e34b82..971f6ee6ebb 100644 --- a/test/configCases/hash-length/output-filename/webpack.config.js +++ b/test/configCases/hash-length/output-filename/webpack.config.js @@ -139,6 +139,58 @@ module.exports = [ expectedFilenameLength: 9 + 7 + 3, expectedChunkFilenameLength: 2 + 9 + 7 + 3 } + }, + { + name: "contenthash in async-node", + output: { + filename: "bundle12.[contenthash].js", + chunkFilename: "[id].bundle12.[contenthash].js" + }, + target: "async-node", + amd: { + expectedFilenameLength: 32, + expectedChunkFilenameLength: 34 + } + }, + { + name: "contenthash in async-node with length", + output: { + filename: "bundle13.[contenthash:7].js", + chunkFilename: "[id].bundle13.[contenthash:7].js" + }, + target: "async-node", + amd: { + expectedFilenameLength: 9 + 7 + 3, + expectedChunkFilenameLength: 2 + 9 + 7 + 3 + } + }, + { + name: "contenthash in webpack", + entry: "./no-async", + output: { + filename: "bundle14.[contenthash].js", + chunkFilename: "[id].bundle14.[contenthash].js", + globalObject: "this" + }, + target: "web", + amd: { + expectedFilenameLength: 32, + expectedChunkFilenameLength: 34 + } + }, + { + name: "contenthash in async-node with length", + entry: "./no-async", + output: { + filename: "bundle15.[contenthash:7].js", + chunkFilename: "[id].bundle15.[contenthash:7].js", + globalObject: "this" + }, + target: "web", + amd: { + expectedFilenameLength: 9 + 7 + 3, + expectedChunkFilenameLength: 2 + 9 + 7 + 3 + } } ]; From 06e9a5709b502bbd9f0329dde65197aea24507c6 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Sat, 24 Mar 2018 12:06:46 +0100 Subject: [PATCH 4/5] get rid of webpackJsonp global leak --- test/ConfigTestCases.test.js | 1 + test/configCases/hash-length/output-filename/test.config.js | 3 +++ 2 files changed, 4 insertions(+) diff --git a/test/ConfigTestCases.test.js b/test/ConfigTestCases.test.js index 0a24486ff40..64cd0f2eeff 100644 --- a/test/ConfigTestCases.test.js +++ b/test/ConfigTestCases.test.js @@ -226,6 +226,7 @@ describe("ConfigTestCases", () => { ); if (exportedTests < filesCount) return done(new Error("No tests exported by test case")); + if (testConfig.afterExecute) testConfig.afterExecute(); process.nextTick(done); }); }); diff --git a/test/configCases/hash-length/output-filename/test.config.js b/test/configCases/hash-length/output-filename/test.config.js index db9bb3bf1ec..d77b4a23fbe 100644 --- a/test/configCases/hash-length/output-filename/test.config.js +++ b/test/configCases/hash-length/output-filename/test.config.js @@ -44,5 +44,8 @@ module.exports = { } return "./" + filename; + }, + afterExecute: () => { + delete global.webpackJsonp; } }; From b018bc7ac5e21ac5fb550c74a8b3172b62bb3f4d Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Sun, 25 Mar 2018 10:15:01 +0200 Subject: [PATCH 5/5] more tests and fixes for webworker --- lib/webworker/WebWorkerMainTemplatePlugin.js | 38 +++++++++---------- .../output-filename/test.config.js | 1 + .../output-filename/webpack.config.js | 28 ++++++++++++++ 3 files changed, 48 insertions(+), 19 deletions(-) diff --git a/lib/webworker/WebWorkerMainTemplatePlugin.js b/lib/webworker/WebWorkerMainTemplatePlugin.js index f5881475bcd..3408511bf92 100644 --- a/lib/webworker/WebWorkerMainTemplatePlugin.js +++ b/lib/webworker/WebWorkerMainTemplatePlugin.js @@ -51,27 +51,27 @@ class WebWorkerMainTemplatePlugin { length )} + "`, chunk: { - id: '" + chunkId + "' - }, - contentHash: { - javascript: `" + ${JSON.stringify( - chunkMaps.contentHash.javascript - )}[chunkId] + "` - }, - contentHashWithLength: { - javascript: length => { - const shortContentHashMap = {}; - const contentHash = chunkMaps.contentHash.javascript; - for (const chunkId of Object.keys(contentHash)) { - if (typeof contentHash[chunkId] === "string") { - shortContentHashMap[chunkId] = contentHash[ - chunkId - ].substr(0, length); + id: '" + chunkId + "', + contentHash: { + javascript: `" + ${JSON.stringify( + chunkMaps.contentHash.javascript + )}[chunkId] + "` + }, + contentHashWithLength: { + javascript: length => { + const shortContentHashMap = {}; + const contentHash = chunkMaps.contentHash.javascript; + for (const chunkId of Object.keys(contentHash)) { + if (typeof contentHash[chunkId] === "string") { + shortContentHashMap[chunkId] = contentHash[ + chunkId + ].substr(0, length); + } } + return `" + ${JSON.stringify( + shortContentHashMap + )}[chunkId] + "`; } - return `" + ${JSON.stringify( - shortContentHashMap - )}[chunkId] + "`; } }, contentHashType: "javascript" diff --git a/test/configCases/hash-length/output-filename/test.config.js b/test/configCases/hash-length/output-filename/test.config.js index d77b4a23fbe..a6d2483ca2f 100644 --- a/test/configCases/hash-length/output-filename/test.config.js +++ b/test/configCases/hash-length/output-filename/test.config.js @@ -47,5 +47,6 @@ module.exports = { }, afterExecute: () => { delete global.webpackJsonp; + delete global.webpackChunk; } }; diff --git a/test/configCases/hash-length/output-filename/webpack.config.js b/test/configCases/hash-length/output-filename/webpack.config.js index 971f6ee6ebb..ca75582b24b 100644 --- a/test/configCases/hash-length/output-filename/webpack.config.js +++ b/test/configCases/hash-length/output-filename/webpack.config.js @@ -191,6 +191,34 @@ module.exports = [ expectedFilenameLength: 9 + 7 + 3, expectedChunkFilenameLength: 2 + 9 + 7 + 3 } + }, + { + name: "contenthash in webpack", + entry: "./no-async", + output: { + filename: "bundle16.[contenthash].js", + chunkFilename: "[id].bundle16.[contenthash].js", + globalObject: "this" + }, + target: "webworker", + amd: { + expectedFilenameLength: 32, + expectedChunkFilenameLength: 34 + } + }, + { + name: "contenthash in async-node with length", + entry: "./no-async", + output: { + filename: "bundle17.[contenthash:7].js", + chunkFilename: "[id].bundle17.[contenthash:7].js", + globalObject: "this" + }, + target: "webworker", + amd: { + expectedFilenameLength: 9 + 7 + 3, + expectedChunkFilenameLength: 2 + 9 + 7 + 3 + } } ];