Skip to content

Commit 69c26b9

Browse files
authored
Support building for externally shared js builtins (nodejs#2643)
1 parent d3ad54e commit 69c26b9

File tree

6 files changed

+49
-15
lines changed

6 files changed

+49
-15
lines changed

CONTRIBUTING.md

+10
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
* [Test](#test)
77
* [Coverage](#coverage)
88
* [Update `WPTs`](#update-wpts)
9+
* [Building for externally shared node builtins](#external-builds)
910
* [Developer's Certificate of Origin 1.1](#developers-certificate-of-origin)
1011
* [Moderation Policy](#moderation-policy)
1112

@@ -165,6 +166,15 @@ npm run test
165166
npm run coverage
166167
```
167168

169+
<a id="external-builds"></a>
170+
### Building for externally shared node builtins
171+
172+
If you are packaging `undici` for a distro, this might help if you would like to use
173+
an unbundled version instead of bundling one in `libnode.so`.
174+
175+
To enable this, pass `EXTERNAL_PATH=/path/to/global/node_modules/undici` to `build/wasm.js`.
176+
You shall also pass this path to `--shared-builtin-undici/undici-path` in Node.js's `configure.py`.
177+
168178
<a id="developers-certificate-of-origin"></a>
169179
## Developer's Certificate of Origin 1.1
170180

build/wasm.js

+30-11
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
const { execSync } = require('child_process')
44
const { writeFileSync, readFileSync } = require('fs')
5-
const { join, resolve } = require('path')
5+
const { join, resolve, basename } = require('path')
66

77
const ROOT = resolve(__dirname, '../')
88
const WASM_SRC = resolve(__dirname, '../deps/llhttp')
@@ -15,6 +15,8 @@ let WASM_CFLAGS = process.env.WASM_CFLAGS || '--sysroot=/usr/share/wasi-sysroot
1515
let WASM_LDFLAGS = process.env.WASM_LDFLAGS || ''
1616
const WASM_LDLIBS = process.env.WASM_LDLIBS || ''
1717

18+
const EXTERNAL_PATH = process.env.EXTERNAL_PATH
19+
1820
// These are relevant for undici and should not be overridden
1921
WASM_CFLAGS += ' -Ofast -fno-exceptions -fvisibility=hidden -mexec-model=reactor'
2022
WASM_LDFLAGS += ' -Wl,-error-limit=0 -Wl,-O3 -Wl,--lto-O3 -Wl,--strip-all'
@@ -60,18 +62,31 @@ if (hasApk) {
6062
writeFileSync(join(WASM_OUT, 'wasm_build_env.txt'), buildInfo)
6163
}
6264

65+
const writeWasmChunk = EXTERNAL_PATH
66+
? (path, dest) => {
67+
const base64 = readFileSync(join(WASM_OUT, path)).toString('base64')
68+
writeFileSync(join(WASM_OUT, dest), `
69+
const { Buffer } = require('node:buffer')
70+
71+
module.exports = Buffer.from('${base64}', 'base64')
72+
`)
73+
}
74+
: (path, dest) => {
75+
writeFileSync(join(WASM_OUT, dest), `
76+
const { fs } = require('node:fs')
77+
78+
module.exports = fs.readFileSync(require.resolve('./${basename(path)}'))
79+
`)
80+
}
81+
6382
// Build wasm binary
6483
execSync(`${WASM_CC} ${WASM_CFLAGS} ${WASM_LDFLAGS} \
6584
${join(WASM_SRC, 'src')}/*.c \
6685
-I${join(WASM_SRC, 'include')} \
6786
-o ${join(WASM_OUT, 'llhttp.wasm')} \
6887
${WASM_LDLIBS}`, { stdio: 'inherit' })
6988

70-
const base64Wasm = readFileSync(join(WASM_OUT, 'llhttp.wasm')).toString('base64')
71-
writeFileSync(
72-
join(WASM_OUT, 'llhttp-wasm.js'),
73-
`module.exports = '${base64Wasm}'\n`
74-
)
89+
writeWasmChunk('llhttp.wasm', 'llhttp-wasm.js')
7590

7691
// Build wasm simd binary
7792
execSync(`${WASM_CC} ${WASM_CFLAGS} -msimd128 ${WASM_LDFLAGS} \
@@ -80,8 +95,12 @@ execSync(`${WASM_CC} ${WASM_CFLAGS} -msimd128 ${WASM_LDFLAGS} \
8095
-o ${join(WASM_OUT, 'llhttp_simd.wasm')} \
8196
${WASM_LDLIBS}`, { stdio: 'inherit' })
8297

83-
const base64WasmSimd = readFileSync(join(WASM_OUT, 'llhttp_simd.wasm')).toString('base64')
84-
writeFileSync(
85-
join(WASM_OUT, 'llhttp_simd-wasm.js'),
86-
`module.exports = '${base64WasmSimd}'\n`
87-
)
98+
writeWasmChunk('llhttp_simd.wasm', 'llhttp_simd-wasm.js')
99+
100+
if (EXTERNAL_PATH) {
101+
writeFileSync(join(ROOT, 'loader.js'), `
102+
'use strict'
103+
104+
module.exports = require('node:module').createRequire('${EXTERNAL_PATH}/loader.js')('./index-fetch.js')
105+
`)
106+
}

lib/client.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -479,15 +479,15 @@ async function lazyllhttp () {
479479

480480
let mod
481481
try {
482-
mod = await WebAssembly.compile(Buffer.from(require('./llhttp/llhttp_simd-wasm.js'), 'base64'))
482+
mod = await WebAssembly.compile(require('./llhttp/llhttp_simd-wasm.js'))
483483
} catch (e) {
484484
/* istanbul ignore next */
485485

486486
// We could check if the error was caused by the simd option not
487487
// being enabled, but the occurring of this other error
488488
// * https://github.com/emscripten-core/emscripten/issues/11495
489489
// got me to remove that check to avoid breaking Node 12.
490-
mod = await WebAssembly.compile(Buffer.from(llhttpWasmData || require('./llhttp/llhttp-wasm.js'), 'base64'))
490+
mod = await WebAssembly.compile(llhttpWasmData || require('./llhttp/llhttp-wasm.js'))
491491
}
492492

493493
return await WebAssembly.instantiate(mod, {

lib/llhttp/llhttp-wasm.js

+3-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/llhttp/llhttp_simd-wasm.js

+3-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
"*.d.ts",
6666
"index.js",
6767
"index-fetch.js",
68+
"loader.js",
6869
"lib",
6970
"types",
7071
"docs"

0 commit comments

Comments
 (0)