Skip to content

Commit 8781522

Browse files
Bartek Wronavogel76
authored andcommitted
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 c624110 commit 8781522

7 files changed

Lines changed: 34 additions & 27 deletions

File tree

src/lib/libcore.js

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

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

386385
var _W_EXITCODE = (ret, sig) => ((ret) << 8 | (sig));
387386

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
@@ -549,7 +549,7 @@ function instantiateSync(file, info) {
549549
var binary = getBinarySync(file);
550550
#if NODE_CODE_CACHING
551551
if (ENVIRONMENT_IS_NODE) {
552-
var v8 = require('node:v8');
552+
var v8 = {{{ makeNodeImport('node:v8') }}};
553553
// Include the V8 version in the cache name, so that we don't try to
554554
// load cached code from another version, which fails silently (it seems
555555
// 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
@@ -144,7 +144,7 @@ if (ENVIRONMENT_IS_NODE) {
144144
// depends on it for accurate timing.
145145
// Use `global` rather than `globalThis` here since older versions of node
146146
// don't have `globalThis`.
147-
global.performance ??= require('perf_hooks').performance;
147+
global.performance ??= ({{{ makeNodeImport('perf_hooks') }}}).performance;
148148
}
149149
#endif
150150

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
@@ -106,18 +106,9 @@ if (ENVIRONMENT_IS_PTHREAD) {
106106
#endif
107107
#endif
108108

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

@@ -199,11 +189,13 @@ if (ENVIRONMENT_IS_NODE) {
199189

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

204194
#if EXPORT_ES6
205195
if (_scriptName.startsWith('file:')) {
206-
scriptDirectory = require('node:path').dirname(require('node:url').fileURLToPath(_scriptName)) + '/';
196+
var nodePath = {{{ makeNodeImport('node:path') }}};
197+
var nodeUrl = {{{ makeNodeImport('node:url') }}};
198+
scriptDirectory = nodePath.dirname(nodeUrl.fileURLToPath(_scriptName)) + '/';
207199
}
208200
#else
209201
scriptDirectory = __dirname + '/';
@@ -351,7 +343,7 @@ if (!ENVIRONMENT_IS_AUDIO_WORKLET)
351343
var defaultPrint = console.log.bind(console);
352344
var defaultPrintErr = console.error.bind(console);
353345
if (ENVIRONMENT_IS_NODE) {
354-
var utils = require('node:util');
346+
var utils = {{{ makeNodeImport('node:util') }}};
355347
var stringify = (a) => typeof a == 'object' ? utils.inspect(a) : a;
356348
defaultPrint = (...args) => fs.writeSync(1, args.map(stringify).join(' ') + '\n');
357349
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)