diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 3a7f3ffd14f..cc5d238942c 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -6,6 +6,7 @@
* [Test](#test)
* [Coverage](#coverage)
* [Update `WPTs`](#update-wpts)
+ * [Building for external shared node builtins](#external-builds)
* [Developer's Certificate of Origin 1.1](#developers-certificate-of-origin)
* [Moderation Policy](#moderation-policy)
@@ -165,6 +166,15 @@ npm run test
npm run coverage
```
+
+### Building for externally shared node builtins
+
+If you are packaging undici for a distro, this might help if you would like use
+a unbundled version instead of bundling one in `libnode.so`.
+
+To enable this, pass `EXTERNAL_PATH=/path/to/global/node_modules/undici` to build/wasm.js.
+You shall also pass this path to `--shared-builtin-undici/undici-path` in Node.js's configure.py.
+
## Developer's Certificate of Origin 1.1
diff --git a/build/wasm.js b/build/wasm.js
index 2b63f3c7ab1..1104cfec0b0 100644
--- a/build/wasm.js
+++ b/build/wasm.js
@@ -2,7 +2,7 @@
const { execSync } = require('child_process')
const { writeFileSync, readFileSync } = require('fs')
-const { join, resolve } = require('path')
+const { join, resolve, basename } = require('path')
const ROOT = resolve(__dirname, '../')
const WASM_SRC = resolve(__dirname, '../deps/llhttp')
@@ -15,6 +15,8 @@ let WASM_CFLAGS = process.env.WASM_CFLAGS || '--sysroot=/usr/share/wasi-sysroot
let WASM_LDFLAGS = process.env.WASM_LDFLAGS || ''
const WASM_LDLIBS = process.env.WASM_LDLIBS || ''
+const EXTERNAL_PATH = process.env.EXTERNAL_PATH
+
// These are relevant for undici and should not be overridden
WASM_CFLAGS += ' -Ofast -fno-exceptions -fvisibility=hidden -mexec-model=reactor'
WASM_LDFLAGS += ' -Wl,-error-limit=0 -Wl,-O3 -Wl,--lto-O3 -Wl,--strip-all'
@@ -60,6 +62,23 @@ if (hasApk) {
writeFileSync(join(WASM_OUT, 'wasm_build_env.txt'), buildInfo)
}
+const writeWasmChunk = EXTERNAL_PATH
+ ? (path, dest) => {
+ const base64 = readFileSync(join(WASM_OUT, path)).toString('base64')
+ writeFileSync(join(WASM_OUT, dest), `
+const { Buffer } = require('node:buffer')
+
+module.exports = Buffer.from('${base64}', 'base64')
+`)
+ }
+ : (path, dest) => {
+ writeFileSync(join(WASM_OUT, dest), `
+const { fs } = require('node:fs')
+
+module.exports = fs.readFileSync(require.resolve('./${basename(path)}'))
+`)
+ }
+
// Build wasm binary
execSync(`${WASM_CC} ${WASM_CFLAGS} ${WASM_LDFLAGS} \
${join(WASM_SRC, 'src')}/*.c \
@@ -67,11 +86,7 @@ execSync(`${WASM_CC} ${WASM_CFLAGS} ${WASM_LDFLAGS} \
-o ${join(WASM_OUT, 'llhttp.wasm')} \
${WASM_LDLIBS}`, { stdio: 'inherit' })
-const base64Wasm = readFileSync(join(WASM_OUT, 'llhttp.wasm')).toString('base64')
-writeFileSync(
- join(WASM_OUT, 'llhttp-wasm.js'),
- `module.exports = '${base64Wasm}'\n`
-)
+writeWasmChunk('llhttp.wasm', 'llhttp-wasm.js')
// Build wasm simd binary
execSync(`${WASM_CC} ${WASM_CFLAGS} -msimd128 ${WASM_LDFLAGS} \
@@ -80,8 +95,12 @@ execSync(`${WASM_CC} ${WASM_CFLAGS} -msimd128 ${WASM_LDFLAGS} \
-o ${join(WASM_OUT, 'llhttp_simd.wasm')} \
${WASM_LDLIBS}`, { stdio: 'inherit' })
-const base64WasmSimd = readFileSync(join(WASM_OUT, 'llhttp_simd.wasm')).toString('base64')
-writeFileSync(
- join(WASM_OUT, 'llhttp_simd-wasm.js'),
- `module.exports = '${base64WasmSimd}'\n`
-)
+writeWasmChunk('llhttp_simd.wasm', 'llhttp_simd-wasm.js')
+
+if (EXTERNAL_PATH) {
+ writeFileSync(join(ROOT, 'loader.js'), `
+'use strict'
+
+module.exports = require('node:module').createRequire('${EXTERNAL_PATH}/loader.js')('./index-fetch.js')
+`)
+}
diff --git a/lib/client.js b/lib/client.js
index b9077d4dd6a..a46a1504b54 100644
--- a/lib/client.js
+++ b/lib/client.js
@@ -479,7 +479,7 @@ async function lazyllhttp () {
let mod
try {
- mod = await WebAssembly.compile(Buffer.from(require('./llhttp/llhttp_simd-wasm.js'), 'base64'))
+ mod = await WebAssembly.compile(require('./llhttp/llhttp_simd-wasm.js'))
} catch (e) {
/* istanbul ignore next */
@@ -487,7 +487,7 @@ async function lazyllhttp () {
// being enabled, but the occurring of this other error
// * https://github.com/emscripten-core/emscripten/issues/11495
// got me to remove that check to avoid breaking Node 12.
- mod = await WebAssembly.compile(Buffer.from(llhttpWasmData || require('./llhttp/llhttp-wasm.js'), 'base64'))
+ mod = await WebAssembly.compile(llhttpWasmData || require('./llhttp/llhttp-wasm.js'))
}
return await WebAssembly.instantiate(mod, {
diff --git a/package.json b/package.json
index 5200f436a9b..ea5ae16a576 100644
--- a/package.json
+++ b/package.json
@@ -65,6 +65,7 @@
"*.d.ts",
"index.js",
"index-fetch.js",
+ "loader.js",
"lib",
"types",
"docs"