Skip to content

Commit

Permalink
Implement externalized WASM build, fix nodejs#96
Browse files Browse the repository at this point in the history
  • Loading branch information
mochaaP committed May 7, 2024
1 parent 4cdb01a commit c2eb548
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 61 deletions.
102 changes: 49 additions & 53 deletions build.js
Original file line number Diff line number Diff line change
@@ -1,73 +1,69 @@
const fs = require('fs');
const { buildSync } = require('esbuild');
const path = require('path/posix')
const esbuild = require('esbuild');

const { EXTERNAL_PATH } = process.env;
const MINIFY = !EXTERNAL_PATH;
let minify = true;
let cjsBuild = true;
let esmBuild = true;

try { fs.mkdirSync('./dist'); }
catch (e) {}
for (const arg of process.argv) {
switch (arg) {
case '--without-cjs': {
cjsBuild = false;
break;
}
case '--without-esm': {
esmBuild = false;
break;
}
case '--no-minify': {
minify = false;
break;
}
default:
continue;
}
}

fs.mkdirSync('./dist', { recursive: true });

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

buildSync({
/** @type {esbuild.BuildOptions} */
const buildOptions = {
entryPoints: ['./src/lexer.js'],
outfile: './dist/lexer.mjs',
bundle: true,
minify: MINIFY,
minify,
platform: 'node',
format: 'esm',
banner: {
js: `/* cjs-module-lexer ${pjson.version} */`
js: `/* cjs-module-lexer ${pjson.version} */`,
},
define: EXTERNAL_PATH ? {
WASM_BINARY: 'undefined',
EXTERNAL_PATH: `'${path.join(EXTERNAL_PATH, 'lib/lexer.wasm')}'`,
} : {
outfile: './dist/lexer.mjs',
format: 'esm',
define: {
WASM_BINARY: `'${wasmBuffer.toString('base64')}'`,
EXTERNAL_PATH: 'undefined'
}
})

if (EXTERNAL_PATH) {
buildSync({
stdin: {
contents: `'use strict';
let lazy;
async function init () {
if (!lazy) {
lazy = await import(require('node:url').pathToFileURL(require('node:module').createRequire('${EXTERNAL_PATH}/dist/lexer.js').resolve('./lexer.mjs')));
}
module.exports = lazy;
return lazy.init();
}
function parse (source, name = '@') {
if (!lazy)
throw new Error('Not initialized');
},
};

return lazy.parse(source, name);
if (esmBuild) {
// ESM builds are used when importing from npm.
// Assume lib/lexer.wasm exists.
esbuild.buildSync({
...buildOptions,
define: {
WASM_BINARY: 'undefined',
},
});
}

module.exports = { init, parse };`,
loader: 'js',
},
if (cjsBuild) {
// CJS builds are used for libnode inlined builtins.
esbuild.buildSync({
...buildOptions,
outfile: './dist/lexer.js',
minify: MINIFY,
platform: 'node',
format: 'cjs',
logOverride: {
'empty-import-meta': 'silent'
},
});
} else {
buildSync({
entryPoints: ['./dist/lexer.mjs'],
outfile: './dist/lexer.js',
minify: MINIFY,
platform: 'node',
format: 'cjs',
banner: {
js: `/* cjs-module-lexer ${pjson.version} */`
}
})
}

5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@
"mocha": "^9.1.3"
},
"files": [
"dist",
"dist/lexer.mjs",
"lib/lexer.wasm",
"lexer.d.ts"
],
"repository": {
Expand All @@ -41,4 +42,4 @@
"url": "https://github.com/nodejs/cjs-module-lexer/issues"
},
"homepage": "https://github.com/nodejs/cjs-module-lexer#readme"
}
}
19 changes: 13 additions & 6 deletions src/lexer.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,19 +90,26 @@ function copyLE (src, outBuf16) {
outBuf16[i] = src.charCodeAt(i++);
}

const loadWasm = (typeof EXTERNAL_PATH === "string" && (async () => {
return (await import("node:fs/promises"))
/*
* Load from file when WASM_BINARY isn't inlined.
* A LogicalExpression is used here instead of a ConditionalExpression,
* to ensure esbuild perform dead code elimination correctly.
*/
const loadWasm = (typeof WASM_BINARY === 'undefined' && (async () => {
// we can safely assume import.meta works here with the following workaround.
// https://github.com/nodejs/cjs-module-lexer/blob/bcc6ce4/build.js#L36-L53
return (await import('node:fs/promises'))
.readFile(
(await import("node:url")).fileURLToPath(
import.meta.resolve("../lib/lexer.wasm")
(await import('node:url')).fileURLToPath(
import.meta.resolve('../lib/lexer.wasm')
)
);
})) || (async () => {
const binary = WASM_BINARY
if (typeof window !== "undefined" && typeof atob === "function") {
if (typeof window !== 'undefined' && typeof atob === 'function') {
return Uint8Array.from(atob(binary), (x) => x.charCodeAt(0));
} else {
return Buffer.from(binary, "base64");
return Buffer.from(binary, 'base64');
}
});

Expand Down

0 comments on commit c2eb548

Please sign in to comment.