如何在Vite构建的Svelte项目中引入npm发布的WASM模块?
Vite 自带的 .wasm 自动处理逻辑,默认仅对项目源码目录(通常是src/)下开发者直接引入的 wasm 文件生效,不会主动处理 node_modules 依赖包内部引用的 wasm 资源。
你用 wasm-pack --target web 构建出来的包,内部是通过固定相对路径读取同目录下的 compiler_bg.wasm 文件,Vite 在做依赖预构建时,既不会改写这段引用路径适配自己的静态资源规则,也不会把依赖里的 wasm 文件纳入资源处理管线,预构建阶段在 Node 环境下运行依赖代码时,识别不了 .wasm 后缀就会抛出你看到的错误。
方案1:调整 wasm-pack 构建目标(推荐,零业务代码侵入)
发布 npm 包时不要用 --target web 参数,换成专门给打包工具设计的 bundler 目标重新构建:
wasm-pack build --target bundler
这个目标产出的 JS 胶水代码,对 wasm 文件的引用方式完全符合 Vite、Webpack 这类工具的静态分析规则,Vite 可以自动识别处理,构建完成后重新发布 npm 包,业务侧原有引入代码不需要任何修改就能正常运行。
方案2:不重构建 wasm 包,调整 Vite 配置适配
如果不方便重新发布 wasm 包,可以直接在项目的 Vite 配置里加规则,跳过对该包的预构建,同时强制让 Vite 处理依赖内的 wasm 文件:
// vite.config.ts import { defineConfig } from 'vite' import { svelte } from '@sveltejs/vite-plugin-svelte' export default defineConfig({ plugins: [svelte()], optimizeDeps: { // 将wasm包排除出依赖预构建,避免Node环境直接执行胶水代码 exclude: ['@ocr-compiler/compiler'] }, // 强制将wasm文件纳入静态资源处理范围 assetsInclude: ['**/*.wasm'] })
如果加完配置还是报路径错误,可以在业务代码里手动引入 wasm 文件的访问地址,传入 init 方法覆盖默认的路径查找逻辑:
<script lang="ts"> import init, { greet } from "@ocr-compiler/compiler"; // 手动引入wasm文件的生产环境可用URL import wasmUrl from "@ocr-compiler/compiler/compiler_bg.wasm?url"; init(wasmUrl).then(() => { greet("Hello"); }); </script>
额外注意事项
如果你用的是 SvelteKit 而非纯 Vite + Svelte 模板,记得把 wasm 初始化逻辑放到客户端侧执行,不要在 SSR 服务端阶段运行,可以用 SvelteKit 内置的browser判断或者放在onMount生命周期里执行,避免服务端环境报文件系统访问错误。
内容的提问来源于stack exchange,提问作者Dr Bracewell

