From 26de35ec4bab1627b3ffad45f8516dae99c76632 Mon Sep 17 00:00:00 2001 From: PendingReality Date: Mon, 1 Dec 2025 17:48:22 +0900 Subject: [PATCH] fix: resolve webpack/Next.js WASM data URL compatibility issue (#95) Add Vite plugin to remove unnecessary `import.meta.url` argument from data: URLs during build. ## Problem wasm-pack generates: `new URL("data:...", import.meta.url)` The `import.meta.url` argument is unnecessary for data: URLs and causes: - Webpack 5: "Invalid generator object" error - Vite: Incorrectly rewrites URL as filesystem path ## Solution Transform during build: - Before: `new URL("data:...", import.meta.url)` - After: `new URL("data:...")` This allows Next.js/webpack users to import spark normally without errors. Fixes #95 --- vite.config.ts | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/vite.config.ts b/vite.config.ts index aae8fce..dd90c0e 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,9 +1,36 @@ import fs from "node:fs"; import path from "node:path"; +import type { Plugin } from "vite"; import { defineConfig } from "vite"; import dts from "vite-plugin-dts"; import glsl from "vite-plugin-glsl"; +/** + * Vite plugin to fix WASM data URL compatibility with webpack/Next.js. + * + * wasm-pack generates code like: new URL("data:...", import.meta.url) + * The import.meta.url argument is unnecessary for data: URLs and causes + * webpack/Vite to incorrectly try to rewrite the URL as a file path. + * + * This plugin transforms: + * new URL("data:...", import.meta.url) → new URL("data:...") + * + * See: https://github.com/sparkjsdev/spark/issues/95 + */ +function fixWasmDataUrl(): Plugin { + return { + name: "fix-wasm-data-url", + renderChunk(code) { + // Match: new URL("data:...", import.meta.url) + // The data URL can contain any characters including quotes (escaped) + const dataUrlPattern = + /new\s+URL\(\s*("data:[^"]*")\s*,\s*import\.meta\.url\s*\)/g; + const result = code.replace(dataUrlPattern, "new URL($1)"); + return result !== code ? result : null; + }, + }; +} + const assetsDirectory = "examples/assets"; const localAssetsDirectoryExist = fs.existsSync(assetsDirectory); if (!localAssetsDirectoryExist) { @@ -32,6 +59,9 @@ export default defineConfig(({ mode }) => { }), dts({ outDir: "dist/types" }), + + // Fix webpack/Next.js compatibility for WASM data URLs + fixWasmDataUrl(), { name: "serve-node-modules-alias", configureServer(server) {