Files
oxc/napi/parser/scripts/build-browser-bundle.js
Boshen f585cb42cd feat(napi): add threadless WASI builds (#26898)
## Summary

- add threadless `wasm32-wasip1` builds and generated loaders for parser, minify, transform, transform-react, and transform-relay
- use the threadless bindings for browser and Cloudflare Workers while preserving threaded WASI and WebContainer fallbacks
- build and publish the new target in CI and release workflows

Closes #25271

## Testing

- native NAPI builds and package tests: 1,091 passed
- parser Chromium browser tests passed
- local workerd smoke tests passed for all five packages
- deployed Workers using local package tarballs passed for all five packages and reported `wasm32-wasip1`
- packed main-package file lists match the published `0.150.0` packages
- `just fmt`, `just check`, `just lint`, `just doc`, `just ast`, targeted Oxlint, typos, and `git diff --check` passed
- `just ready` reaches three unrelated Oxlint ANSI-color snapshot mismatches in this non-interactive environment; no pending snapshots remain

## AI assistance

Codex was used to help implement and test this change. The contributor remains responsible for reviewing and understanding the changes before merge.
2026-09-23 06:54:41 +00:00

71 lines
2.0 KiB
JavaScript

import fs from "node:fs";
import path from "node:path";
import { parseArgs } from "node:util";
import { rolldown } from "rolldown";
// Rollup-compatible bundlers reserve `\0`-prefixed IDs for plugin virtual modules,
// so Rolldown will not try to resolve these generated `?url` asset modules as files.
const NEW_URL_ASSET_PREFIX = "\0new-url-asset:";
const WASIP1_BROWSER_BINDING = path.resolve("./src-js/parser.wasip1-browser.js");
async function main() {
const args = parseArgs({
strict: true,
options: {
npmDir: {
type: "string",
},
},
});
// bundle wasm.js -> browser-bundle.js
const bundle = await rolldown({
input: "./src-js/wasm.js",
platform: "browser",
resolve: {
alias: {
"@oxc-parser/binding-wasm32-wasip1": WASIP1_BROWSER_BINDING,
},
},
plugins: [
{
name: "patch-new-url",
resolveId(source) {
if (source.endsWith("?url")) {
return `${NEW_URL_ASSET_PREFIX}${source.replace(/\?url$/, "")}`;
}
},
load(id) {
if (id.startsWith(NEW_URL_ASSET_PREFIX)) {
const assetPath = id.slice(NEW_URL_ASSET_PREFIX.length);
return `export default new URL(${JSON.stringify(assetPath)}, import.meta.url).href`;
}
},
},
],
});
try {
await bundle.write({
file: "browser-bundle.js",
format: "esm",
});
} finally {
await bundle.close();
}
if (args.values.npmDir) {
const pkgDir = path.resolve(args.values.npmDir, "wasm32-wasip1");
// add `browser-bundle.js` to `package.json:files`
const pkgFile = path.join(pkgDir, "package.json");
const pkg = JSON.parse(fs.readFileSync(pkgFile, "utf8"));
pkg.files.push("browser-bundle.js");
fs.writeFileSync(pkgFile, JSON.stringify(pkg, null, 2));
// copy `browser-bundle.js` to `<npmDir>/wasm32-wasip1`
fs.cpSync("browser-bundle.js", path.join(pkgDir, "browser-bundle.js"));
}
}
await main();