Skip to content

Commit 8b2fb1c

Browse files
Bartek Wronavogel76
authored andcommitted
Add bundler integration tests verifying EXPORT_ES6 output has no require()
Add two tests that verify EXPORT_ES6 output is valid ESM and works with bundlers: - test_webpack_esm_output_clean: Compiles with EXPORT_ES6 and default environment (web+node), then builds with webpack. On main, webpack hard-fails because it cannot resolve 'node:module' (used by emscripten's createRequire polyfill). This breaks any webpack/Next.js/Nuxt project. - test_vite_esm_output_clean: Compiles with EXPORT_ES6 and default environment, then builds with vite. On main, vite externalizes 'node:module' for browser compatibility, emitting a warning. The resulting bundle contains code referencing unavailable node modules. These tests are expected to fail on main and pass after eliminating require() from EXPORT_ES6 output.
1 parent 88d7ed2 commit 8b2fb1c

File tree

2 files changed

+49
-0
lines changed

2 files changed

+49
-0
lines changed

test/test_other.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14991,6 +14991,43 @@ def test_rollup(self):
1499114991
shutil.copy('hello.wasm', 'dist/')
1499214992
self.assertContained('Hello, world!', self.run_js('dist/bundle.mjs'))
1499314993

14994+
@crossplatform
14995+
@requires_dev_dependency('webpack')
14996+
def test_webpack_esm_output_clean(self):
14997+
"""Verify webpack can build EXPORT_ES6 output without errors.
14998+
14999+
When emscripten generates require() in EXPORT_ES6 output (via
15000+
createRequire from 'node:module'), webpack fails with:
15001+
UnhandledSchemeError: Reading from "node:module" is not handled by plugins
15002+
This breaks any webpack/Next.js/Nuxt project using emscripten's ESM output.
15003+
"""
15004+
copytree(test_file('webpack_es6'), '.')
15005+
# Compile with default environment (web+node). On main, this generates
15006+
# 'import { createRequire } from "node:module"' and require() calls for
15007+
# node support, which webpack cannot resolve for web targets.
15008+
self.run_process([EMCC, test_file('hello_world.c'), '-sEXPORT_ES6', '-sEXIT_RUNTIME',
15009+
'-sMODULARIZE', '-o', 'src/hello.mjs'])
15010+
self.run_process(shared.get_npm_cmd('webpack') + ['--mode=development', '--no-devtool'])
15011+
15012+
@crossplatform
15013+
@requires_dev_dependency('vite')
15014+
def test_vite_esm_output_clean(self):
15015+
"""Verify vite bundles EXPORT_ES6 output without require() or externalizing.
15016+
15017+
When emscripten generates require() in EXPORT_ES6 output, vite externalizes
15018+
the node modules for browser compatibility, emitting a warning. The resulting
15019+
bundle contains code that references modules unavailable in browsers.
15020+
"""
15021+
copytree(test_file('vite'), '.')
15022+
# Compile with default environment (web+node). On main, this generates
15023+
# require() calls for node support which vite externalizes but leaves
15024+
# as require() in the bundle output.
15025+
self.run_process([EMCC, test_file('hello_world.c'), '-sEXPORT_ES6', '-sEXIT_RUNTIME',
15026+
'-sMODULARIZE', '-o', 'hello.mjs'])
15027+
# vite.config.js turns externalization warnings into errors, so vite
15028+
# will fail with non-zero exit code if require() appears in ESM output.
15029+
self.run_process(shared.get_npm_cmd('vite') + ['build'])
15030+
1499415031
def test_rlimit(self):
1499515032
self.do_other_test('test_rlimit.c', cflags=['-O1'])
1499615033

test/vite/vite.config.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
11
export default {
22
base: './',
3+
build: {
4+
rollupOptions: {
5+
onwarn(warning, defaultHandler) {
6+
// Treat externalized-for-browser-compatibility warnings as errors.
7+
// This catches require() in ESM output that vite silently externalizes.
8+
if (warning.message && warning.message.includes('externalized for browser compatibility')) {
9+
throw new Error(warning.message);
10+
}
11+
defaultHandler(warning);
12+
},
13+
},
14+
},
315
}

0 commit comments

Comments
 (0)