Skip to content

Commit 6611af0

Browse files
committed
Implement externalized WASM build, fix nodejs#96
1 parent 4cdb01a commit 6611af0

File tree

3 files changed

+65
-61
lines changed

3 files changed

+65
-61
lines changed

build.js

+49-53
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,69 @@
11
const fs = require('fs');
2-
const { buildSync } = require('esbuild');
3-
const path = require('path/posix')
2+
const esbuild = require('esbuild');
43

5-
const { EXTERNAL_PATH } = process.env;
6-
const MINIFY = !EXTERNAL_PATH;
4+
let minify = true;
5+
let cjsBuild = true;
6+
let esmBuild = true;
77

8-
try { fs.mkdirSync('./dist'); }
9-
catch (e) {}
8+
for (const arg of process.argv) {
9+
switch (arg) {
10+
case '--without-cjs': {
11+
cjsBuild = false;
12+
break;
13+
}
14+
case '--without-esm': {
15+
esmBuild = false;
16+
break;
17+
}
18+
case '--no-minify': {
19+
minify = false;
20+
break;
21+
}
22+
default:
23+
continue;
24+
}
25+
}
26+
27+
fs.mkdirSync('./dist', { recursive: true });
1028

1129
const wasmBuffer = fs.readFileSync('./lib/lexer.wasm');
1230
const pjson = JSON.parse(fs.readFileSync('./package.json').toString());
1331

14-
buildSync({
32+
/** @type {esbuild.BuildOptions} */
33+
const buildOptions = {
1534
entryPoints: ['./src/lexer.js'],
16-
outfile: './dist/lexer.mjs',
1735
bundle: true,
18-
minify: MINIFY,
36+
minify,
1937
platform: 'node',
20-
format: 'esm',
2138
banner: {
22-
js: `/* cjs-module-lexer ${pjson.version} */`
39+
js: `/* cjs-module-lexer ${pjson.version} */`,
2340
},
24-
define: EXTERNAL_PATH ? {
25-
WASM_BINARY: 'undefined',
26-
EXTERNAL_PATH: `'${path.join(EXTERNAL_PATH, 'lib/lexer.wasm')}'`,
27-
} : {
41+
outfile: './dist/lexer.mjs',
42+
format: 'esm',
43+
define: {
2844
WASM_BINARY: `'${wasmBuffer.toString('base64')}'`,
29-
EXTERNAL_PATH: 'undefined'
30-
}
31-
})
32-
33-
if (EXTERNAL_PATH) {
34-
buildSync({
35-
stdin: {
36-
contents: `'use strict';
37-
let lazy;
38-
async function init () {
39-
if (!lazy) {
40-
lazy = await import(require('node:url').pathToFileURL(require('node:module').createRequire('${EXTERNAL_PATH}/dist/lexer.js').resolve('./lexer.mjs')));
41-
}
42-
module.exports = lazy;
43-
return lazy.init();
44-
}
45-
46-
function parse (source, name = '@') {
47-
if (!lazy)
48-
throw new Error('Not initialized');
45+
},
46+
};
4947

50-
return lazy.parse(source, name);
48+
if (esmBuild) {
49+
// ESM builds are used when importing from npm.
50+
// Assume lib/lexer.wasm exists.
51+
esbuild.buildSync({
52+
...buildOptions,
53+
define: {
54+
WASM_BINARY: 'undefined',
55+
},
56+
});
5157
}
5258

53-
module.exports = { init, parse };`,
54-
loader: 'js',
55-
},
59+
if (cjsBuild) {
60+
// CJS builds are used for libnode inlined builtins.
61+
esbuild.buildSync({
62+
...buildOptions,
5663
outfile: './dist/lexer.js',
57-
minify: MINIFY,
58-
platform: 'node',
5964
format: 'cjs',
65+
logOverride: {
66+
'empty-import-meta': 'silent'
67+
},
6068
});
61-
} else {
62-
buildSync({
63-
entryPoints: ['./dist/lexer.mjs'],
64-
outfile: './dist/lexer.js',
65-
minify: MINIFY,
66-
platform: 'node',
67-
format: 'cjs',
68-
banner: {
69-
js: `/* cjs-module-lexer ${pjson.version} */`
70-
}
71-
})
7269
}
73-

package.json

+3-2
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@
3030
"mocha": "^9.1.3"
3131
},
3232
"files": [
33-
"dist",
33+
"dist/",
34+
"lib/lexer.wasm",
3435
"lexer.d.ts"
3536
],
3637
"repository": {
@@ -41,4 +42,4 @@
4142
"url": "https://github.com/nodejs/cjs-module-lexer/issues"
4243
},
4344
"homepage": "https://github.com/nodejs/cjs-module-lexer#readme"
44-
}
45+
}

src/lexer.js

+13-6
Original file line numberDiff line numberDiff line change
@@ -90,19 +90,26 @@ function copyLE (src, outBuf16) {
9090
outBuf16[i] = src.charCodeAt(i++);
9191
}
9292

93-
const loadWasm = (typeof EXTERNAL_PATH === "string" && (async () => {
94-
return (await import("node:fs/promises"))
93+
/*
94+
* Load from file when WASM_BINARY isn't inlined.
95+
* A LogicalExpression is used here instead of a ConditionalExpression,
96+
* to ensure esbuild perform dead code elimination correctly.
97+
*/
98+
const loadWasm = (typeof WASM_BINARY === 'undefined' && (async () => {
99+
// we can safely assume import.meta works here with the following workaround.
100+
// https://github.com/nodejs/cjs-module-lexer/blob/bcc6ce4/build.js#L36-L53
101+
return (await import('node:fs/promises'))
95102
.readFile(
96-
(await import("node:url")).fileURLToPath(
97-
import.meta.resolve("../lib/lexer.wasm")
103+
(await import('node:url')).fileURLToPath(
104+
import.meta.resolve('../lib/lexer.wasm')
98105
)
99106
);
100107
})) || (async () => {
101108
const binary = WASM_BINARY
102-
if (typeof window !== "undefined" && typeof atob === "function") {
109+
if (typeof window !== 'undefined' && typeof atob === 'function') {
103110
return Uint8Array.from(atob(binary), (x) => x.charCodeAt(0));
104111
} else {
105-
return Buffer.from(binary, "base64");
112+
return Buffer.from(binary, 'base64');
106113
}
107114
});
108115

0 commit comments

Comments
 (0)