Skip to content

Commit a5847c9

Browse files
authored
Improve detection & usage of deno/bun (#1333)
* Improve detection & usage of deno/bun * Ignore deno.lock file * Fix webpack config * Support cloudflare worker in conditional exports cloudflare/workers-sdk#84 cloudflare/workers-sdk#93 * Fix webpack config * Remove cloudflare conditional exports * Remove publicPath in webpack config * Update webpack.config.js * Finalize PR
1 parent 4362237 commit a5847c9

File tree

8 files changed

+60
-30
lines changed

8 files changed

+60
-30
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ __pycache__
33
node_modules
44
.cache
55
.DS_STORE
6+
deno.lock
67

78
# Do not track build artifacts/generated files
89
/dist

package.json

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -82,13 +82,6 @@
8282
"README.md",
8383
"LICENSE"
8484
],
85-
"browser": {
86-
"fs": false,
87-
"path": false,
88-
"url": false,
89-
"sharp": false,
90-
"onnxruntime-node": false
91-
},
9285
"publishConfig": {
9386
"access": "public"
9487
},

src/env.js

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@
2222
* @module env
2323
*/
2424

25-
import fs from 'fs';
26-
import path from 'path';
27-
import url from 'url';
25+
import fs from 'node:fs';
26+
import path from 'node:path';
27+
import url from 'node:url';
2828

2929
const VERSION = '3.5.2';
3030

@@ -40,6 +40,10 @@ const IS_NODE_ENV = IS_PROCESS_AVAILABLE && process?.release?.name === 'node';
4040
const IS_FS_AVAILABLE = !isEmpty(fs);
4141
const IS_PATH_AVAILABLE = !isEmpty(path);
4242

