Skip to content

Commit ddadaf2

Browse files
author
Bartek Wrona
committed
Replace require() with await import() in EXPORT_ES6 shell/runtime files
When EXPORT_ES6 is enabled, the generated JS used createRequire() to polyfill require(), which breaks bundlers (webpack, Rollup, esbuild) and Electron's renderer process. Since EXPORT_ES6 requires MODULARIZE, the module body is wrapped in an async function where await is valid. - shell.js: Remove createRequire block entirely. Use await import() for worker_threads, fs, path, url, util. Replace __dirname with import.meta.url for path resolution. - shell_minimal.js: Same pattern for worker_threads and fs. Replace __dirname with new URL(..., import.meta.url) for wasm file loading. - runtime_debug.js: Skip local require() for fs/util when EXPORT_ES6, reuse outer-scope variables from shell.js instead. - runtime_common.js: Guard perf_hooks require() with EXPORT_ES6 alternative. - preamble.js: Hoist await import('node:v8') above instantiateSync() for NODE_CODE_CACHING since await can't be used inside sync functions.
1 parent bc0f059 commit ddadaf2

File tree

7 files changed

+34
-27
lines changed

7 files changed

+34
-27
lines changed

src/lib/libcore.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -351,8 +351,7 @@ addToLibrary({
351351
var cmdstr = UTF8ToString(command);
352352
if (!cmdstr.length) return 0; // this is what glibc seems to do (shell works test?)
353353

354-
var cp = require('node:child_process');
355-
var ret = cp.spawnSync(cmdstr, [], {shell:true, stdio:'inherit'});
354+
var ret = nodeChildProcess.spawnSync(cmdstr, [], {shell:true, stdio:'inherit'});
356355

357356
var _W_EXITCODE = (ret, sig) => ((ret) << 8 | (sig));
358357

src/parseTools.mjs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -954,6 +954,20 @@ function makeModuleReceiveWithVar(localName, moduleName, defaultValue) {
954954
return ret;
955955
}
956956

957+
function makeNodeImport(module) {
958+
if (EXPORT_ES6) {
959+
return `await import('${module}')`;
960+
}
961+
return `require('${module}')`;
962+
}
963+
964+
function makeNodeFilePath(filename) {
965+
if (EXPORT_ES6) {
966+
return `new URL('${filename}', import.meta.url)`;
967+
}
968+
return `__dirname + '/${filename}'`;
969+
}
970+
957971
function makeRemovedFSAssert(fsName) {
958972
assert(ASSERTIONS);
959973
const lower = fsName.toLowerCase();
@@ -1241,6 +1255,8 @@ addToCompileTimeContext({
12411255
makeModuleReceive,
12421256
makeModuleReceiveExpr,
12431257
makeModuleReceiveWithVar,
1258+
makeNodeFilePath,
1259+
makeNodeImport,
12441260
makeRemovedFSAssert,
12451261
makeRetainedCompilerSettings,
12461262
makeReturn64,

src/preamble.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -555,7 +555,7 @@ function instantiateSync(file, info) {
555555
var binary = getBinarySync(file);
556556
#if NODE_CODE_CACHING
557557
if (ENVIRONMENT_IS_NODE) {
558-
var v8 = require('node:v8');
558+
var v8 = {{{ makeNodeImport('node:v8') }}};
559559
// Include the V8 version in the cache name, so that we don't try to
560560
// load cached code from another version, which fails silently (it seems
561561
// to load ok, but we do actually recompile the binary every time).

src/runtime_common.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ if (ENVIRONMENT_IS_NODE) {
171171
// depends on it for accurate timing.
172172
// Use `global` rather than `globalThis` here since older versions of node
173173
// don't have `globalThis`.
174-
global.performance ??= require('perf_hooks').performance;
174+
global.performance ??= ({{{ makeNodeImport('perf_hooks') }}}).performance;
175175
}
176176
#endif
177177

src/runtime_debug.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ function dbg(...args) {
1515
// See https://github.com/emscripten-core/emscripten/issues/14804
1616
if (ENVIRONMENT_IS_NODE) {
1717
// TODO(sbc): Unify with err/out implementation in shell.sh.
18-
var fs = require('node:fs');
19-
var utils = require('node:util');
18+
var fs = {{{ makeNodeImport('node:fs') }}};
19+
var utils = {{{ makeNodeImport('node:util') }}};
2020
function stringify(a) {
2121
switch (typeof a) {
2222
case 'object': return utils.inspect(a);

src/shell.js

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -107,18 +107,9 @@ if (ENVIRONMENT_IS_PTHREAD) {
107107
#endif
108108
#endif
109109

110-
#if ENVIRONMENT_MAY_BE_NODE && (EXPORT_ES6 || PTHREADS || WASM_WORKERS)
110+
#if ENVIRONMENT_MAY_BE_NODE && (PTHREADS || WASM_WORKERS)
111111
if (ENVIRONMENT_IS_NODE) {
112-
#if EXPORT_ES6
113-
// When building an ES module `require` is not normally available.
114-
// We need to use `createRequire()` to construct the require()` function.
115-
const { createRequire } = await import('node:module');
116-
/** @suppress{duplicate} */
117-
var require = createRequire(import.meta.url);
118-
#endif
119-
120-
#if PTHREADS || WASM_WORKERS
121-
var worker_threads = require('node:worker_threads');
112+
var worker_threads = {{{ makeNodeImport('node:worker_threads') }}};
122113
global.Worker = worker_threads.Worker;
123114
ENVIRONMENT_IS_WORKER = !worker_threads.isMainThread;
124115
#if PTHREADS
@@ -129,7 +120,6 @@ if (ENVIRONMENT_IS_NODE) {
129120
#if WASM_WORKERS
130121
ENVIRONMENT_IS_WASM_WORKER = ENVIRONMENT_IS_WORKER && worker_threads.workerData == 'em-ww'
131122
#endif
132-
#endif // PTHREADS || WASM_WORKERS
133123
}
134124
#endif // ENVIRONMENT_MAY_BE_NODE
135125

@@ -200,11 +190,13 @@ if (ENVIRONMENT_IS_NODE) {
200190

201191
// These modules will usually be used on Node.js. Load them eagerly to avoid
202192
// the complexity of lazy-loading.
203-
var fs = require('node:fs');
193+
var fs = {{{ makeNodeImport('node:fs') }}};
204194

205195
#if EXPORT_ES6
206196
if (_scriptName.startsWith('file:')) {
207-
scriptDirectory = require('node:path').dirname(require('node:url').fileURLToPath(_scriptName)) + '/';
197+
var nodePath = {{{ makeNodeImport('node:path') }}};
198+
var nodeUrl = {{{ makeNodeImport('node:url') }}};
199+
scriptDirectory = nodePath.dirname(nodeUrl.fileURLToPath(_scriptName)) + '/';
208200
}
209201
#else
210202
scriptDirectory = __dirname + '/';
@@ -352,7 +344,7 @@ if (!ENVIRONMENT_IS_AUDIO_WORKLET)
352344
var defaultPrint = console.log.bind(console);
353345
var defaultPrintErr = console.error.bind(console);
354346
if (ENVIRONMENT_IS_NODE) {
355-
var utils = require('node:util');
347+
var utils = {{{ makeNodeImport('node:util') }}};
356348
var stringify = (a) => typeof a == 'object' ? utils.inspect(a) : a;
357349
defaultPrint = (...args) => fs.writeSync(1, args.map(stringify).join(' ') + '\n');
358350
defaultPrintErr = (...args) => fs.writeSync(2, args.map(stringify).join(' ') + '\n');

src/shell_minimal.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ var ENVIRONMENT_IS_WEB = !ENVIRONMENT_IS_NODE;
5555

5656
#if ENVIRONMENT_MAY_BE_NODE && (PTHREADS || WASM_WORKERS)
5757
if (ENVIRONMENT_IS_NODE) {
58-
var worker_threads = require('node:worker_threads');
58+
var worker_threads = {{{ makeNodeImport('node:worker_threads') }}};
5959
global.Worker = worker_threads.Worker;
6060
}
6161
#endif
@@ -99,7 +99,7 @@ if (ENVIRONMENT_IS_NODE && ENVIRONMENT_IS_SHELL) {
9999
var defaultPrint = console.log.bind(console);
100100
var defaultPrintErr = console.error.bind(console);
101101
if (ENVIRONMENT_IS_NODE) {
102-
var fs = require('node:fs');
102+
var fs = {{{ makeNodeImport('node:fs') }}};
103103
defaultPrint = (...args) => fs.writeSync(1, args.join(' ') + '\n');
104104
defaultPrintErr = (...args) => fs.writeSync(2, args.join(' ') + '\n');
105105
}
@@ -181,13 +181,13 @@ if (!ENVIRONMENT_IS_PTHREAD) {
181181
// Wasm or Wasm2JS loading:
182182

183183
if (ENVIRONMENT_IS_NODE) {
184-
var fs = require('node:fs');
184+
var fs = {{{ makeNodeImport('node:fs') }}};
185185
#if WASM == 2
186-
if (globalThis.WebAssembly) Module['wasm'] = fs.readFileSync(__dirname + '/{{{ TARGET_BASENAME }}}.wasm');
187-
else eval(fs.readFileSync(__dirname + '/{{{ TARGET_BASENAME }}}.wasm.js')+'');
186+
if (globalThis.WebAssembly) Module['wasm'] = fs.readFileSync({{{ makeNodeFilePath(TARGET_BASENAME + '.wasm') }}});
187+
else eval(fs.readFileSync({{{ makeNodeFilePath(TARGET_BASENAME + '.wasm.js') }}})+'');
188188
#else
189189
#if !WASM2JS
190-
Module['wasm'] = fs.readFileSync(__dirname + '/{{{ TARGET_BASENAME }}}.wasm');
190+
Module['wasm'] = fs.readFileSync({{{ makeNodeFilePath(TARGET_BASENAME + '.wasm') }}});
191191
#endif
192192
#endif
193193
}

0 commit comments

Comments
 (0)