Skip to content

Commit de21f1e

Browse files
author
Bartek Wrona
committed
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 2cfc657 commit de21f1e

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
@@ -15028,6 +15028,43 @@ def test_rollup(self):
1502815028
shutil.copy('hello.wasm', 'dist/')
1502915029
self.assertContained('hello, world!', self.run_js('dist/bundle.mjs'))
1503015030

15031+
@crossplatform
15032+
@requires_dev_dependency('webpack')
15033+
def test_webpack_esm_output_clean(self):
15034+
"""Verify webpack can build EXPORT_ES6 output without errors.
15035+
15036+
When emscripten generates require() in EXPORT_ES6 output (via
15037+
createRequire from 'node:module'), webpack fails with:
15038+
UnhandledSchemeError: Reading from "node:module" is not handled by plugins
15039+
This breaks any webpack/Next.js/Nuxt project using emscripten's ESM output.
15040+
"""
15041+
copytree(test_file('webpack_es6'), '.')
15042+
# Compile with default environment (web+node). On main, this generates
15043+
# 'import { createRequire } from "node:module"' and require() calls for
15044+
# node support, which webpack cannot resolve for web targets.
15045+
self.run_process([EMCC, test_file('hello_world.c'), '-sEXPORT_ES6', '-sEXIT_RUNTIME',
15046+
'-sMODULARIZE', '-o', 'src/hello.mjs'])
15047+
self.run_process(shared.get_npm_cmd('webpack') + ['--mode=development', '--no-devtool'])
15048+
15049+
@crossplatform
15050+
@requires_dev_dependency('vite')
15051+
def test_vite_esm_output_clean(self):
15052+
"""Verify vite bundles EXPORT_ES6 output without require() or externalizing.
15053+
15054+
When emscripten generates require() in EXPORT_ES6 output, vite externalizes
15055+
the node modules for browser compatibility, emitting a warning. The resulting
15056+
bundle contains code that references modules unavailable in browsers.
15057+
"""
15058+
copytree(test_file('vite'), '.')
15059+
# Compile with default environment (web+node). On main, this generates
15060+
# require() calls for node support which vite externalizes but leaves
15061+
# as require() in the bundle output.
15062+
self.run_process([EMCC, test_file('hello_world.c'), '-sEXPORT_ES6', '-sEXIT_RUNTIME',
15063+
'-sMODULARIZE', '-o', 'hello.mjs'])
15064+
# vite.config.js turns externalization warnings into errors, so vite
15065+
# will fail with non-zero exit code if require() appears in ESM output.
15066+
self.run_process(shared.get_npm_cmd('vite') + ['build'])
15067+
1503115068
def test_rlimit(self):
1503215069
self.do_other_test('test_rlimit.c', cflags=['-O1'])
1503315070

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)