Skip to content

Commit 08e5fd8

Browse files
authored
Wasm/JS uses ES modules [1], and the require function is not guaranteed to be present there. (#481)
It worked previously, but recent changes in K/Wasm (that'll land in 2.3.20) triggered the following error: > Cannot determine intended module format because both require() and top-level await are present. > If the code is intended to be CommonJS, wrap await in an async function. > If the code is intended to be an ES module, replace require() with import. This change provides a workaround for the issue. [1] https://kotlinlang.org/docs/wasm-js-interop.html#kotlin-wasm-and-kotlin-js-interoperability-differences
1 parent dc2b7c5 commit 08e5fd8

File tree

1 file changed

+28
-16
lines changed

1 file changed

+28
-16
lines changed

core/wasmJs/src/node/nodeModulesWasmJs.kt

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,36 @@
55

66
package kotlinx.io.node
77

8-
9-
internal fun requireExists(): Boolean = js("typeof require === 'function'")
10-
11-
internal fun requireModule(mod: String): JsAny? = js("""{
12-
try {
13-
let m = require(mod);
14-
if (m) return m;
15-
return null;
16-
} catch (e) {
17-
return null;
18-
}
19-
}""")
8+
@JsFun("""
9+
(globalThis.module = (typeof process !== 'undefined') && (process.release.name === 'node') ?
10+
await import('node:module') : void 0, () => {})
11+
""")
12+
internal external fun persistModule()
13+
14+
@JsFun("""() => {
15+
const importMeta = import.meta;
16+
return globalThis.module.default.createRequire(importMeta.url);
17+
}
18+
""")
19+
internal external fun getRequire(): JsAny
20+
21+
private val require = persistModule().let { getRequire() }
22+
23+
@JsFun("""
24+
(require, mod) => {
25+
try {
26+
let m = require(mod);
27+
if (m) return m;
28+
return null;
29+
} catch (e) {
30+
return null;
31+
}
32+
}
33+
""")
34+
internal external fun requireModule(require: JsAny, mod: String): JsAny?
2035

2136
internal fun loadModule(name: String): JsAny {
22-
if (!requireExists()) {
23-
throw UnsupportedOperationException("Module $name could not be loaded")
24-
}
25-
val mod = requireModule(name) ?: throw UnsupportedOperationException("Module '$name' could not be imported")
37+
val mod = requireModule(require, name) ?: throw UnsupportedOperationException("Module '$name' could not be imported")
2638
return mod
2739
}
2840

0 commit comments

Comments
 (0)