Skip to content

Commit de54b9b

Browse files
Load async Wasm and JSON imports in parallel (#17818)
1 parent 2391ce6 commit de54b9b

17 files changed

Lines changed: 99 additions & 10 deletions

File tree

packages/babel-helper-import-to-platform-api/src/index.ts

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { types as t, template, type File } from "@babel/core";
1+
import { type NodePath, types as t, template, type File } from "@babel/core";
22
import type { Targets } from "@babel/helper-compilation-targets";
33
import { addNamed } from "@babel/helper-module-imports";
44

@@ -268,7 +268,7 @@ export function importToPlatformApi(
268268
};
269269
}
270270

271-
export function buildParallelStaticImports(
271+
function buildParallelStaticImports(
272272
data: { id: t.Identifier; fetch: t.Expression }[],
273273
needsAwait: boolean,
274274
): t.VariableDeclaration | null {
@@ -301,3 +301,44 @@ export function buildParallelStaticImports(
301301

302302
return t.variableDeclaration("const", declarators);
303303
}
304+
305+
const PREV_PARALLEL_IMPORTS = new WeakMap<
306+
t.Program,
307+
{
308+
node: t.Statement;
309+
data: { id: t.Identifier; fetch: t.Expression }[];
310+
needsAwait: boolean;
311+
}
312+
>();
313+
314+
export function injectParallelStaticImports(
315+
programPath: NodePath<t.Program>,
316+
data: { id: t.Identifier; fetch: t.Expression }[],
317+
needsAwait: boolean,
318+
): void {
319+
if (data.length === 0) return;
320+
321+
const program = programPath.node;
322+
const prev = PREV_PARALLEL_IMPORTS.get(program);
323+
let replacementIndex = -1;
324+
325+
if (prev) {
326+
replacementIndex = program.body.indexOf(prev.node);
327+
if (replacementIndex === -1) {
328+
PREV_PARALLEL_IMPORTS.delete(program);
329+
} else {
330+
data = prev.data.concat(data);
331+
needsAwait ||= prev.needsAwait;
332+
}
333+
}
334+
335+
const varDecl = buildParallelStaticImports(data, needsAwait);
336+
337+
PREV_PARALLEL_IMPORTS.set(program, { node: varDecl, data, needsAwait });
338+
339+
if (replacementIndex === -1) {
340+
programPath.unshiftContainer("body", varDecl);
341+
} else {
342+
programPath.get(`body.${replacementIndex}`).replaceWith(varDecl);
343+
}
344+
}

packages/babel-plugin-proposal-import-wasm-source/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@
4141
},
4242
"devDependencies": {
4343
"@babel/core": "workspace:^",
44-
"@babel/helper-plugin-test-runner": "workspace:^"
44+
"@babel/helper-plugin-test-runner": "workspace:^",
45+
"@babel/plugin-transform-json-modules": "workspace:^"
4546
},
4647
"engines": {
4748
"node": "^20.19.0 || >=22.12.0"

packages/babel-plugin-proposal-import-wasm-source/src/index.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import syntaxImportSourcePhase from "@babel/plugin-syntax-import-source";
44

55
import {
66
importToPlatformApi,
7-
buildParallelStaticImports,
7+
injectParallelStaticImports,
88
type Pieces,
99
type Builders,
1010
} from "@babel/helper-import-to-platform-api";
@@ -79,8 +79,7 @@ export default declare(api => {
7979
decl.remove();
8080
}
8181

82-
const decl = buildParallelStaticImports(data, helper.needsAwait);
83-
if (decl) path.unshiftContainer("body", decl);
82+
injectParallelStaticImports(path, data, helper.needsAwait);
8483
},
8584

8685
ImportExpression(path) {
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import source s1 from "./x1.wasm";
2+
import source s2 from "./x2.wasm";
3+
import j1 from "./x1.wasm" with { type: "json" };
4+
import j2 from "./x2.wasm" with { type: "json" };
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"sourceType": "module",
3+
"targets": { "firefox": "110", "node": "20.6" },
4+
"plugins": ["proposal-import-wasm-source", "transform-json-modules"]
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
const [s1, s2, j1, j2] = await Promise.all([typeof process === "object" && process.versions?.node ? import("fs").then(fs => fs.promises.readFile(new URL(import.meta.resolve("./x1.wasm")))).then(WebAssembly.compile) : WebAssembly.compileStreaming(fetch(import.meta.resolve("./x1.wasm"))), typeof process === "object" && process.versions?.node ? import("fs").then(fs => fs.promises.readFile(new URL(import.meta.resolve("./x2.wasm")))).then(WebAssembly.compile) : WebAssembly.compileStreaming(fetch(import.meta.resolve("./x2.wasm"))), typeof process === "object" && process.versions?.node ? import("fs").then(fs => fs.promises.readFile(new URL(import.meta.resolve("./x1.wasm")))).then(JSON.parse) : fetch(import.meta.resolve("./x1.wasm")).then(r => r.json()), typeof process === "object" && process.versions?.node ? import("fs").then(fs => fs.promises.readFile(new URL(import.meta.resolve("./x2.wasm")))).then(JSON.parse) : fetch(import.meta.resolve("./x2.wasm")).then(r => r.json())]);
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import source s1 from "./x1.wasm";
2+
import source s2 from "./x2.wasm";
3+
import j1 from "./x1.wasm" with { type: "json" };
4+
import j2 from "./x2.wasm" with { type: "json" };
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"sourceType": "module",
3+
"targets": { "firefox": "110" },
4+
"plugins": ["proposal-import-wasm-source", "transform-json-modules"]
5+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
const [s1, s2, j1, j2] = await Promise.all([WebAssembly.compileStreaming(fetch(import.meta.resolve("./x1.wasm"))), WebAssembly.compileStreaming(fetch(import.meta.resolve("./x2.wasm"))), fetch(import.meta.resolve("./x1.wasm")).then(r => r.json()), fetch(import.meta.resolve("./x2.wasm")).then(r => r.json())]);
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import source s1 from "./x1.wasm";
2+
import source s2 from "./x2.wasm";
3+
import j1 from "./x1.wasm" with { type: "json" };
4+
import j2 from "./x2.wasm" with { type: "json" };

0 commit comments

Comments
 (0)