Skip to content

Commit

Permalink
Merge pull request #11686 from webpack/bugfix/11677
Browse files Browse the repository at this point in the history
order runtime chunks correctly when they depend on each other
  • Loading branch information
sokra committed Oct 14, 2020
2 parents 74a44cd + 4504046 commit c0410e8
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 9 deletions.
48 changes: 39 additions & 9 deletions lib/Compilation.js
Expand Up @@ -2660,17 +2660,44 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
* this is needed as the "hasRuntime()" chunks are dependent on the
* hashes of the non-runtime chunks.
*/
chunks.sort((a, b) => {
const aEntry = a.hasRuntime();
const bEntry = b.hasRuntime();
if (aEntry && !bEntry) return 1;
if (!aEntry && bEntry) return -1;
return byId(a, b);
const runtimeChunks = [];
const otherChunks = [];
for (const c of chunks) {
if (c.hasRuntime()) {
runtimeChunks.push({
chunk: c,
referencedChunks: new Set(
Array.from(c.getAllReferencedAsyncEntrypoints()).map(
e => e.chunks[e.chunks.length - 1]
)
)
});
} else {
otherChunks.push(c);
}
}
otherChunks.sort(byId);
runtimeChunks.sort((a, b) => {
const aDependOnB = a.referencedChunks.has(b.chunk);
const bDependOnA = b.referencedChunks.has(a.chunk);
if (aDependOnB && bDependOnA) {
const err = new WebpackError(
`Circular dependency between chunks with runtime (${
a.chunk.name || a.chunk.id
} and ${b.chunk.name || b.chunk.id}).
This prevents using hashes of each other and should be avoided.`
);
err.chunk = a.chunk;
this.warnings.push(err);
return byId(a.chunk, b.chunk);
}
if (aDependOnB) return 1;
if (bDependOnA) return -1;
return byId(a.chunk, b.chunk);
});
this.logger.timeEnd("hashing: sort chunks");
const fullHashChunks = new Set();
for (let i = 0; i < chunks.length; i++) {
const chunk = chunks[i];
const processChunk = chunk => {
// Last minute module hash generation for modules that depend on chunk hashes
this.logger.time("hashing: hash runtime modules");
for (const module of chunkGraph.getChunkModulesIterable(chunk)) {
Expand Down Expand Up @@ -2722,7 +2749,10 @@ Or do you want to use the entrypoints '${name}' and '${runtime}' independently o
this.errors.push(new ChunkRenderError(chunk, "", err));
}
this.logger.timeAggregate("hashing: hash chunks");
}
};
otherChunks.forEach(processChunk);
for (const { chunk } of runtimeChunks) processChunk(chunk);

this.logger.timeAggregateEnd("hashing: hash runtime modules");
this.logger.timeAggregateEnd("hashing: hash chunks");
this.logger.time("hashing: hash digest");
Expand Down
18 changes: 18 additions & 0 deletions test/configCases/worker/worker-contenthash/index.js
@@ -0,0 +1,18 @@
import { Worker } from "worker_threads";

it("should allow to create a WebWorker", async () => {
const worker = new Worker(new URL("./worker.js", import.meta.url));
worker.postMessage("ok");
const result = await new Promise(resolve => {
worker.on("message", data => {
resolve(data);
});
});
expect(result).toBe("data: OK, thanks");
worker.terminate();
});

it("should allow to share chunks", async () => {
const { upper } = await import("./module");
expect(upper("ok")).toBe("OK");
});
3 changes: 3 additions & 0 deletions test/configCases/worker/worker-contenthash/module.js
@@ -0,0 +1,3 @@
export function upper(str) {
return str.toUpperCase();
}
5 changes: 5 additions & 0 deletions test/configCases/worker/worker-contenthash/test.config.js
@@ -0,0 +1,5 @@
module.exports = {
findBundle: function(i, options) {
return ["main.js"];
}
};
5 changes: 5 additions & 0 deletions test/configCases/worker/worker-contenthash/test.filter.js
@@ -0,0 +1,5 @@
var supportsWorker = require("../../../helpers/supportsWorker");

module.exports = function (config) {
return supportsWorker();
};
11 changes: 11 additions & 0 deletions test/configCases/worker/worker-contenthash/webpack.config.js
@@ -0,0 +1,11 @@
module.exports = {
entry: {
main: {
import: "./index.js",
filename: "[name].js"
}
},
output: {
filename: "[name]-[contenthash].js"
}
};
6 changes: 6 additions & 0 deletions test/configCases/worker/worker-contenthash/worker.js
@@ -0,0 +1,6 @@
import { parentPort } from "worker_threads";

parentPort.on("message", async data => {
const { upper } = await import("./module");
parentPort.postMessage(`data: ${upper(data)}, thanks`);
});

0 comments on commit c0410e8

Please sign in to comment.