43+
// Runtime detection
44+
const IS_DENO_RUNTIME = typeof globalThis.Deno !== 'undefined';
45+
const IS_BUN_RUNTIME = typeof globalThis.Bun !== 'undefined';
46+
4347
/**
4448
* A read-only object containing information about the APIs available in the current environment.
4549
*/
@@ -62,7 +66,7 @@ export const apis = Object.freeze({
6266
/** Whether the Node.js process API is available */
6367
IS_PROCESS_AVAILABLE,
6468

65-
/** Whether we are running in a Node.js environment */
69+
/** Whether we are running in a Node.js-like environment (node, deno, bun) */
6670
IS_NODE_ENV,
6771

6872
/** Whether the filesystem API is available */
@@ -143,7 +147,7 @@ export const env = {
143147
useFS: IS_FS_AVAILABLE,
144148

145149
/////////////////// Cache settings ///////////////////
146-
useBrowserCache: IS_WEB_CACHE_AVAILABLE,
150+
useBrowserCache: IS_WEB_CACHE_AVAILABLE && !IS_DENO_RUNTIME,
147151

148152
useFSCache: IS_FS_AVAILABLE,
149153
cacheDir: DEFAULT_CACHE_DIR,

src/utils/audio.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,8 @@ import {
1515
calculateReflectOffset, saveBlob,
1616
} from './core.js';
1717
import { apis } from '../env.js';
18-
import fs from 'fs';
1918
import { Tensor, matmul } from './tensor.js';
20-
19+
import fs from 'node:fs';
2120

2221
/**
2322
* Helper function to read audio from a path/URL.

src/utils/hub.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
* @module utils/hub
66
*/
77

8-
import fs from 'fs';
9-
import path from 'path';
8+
import fs from 'node:fs';
9+
import path from 'node:path';
1010

1111
import { apis, env } from '../env.js';
1212
import { dispatchCallback } from './core.js';

tests/test_utils.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import fs from "fs";
2-
import path from "path";
3-
import { fileURLToPath } from "url";
1+
import fs from "node:fs";
2+
import path from "node:path";
3+
import { fileURLToPath } from "node:url";
44

55
export async function loadAudio(url) {
66
// NOTE: Since the Web Audio API is not available in Node.js, we will need to use the `wavefile` library to obtain the raw audio data.

tests/utils/hub.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { AutoModel, PreTrainedModel } from "../../src/models.js";
22

33
import { MAX_TEST_EXECUTION_TIME, DEFAULT_MODEL_OPTIONS } from "../init.js";
4-
import fs from "fs";
4+
import fs from "node:fs";
55

66
// TODO: Set cache folder to a temp directory
77

webpack.config.js

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,35 @@
1+
import { fileURLToPath } from "node:url";
2+
import path from "node:path";
3+
import fs from "node:fs";
4+
import webpack from "webpack";
15
import TerserPlugin from "terser-webpack-plugin";
2-
import { fileURLToPath } from "url";
3-
import path from "path";
4-
import fs from "fs";
56

67
const __dirname = path.dirname(fileURLToPath(import.meta.url));
78

9+
/**
10+
* Plugin to strip the "node:" prefix from module requests.
11+
*
12+
* This is necessary to ensure both web and node builds work correctly,
13+
* otherwise we would get an error like:
14+
* ```
15+
* Module build failed: UnhandledSchemeError: Reading from "node:path" is not handled by plugins (Unhandled scheme).
16+
* Webpack supports "data:" and "file:" URIs by default.
17+
* You may need an additional plugin to handle "node:" URIs.
18+
* ```
19+
*
20+
* NOTE: We then do not need to use the `node:` prefix in the resolve.alias configuration.
21+
*/
22+
class StripNodePrefixPlugin extends webpack.NormalModuleReplacementPlugin {
23+
constructor() {
24+
super(
25+
/^node:(.+)$/,
26+
resource => {
27+
resource.request = resource.request.replace(/^node:/, '');
28+
}
29+
);
30+
}
31+
}
32+
833
/**
934
* Plugin to post-process build files. Required to solve certain issues with ESM module output.
1035
* See https://github.com/webpack/webpack/issues/17121 for more information.
@@ -55,7 +80,6 @@ function buildConfig({
5580
plugins = [],
5681
} = {}) {
5782
const outputModule = type === "module";
58-
5983
const alias = Object.fromEntries(
6084
ignoreModules.map((module) => [module, false]),
6185
);
@@ -137,13 +161,15 @@ const NODE_EXTERNAL_MODULES = [
137161
"onnxruntime-common",
138162
"onnxruntime-node",
139163
"sharp",
140-
"fs",
141-
"path",
142-
"url",
164+
"node:fs",
165+
"node:path",
166+
"node:url",
143167
];
144168

145-
// Do not bundle onnxruntime-node when packaging for the web.
146-
const WEB_IGNORE_MODULES = ["onnxruntime-node"];
169+
// Do not bundle node-only packages when bundling for the web.
170+
// NOTE: We can exclude the "node:" prefix for built-in modules here,
171+
// since we apply the `StripNodePrefixPlugin` to strip it.
172+
const WEB_IGNORE_MODULES = ["onnxruntime-node", "sharp", "fs", "path", "url"];
147173

148174
// Do not bundle the following modules with webpack (mark as external)
149175
const WEB_EXTERNAL_MODULES = [
@@ -157,12 +183,19 @@ const WEB_BUILD = buildConfig({
157183
type: "module",
158184
ignoreModules: WEB_IGNORE_MODULES,
159185
externalModules: WEB_EXTERNAL_MODULES,
186+
plugins: [
187+
new StripNodePrefixPlugin()
188+
]
160189
});
161190

162191
// Web-only build, bundled with onnxruntime-web
163192
const BUNDLE_BUILD = buildConfig({
164193
type: "module",
165-
plugins: [new PostBuildPlugin()],
194+
ignoreModules: WEB_IGNORE_MODULES,
195+
plugins: [
196+
new StripNodePrefixPlugin(),
197+
new PostBuildPlugin(),
198+
],
166199
});
167200

168201
// Node-compatible builds

0 commit comments

Comments
 (0)