/
index.ts
67 lines (60 loc) · 2.2 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import type { Plugin, ResolvedConfig } from "vite";
import { parseWasm } from "./parse-wasm";
import * as wasmHelper from "./wasm-helper";
export default function wasm(): Plugin {
let resolvedConfig: ResolvedConfig;
let originalWasmPlugin: Plugin;
let resolvePlugin: Plugin;
return {
name: "vite-plugin-wasm",
enforce: "pre",
configResolved(config) {
resolvedConfig = config;
originalWasmPlugin = resolvedConfig.plugins.find(plugin => plugin.name === "vite:wasm-helper");
resolvePlugin = resolvedConfig.plugins.find(plugin => plugin.name === "vite:resolve");
},
resolveId(id) {
if (id === wasmHelper.id) {
return id;
}
},
async load(id) {
if (id === wasmHelper.id) {
return `export default ${wasmHelper.code}`;
}
if (!id.toLowerCase().endsWith(".wasm")) {
return;
}
const { imports, exports } = await parseWasm(id);
// Make a call to Vite's internal `fileToUrl` function by calling Vite's original WASM plugin's load()
const originalLoadResult = (await originalWasmPlugin.load.call(this, id + "?init")) as string;
const url = JSON.parse(/".+"/g.exec(originalLoadResult.trim().split("\n")[1])[0]) as string;
const importUrls = await Promise.all(
imports.map(async ({ from }) => {
const importerPath = id.slice(0, id.lastIndexOf("/")) + from.slice(from.lastIndexOf("/"));
return resolvePlugin.resolveId.call(this, importerPath, null, null);
})
);
return `
import __vite__initWasm from "${wasmHelper.id}"
${imports
.map(
({ names }, i) =>
`import { ${names.map((name, j) => `${name} as __vite__wasmImport_${i}_${j}`).join(", ")} } from ${JSON.stringify(
importUrls[i]
)};`
)
.join("\n")}
const __vite__wasmModule = await __vite__initWasm({ ${imports
.map(
({ from, names }, i) =>
`${JSON.stringify(from)}: { ${names.map((name, j) => `${name}: __vite__wasmImport_${i}_${j}`).join(", ")} }`
)
.join(", ")} }, ${JSON.stringify(url)});
${exports
.map(name => `export ${name === "default" ? "default" : `const ${name} =`} __vite__wasmModule.${name};`)
.join("\n")}
`;
}
};
}