From d65feac8ffbd3c60261060d43e93d2e20521567d Mon Sep 17 00:00:00 2001 From: sigoden Date: Wed, 7 Sep 2022 15:47:45 +0800 Subject: [PATCH 1/4] fix: wasm functions return undefined --- src/index.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/index.ts b/src/index.ts index 3882aa9..d53ad74 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,6 +6,7 @@ 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", @@ -13,6 +14,7 @@ export default function wasm(): Plugin { 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) { @@ -33,14 +35,20 @@ export default function wasm(): Plugin { // 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( - ({ from, names }, i) => + ({ names }, i) => `import { ${names.map((name, j) => `${name} as __vite__wasmImport_${i}_${j}`).join(", ")} } from ${JSON.stringify( - from + importUrls[i] )};` ) .join("\n")} From 457ca22af04a9067364f855a55cfd41e9f211a44 Mon Sep 17 00:00:00 2001 From: sigoden Date: Wed, 7 Sep 2022 20:23:58 +0800 Subject: [PATCH 2/4] make it works with pre-bundling --- src/index.ts | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/src/index.ts b/src/index.ts index d53ad74..85f01c2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,7 +6,7 @@ import * as wasmHelper from "./wasm-helper"; export default function wasm(): Plugin { let resolvedConfig: ResolvedConfig; let originalWasmPlugin: Plugin; - let resolvePlugin: Plugin; + let moduleIds: string[] = []; return { name: "vite-plugin-wasm", @@ -14,7 +14,6 @@ export default function wasm(): Plugin { 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) { @@ -22,6 +21,7 @@ export default function wasm(): Plugin { } }, async load(id) { + moduleIds.push(id); if (id === wasmHelper.id) { return `export default ${wasmHelper.code}`; } @@ -35,12 +35,7 @@ export default function wasm(): Plugin { // 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); - }) - ); + const importUrls = await Promise.all(imports.map(async ({ from }) => getImportUrl(id, from, moduleIds))); return ` import __vite__initWasm from "${wasmHelper.id}" @@ -65,3 +60,29 @@ ${exports } }; } + +async function getImportUrl(id: string, from: string, moduleIds: string[]) { + const importerPath = id.slice(0, id.lastIndexOf("/")) + from.slice(from.lastIndexOf("/")); + if (importerPath.indexOf("node_modules") === -1) { + // Local js won't have versionHash, so the importerPath is importerId + return importerPath; + } + // The module may be pre-bundled, pre-bundling js file has higher priority than original file. + const preBundlingPath = getPreBundlePath(importerPath); + return ( + moduleIds.find(v => v.startsWith(preBundlingPath)) || + moduleIds.find(v => v.startsWith(importerPath)) || + importerPath + ); +} + +function getPreBundlePath(importerPath: string) { + const [prefix, modulePath] = importerPath.split("node_modules/"); + const modulePathParts = modulePath.split("/"); + let pkgName = modulePathParts[0]; + if (pkgName.startsWith("@")) { + // Scope Package + pkgName = `${modulePathParts[0]}_${modulePathParts[1]}`; + } + return `${prefix}node_modules/.vite/deps/${pkgName}.js`; +} From 6414363ae46ea791d943fd89a122d7f44f666d34 Mon Sep 17 00:00:00 2001 From: Menci Date: Wed, 21 Sep 2022 22:03:54 +0800 Subject: [PATCH 3/4] Update src/index.ts --- src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index 85f01c2..ad2d0ec 100644 --- a/src/index.ts +++ b/src/index.ts @@ -62,7 +62,7 @@ ${exports } async function getImportUrl(id: string, from: string, moduleIds: string[]) { - const importerPath = id.slice(0, id.lastIndexOf("/")) + from.slice(from.lastIndexOf("/")); + const importerPath = path.resolve(id, "../" + from); if (importerPath.indexOf("node_modules") === -1) { // Local js won't have versionHash, so the importerPath is importerId return importerPath; From ad062bcb2e7498f1b833559d0f3e1fffaa4464a0 Mon Sep 17 00:00:00 2001 From: Menci Date: Wed, 21 Sep 2022 22:18:13 +0800 Subject: [PATCH 4/4] Add missing import path --- src/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/index.ts b/src/index.ts index ad2d0ec..218762d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,5 @@ import type { Plugin, ResolvedConfig } from "vite"; +import path from "path"; import { parseWasm } from "./parse-wasm"; import * as wasmHelper from "./wasm-helper";