Open Interpause opened 2 years ago
Additionally, the current solution using worker-loader
is deprecated in webpack v5. It is now recommended to use Workers directly:
new Worker(new URL('./worker.js', import.meta.url));
I understand the issue with "worker-loader", but it resolves the big problem of file not found after deployment. With worker-loader the actual content is embedded so we no longer worry about various file-not-found issues caused by different reasons.
The problem is not about worker-loader, it's about why Vite runs into the source code of onnxruntime-web. Vite actually run into scan file 'onnxruntime-web/lib/wasm/proxy-wrapper.js'. This is not what I expected; my expectation is the bundler picks up the single file 'dist/ort-web.min.js' directly, skipping the building phrase and ignores anything under folder 'onnxruntime-web/lib'. this should be picked up by the "browser" field.
@Interpause kindly have you found a workaround using Vite to bundle? Many thanks.
I ended up adding onnxruntime-web
via a script tag (which adds it to the global namespace). Then, I used the npm onnxruntime-web
package just for typing. See https://github.com/Interpause/onnx-web-test/commit/5dcb31af219f8bd5b906ce6d56778e5827484892 for what exactly I did. So technically I did not use Vite to bundle it... Also it means dependency on being able to reach the jsdelivr CDN.
Any update as to whether support for vitejs bundling is on the roadmap?
I am using the workaround above but I am getting the following error.
TypeError: cannot resolve operator 'Erf' with opsets: ai.onnx v11
Erf operator seems to be present post v13 and the CDN is only delivering v11.
TypeError: cannot resolve operator 'Erf' with opsets: ai.onnx v11
this is no longer the bundling issue. the error message indicates that operator Erf
v13 is not supported in WebGL backend. Switching to web assembly backend should be able to resolve this issue.
I've written a simple plugin for ViteJS which directly imports dist/ort-web.min.js
as @fs-eire expected. Please have a try @Interpause
vite.config.ts ```typescript import { defineConfig, Plugin } from "vite" import fs from "node:fs/promises" export type OnnxruntimeWebPluginOptions = { /** * @default "onnxruntime-web/dist/ort-web.min.js" */ importSource?: string /** * @default "node_modules/onnxruntime-web/dist" */ ortDistDir?: string } function proxyScript(importSource: string, wasmPaths: string) { return ` import * as ort from "${importSource}"; ort.env.wasm.wasmPaths = import.meta.env.BASE_URL + "${wasmPaths}/"; export default ort; export * from "${importSource}";` } export function onnxruntimeWebPlugin(options?: OnnxruntimeWebPluginOptions): Plugin { const importSource = options?.importSource ?? "onnxruntime-web/dist/ort-web.min.js" const ortDistDir = options?.ortDistDir ?? "node_modules/onnxruntime-web/dist" const ortModuleId = "onnxruntime-web" const virtualModuleId = "\0/vite-plugin-onnxruntime-web/ort" let isDev = false let assetsDir = "assets" return { name: "vite-plugin-onnxruntime-web", enforce: "pre", configResolved(config) { isDev = config.command === "serve" assetsDir = config.build.assetsDir }, resolveId(source) { if (source === ortModuleId) return virtualModuleId }, load(id) { if (id === virtualModuleId) return proxyScript(importSource, isDev ? ortDistDir : assetsDir) }, async generateBundle() { for (const file of await fs.readdir(ortDistDir)) { if (file.endsWith(".wasm")) { this.emitFile({ type: "asset", fileName: `${assetsDir}/${file}`, source: await fs.readFile(`${ortDistDir}/${file}`), }) } } }, } } export default defineConfig({ plugins: [ onnxruntimeWebPlugin(), ] }) ```
Currently, wasm doesn't have an official way to be directly imported as an es module (MDN docs). This causes the hard parts in the plugin. Web workers are built inline in the dist files and are nothing to do with the implementation. I've tested this with vite^4.0.4
and onnxruntime-web^1.13.1
, and it works correctly.
Update: a simpler way without a plugin:
ort.ts
import * as ort from "onnxruntime-web/dist/ort-web.min.js"
import wasm from "onnxruntime-web/dist/ort-wasm.wasm?url"
import wasmThreaded from "onnxruntime-web/dist/ort-wasm-threaded.wasm?url"
import wasmSimd from "onnxruntime-web/dist/ort-wasm-simd.wasm?url"
import wasmSimdThreaded from "onnxruntime-web/dist/ort-wasm-simd-threaded.wasm?url"
import modelUrl from "./model.onnx?url"
ort.env.wasm.wasmPaths = {
"ort-wasm.wasm": wasm,
"ort-wasm-threaded.wasm": wasmThreaded,
"ort-wasm-simd.wasm": wasmSimd,
"ort-wasm-simd-threaded.wasm": wasmSimdThreaded,
}
vite-env.d.ts
/// <reference types="vite/client" />
declare module "onnxruntime-web/dist/*.js" {
export * from "onnxruntime-web"
}
@K024 where do you put the ort.ts
file?
When using Vite to bundle
onnxruntime-web
into my project, I face the following error when attempting to import it.From what I can tell,
worker-loader
seems to be a Webpack-specific method for loading web workers. Would it be possible to fix this? If not, I think Webpack should be added as a peer dependency to make it clearer that specifically Webpack must be used. Thanks.