fix(javascript): retain distinct chunk registration callback metadata (#2737)
Co-authored-by: LouisChen <3361008+chqcjq@users.noreply.github.com>
This commit is contained in:
1 parent
52d4ce6ced
commit
0cf224e762
3 files changed
+147
No files matched your search
@@ -0,0 +1,78 @@
|
||||
import { expect, it } from "vitest";
|
||||
import { analyzeJavaScriptStaticSource } from "./javascriptStaticAnalysis.js";
|
||||
|
||||
const registration = (runtime: string, callback: string, chunk = 1) =>
|
||||
"(globalThis." +
|
||||
runtime +
|
||||
" = globalThis." +
|
||||
runtime +
|
||||
" || []).push([[" +
|
||||
chunk +
|
||||
"], {a: function() {}}, " +
|
||||
callback +
|
||||
"]);";
|
||||
|
||||
it.each(["webpackChunkFixture", "rspackChunkFixture"])(
|
||||
"keeps differing callback facts for %s independent of source order",
|
||||
(runtime) => {
|
||||
const first = registration(
|
||||
runtime,
|
||||
'function(r) { r(7); r.e("chunk-a"); }',
|
||||
);
|
||||
const second = registration(
|
||||
runtime,
|
||||
'function(r) { r(8); r.e("chunk-b"); }',
|
||||
);
|
||||
for (const source of [first + "\n" + second, second + "\n" + first]) {
|
||||
const result = analyzeJavaScriptStaticSource(source);
|
||||
expect(result.parse_status).toBe("complete");
|
||||
expect(result.bundler_registrations).toHaveLength(2);
|
||||
expect(
|
||||
result.bundler_registrations.flatMap((r) => r.entry_module_keys).sort(),
|
||||
).toEqual(["7", "8"]);
|
||||
expect(
|
||||
result.bundler_registrations.flatMap((r) => r.async_chunk_keys).sort(),
|
||||
).toEqual(["chunk-a", "chunk-b"]);
|
||||
}
|
||||
expect(
|
||||
analyzeJavaScriptStaticSource(first + "\n" + first).bundler_registrations,
|
||||
).toHaveLength(1);
|
||||
expect(
|
||||
analyzeJavaScriptStaticSource(first).bundler_registrations[0],
|
||||
).toMatchObject({
|
||||
entry_module_keys: ["7"],
|
||||
async_chunk_keys: ["chunk-a"],
|
||||
});
|
||||
expect(
|
||||
analyzeJavaScriptStaticSource(second).bundler_registrations[0],
|
||||
).toMatchObject({
|
||||
entry_module_keys: ["8"],
|
||||
async_chunk_keys: ["chunk-b"],
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
it.each([
|
||||
["function(r) { r(7); }", "function(r) { r(8); }"],
|
||||
['function(r) { r.e("a"); }', 'function(r) { r.e("b"); }'],
|
||||
["function(r) {}", "function(s) {}"],
|
||||
["function(r) {}", "function(r) { r(dynamic); }"],
|
||||
["function(r) {}", "function(r) { r.e(dynamic); }"],
|
||||
])("retains callback metadata differences: %s / %s", (left, right) => {
|
||||
const result = analyzeJavaScriptStaticSource(
|
||||
registration("webpackChunkFixture", left) +
|
||||
"\n" +
|
||||
registration("webpackChunkFixture", right),
|
||||
);
|
||||
expect(result.bundler_registrations).toHaveLength(2);
|
||||
});
|
||||
|
||||
it("retains distinct chunk identities with identical callbacks", () => {
|
||||
const callback = "function(r) { r(7); }";
|
||||
const result = analyzeJavaScriptStaticSource(
|
||||
registration("webpackChunkFixture", callback, 1) +
|
||||
"\n" +
|
||||
registration("webpackChunkFixture", callback, 2),
|
||||
);
|
||||
expect(result.bundler_registrations).toHaveLength(2);
|
||||
});
|
||||
@@ -691,6 +691,14 @@ export const registrationKey = (
|
||||
registration.runtime,
|
||||
registration.chunk_keys,
|
||||
String(registration.unknown_chunk_keys),
|
||||
// Equal factory tables can be registered with different runtime callbacks.
|
||||
// Both early collection and finalization must retain those recovered facts.
|
||||
registration.runtime_require_name,
|
||||
registration.runtime_module_cache_status,
|
||||
registration.entry_module_keys,
|
||||
String(registration.unknown_entry_module_keys),
|
||||
registration.async_chunk_keys,
|
||||
String(registration.unknown_async_chunk_keys),
|
||||
registration.modules.map(({ module_key: key, source_sha256: digest }) => [
|
||||
key,
|
||||
digest,
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
import { writeFile } from "node:fs/promises";
|
||||
import { join } from "node:path";
|
||||
import { expect } from "vitest";
|
||||
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
|
||||
import { cliTest } from "../../support/cli/cliFixture.js";
|
||||
import { analyzeJavaScriptDirectory } from "../../support/cli/javascriptApplication.js";
|
||||
|
||||
cliTest.for(["CLI", "stdio MCP"] as const)(
|
||||
"retains both repeated chunk callback observations through %s",
|
||||
async (surface, { cli }) => {
|
||||
const root = await createTestTempDirectory("rea-bundler-callbacks-");
|
||||
const source = [
|
||||
'(globalThis.webpackChunkFixture = globalThis.webpackChunkFixture || []).push([[1], {a: function() {}}, function(r) { r(7); r.e("chunk-a"); }]);',
|
||||
'(globalThis.webpackChunkFixture = globalThis.webpackChunkFixture || []).push([[1], {a: function() {}}, function(r) { r(8); r.e("chunk-b"); }]);',
|
||||
].join("\n");
|
||||
await writeFile(join(root, "bundle.js"), source);
|
||||
const { graph } = await analyzeJavaScriptDirectory(surface, cli, root);
|
||||
const chunk = graph.nodes.find(({ kind }) => kind === "javascript-chunk");
|
||||
for (const [index, entry, asyncChunk] of [
|
||||
[0, "7", "chunk-a"],
|
||||
[1, "8", "chunk-b"],
|
||||
] as const) {
|
||||
expect(chunk?.observations).toContainEqual(
|
||||
expect.objectContaining({
|
||||
properties: expect.objectContaining({
|
||||
entry_module_keys: [entry],
|
||||
async_chunk_keys: [asyncChunk],
|
||||
}),
|
||||
evidence: expect.objectContaining({
|
||||
location: expect.objectContaining({
|
||||
value: expect.objectContaining({
|
||||
source: "bundle.js",
|
||||
start: { line: index + 1, column: 0 },
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
);
|
||||
expect(graph.edges).toContainEqual(
|
||||
expect.objectContaining({
|
||||
source_node_id: chunk?.node_id,
|
||||
properties: expect.objectContaining({
|
||||
kind: "bundler-entry-module",
|
||||
module_key: entry,
|
||||
resolution_status: "not-found",
|
||||
}),
|
||||
}),
|
||||
);
|
||||
expect(graph.edges).toContainEqual(
|
||||
expect.objectContaining({
|
||||
source_node_id: chunk?.node_id,
|
||||
properties: expect.objectContaining({
|
||||
kind: "bundler-async-chunk",
|
||||
chunk_key: asyncChunk,
|
||||
resolution_status: "not-found",
|
||||
}),
|
||||
}),
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
Reference in new issue
Block a user