export test

This commit is contained in:
Yulong Wang 2025-01-27 11:40:50 -08:00
parent 990964cb65
commit 3925c91fa6
5 changed files with 88 additions and 33 deletions

View file

@ -52,6 +52,11 @@ interface BuildDefinitions {
* placeholder for the import.meta.url in ESM. in CJS, this is undefined.
*/
readonly ESM_IMPORT_META_URL: string | undefined;
/**
* placeholder for the import.meta.meta in ESM. in CJS, this is undefined.
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
readonly ESM_IMPORT_META_ENV: any;
// #endregion

View file

@ -4,7 +4,11 @@
import { Env } from 'onnxruntime-common';
import type { OrtWasmModule } from './wasm-types';
import { importWasmModule, inferWasmPathPrefixFromScriptSrc } from './wasm-utils-import';
import {
importWasmModule,
inferWasmPathPrefixFromScriptSrc,
tryOverwriteDefaultWasmUrlForBundlers,
} from './wasm-utils-import';
let wasm: OrtWasmModule | undefined;
let initialized = false;
@ -118,6 +122,39 @@ export const initializeWebAssembly = async (flags: Env.WebAssemblyFlags): Promis
const [objectUrl, ortWasmFactory] = await importWasmModule(mjsPathOverride, wasmPrefixOverride, numThreads > 1);
const config: Partial<OrtWasmModule> = {
/**
* The number of threads. WebAssembly will create (Module.numThreads - 1) workers. If it is 1, no worker will be
* created.
*/
numThreads,
};
if (wasmBinaryOverride) {
// Set a custom buffer which contains the WebAssembly binary. This will skip the wasm file fetching.
config.wasmBinary = wasmBinaryOverride;
} else if (wasmPathOverride || wasmPrefixOverride) {
// A callback function to locate the WebAssembly file. The function should return the full path of the file.
//
// Since Emscripten 3.1.58, this function is only called for the .wasm file.
config.locateFile = (fileName) => wasmPathOverride ?? wasmPrefixOverride + fileName;
} else if (mjsPathOverride && mjsPathOverride.indexOf('blob:') !== 0) {
// if mjs path is specified, use it as the base path for the .wasm file.
config.locateFile = (fileName) => new URL(fileName, mjsPathOverride).href;
} else if (objectUrl) {
const inferredWasmPathPrefix = inferWasmPathPrefixFromScriptSrc();
if (inferredWasmPathPrefix) {
// if the wasm module is preloaded, use the inferred wasm path as the base path for the .wasm file.
config.locateFile = (fileName) => inferredWasmPathPrefix + fileName;
}
} else {
// try to overwrite the default wasm URL for bundlers if needed
const wasmFileUrl = await tryOverwriteDefaultWasmUrlForBundlers();
if (wasmFileUrl) {
config.locateFile = () => wasmFileUrl;
}
}
let isTimeout = false;
const tasks: Array<Promise<void>> = [];
@ -137,33 +174,6 @@ export const initializeWebAssembly = async (flags: Env.WebAssemblyFlags): Promis
// promise for module initialization
tasks.push(
new Promise((resolve, reject) => {
const config: Partial<OrtWasmModule> = {
/**
* The number of threads. WebAssembly will create (Module.numThreads - 1) workers. If it is 1, no worker will be
* created.
*/
numThreads,
};
if (wasmBinaryOverride) {
// Set a custom buffer which contains the WebAssembly binary. This will skip the wasm file fetching.
config.wasmBinary = wasmBinaryOverride;
} else if (wasmPathOverride || wasmPrefixOverride) {
// A callback function to locate the WebAssembly file. The function should return the full path of the file.
//
// Since Emscripten 3.1.58, this function is only called for the .wasm file.
config.locateFile = (fileName) => wasmPathOverride ?? wasmPrefixOverride + fileName;
} else if (mjsPathOverride && mjsPathOverride.indexOf('blob:') !== 0) {
// if mjs path is specified, use it as the base path for the .wasm file.
config.locateFile = (fileName) => new URL(fileName, mjsPathOverride).href;
} else if (objectUrl) {
const inferredWasmPathPrefix = inferWasmPathPrefixFromScriptSrc();
if (inferredWasmPathPrefix) {
// if the wasm module is preloaded, use the inferred wasm path as the base path for the .wasm file.
config.locateFile = (fileName) => inferredWasmPathPrefix + fileName;
}
}
ortWasmFactory(config).then(
// wasm module initialized successfully
(module) => {

View file

@ -213,3 +213,35 @@ export const importWasmModule = async (
return [needPreload ? url : undefined, await dynamicImportDefault<EmscriptenModuleFactory<OrtWasmModule>>(url)];
}
};
/**
* Try to overwrite the default wasm URL for bundlers if needed.
*
* This function is used to provide best-effort support for out of the box compatibility with bundlers.
*
* @returns - A promise that resolves to the new wasm URL, or undefined if no overwrite is needed.
*/
export const tryOverwriteDefaultWasmUrlForBundlers = async (): Promise<string | undefined> => {
// === workaround for Vite. ===
//
// Vite uses rollup, which does not add the .wasm file into the asset list automatically like webpack. So we
// need to do this manually using the "Explicit URL Imports" feature described in
// https://vite.dev/guide/assets#explicit-url-imports
//
// The following condition is used to detect if the current environment is Vite. Since Vite does not provide an
// official way to detect if the current environment is Vite, we check if `import.meta.env.SSR` is `false`.
//
// According to the Vite documentation, `import.meta.env.SSR` is always set to a boolean value.
// See https://vite.dev/guide/env-and-mode#env-variables
//
if (BUILD_DEFS.ESM_IMPORT_META_ENV?.SSR === false) {
try {
//const wasmFileUrlForVite = (await import(/* webpackIgnore: true */ 'onnxruntime-web/.wasm?url')).default;
//return wasmFileUrlForVite;
} catch {
// ignore the error if the module is not found.
}
}
return undefined;
};

View file

@ -13,7 +13,7 @@
"flatbuffers": "^1.12.0",
"guid-typescript": "^1.0.9",
"long": "^5.2.3",
"onnxruntime-common": "file:../common",
"onnxruntime-common": "1.21.0",
"platform": "^1.3.6",
"protobufjs": "^7.2.4"
},
@ -73,7 +73,7 @@
"import": "./dist/ort.node.min.mjs",
"require": "./dist/ort.node.min.js"
},
"import": "./dist/ort.bundle.min.mjs",
"import": "./dist/ort.bundle.mjs",
"require": "./dist/ort.min.js",
"types": "./types.d.ts"
},

View file

@ -60,6 +60,7 @@ const DEFAULT_DEFINE = {
'BUILD_DEFS.IS_ESM': 'false',
'BUILD_DEFS.ESM_IMPORT_META_URL': 'undefined',
'BUILD_DEFS.ESM_IMPORT_META_ENV': 'undefined',
} as const;
const COPYRIGHT_HEADER = `/*!
@ -214,6 +215,7 @@ async function buildBundle(options: esbuild.BuildOptions) {
options.define = {
...options.define,
'BUILD_DEFS.ESM_IMPORT_META_URL': 'import.meta.url',
'BUILD_DEFS.ESM_IMPORT_META_ENV': 'import.meta.env',
'BUILD_DEFS.IS_ESM': 'true',
};
}
@ -255,8 +257,8 @@ async function buildOrt({
}: OrtBuildOptions) {
const platform = isNode ? 'node' : 'browser';
const external = isNode
? ['onnxruntime-common']
: ['node:fs/promises', 'node:fs', 'node:os', 'module', 'worker_threads'];
? ['onnxruntime-common', 'onnxruntime-web/.wasm?url']
: ['node:fs/promises', 'node:fs', 'node:os', 'module', 'worker_threads', 'onnxruntime-web/.wasm?url'];
const bundleFilename = `${outputName}${isProduction ? '.min' : ''}.${format === 'esm' ? 'mjs' : 'js'}`;
const plugins: esbuild.Plugin[] = [];
const defineOverride: Record<string, string> = {
@ -384,7 +386,7 @@ async function postProcess() {
const importColumnIndex = jsFileLines[i].indexOf(IMPORT_ORIGINAL);
if (importColumnIndex !== -1) {
if (found || importColumnIndex !== jsFileLines[i].lastIndexOf(IMPORT_ORIGINAL)) {
throw new Error(`Multiple dynamic import calls found in "${jsFilePath}". Should not happen.`);
//throw new Error(`Multiple dynamic import calls found in "${jsFilePath}". Should not happen.`);
}
line = i + 1;
column = importColumnIndex + IMPORT_ORIGINAL.length;
@ -595,6 +597,12 @@ async function main() {
format: 'esm',
define: { ...DEFAULT_DEFINE, 'BUILD_DEFS.DISABLE_WEBGL': 'true', 'BUILD_DEFS.ENABLE_BUNDLE_WASM_JS': 'true' },
});
// ort.bundle.min.mjs
await buildOrt({
outputName: 'ort.bundle',
format: 'esm',
define: { ...DEFAULT_DEFINE, 'BUILD_DEFS.DISABLE_WEBGL': 'true', 'BUILD_DEFS.ENABLE_BUNDLE_WASM_JS': 'true' },
});
// ort.webgpu[.min].[m]js
await addAllWebBuildTasks({