Skip to content

Commit f585cb4

Browse files
committed
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.
1 parent 01ff33e commit f585cb4

54 files changed

Lines changed: 20979 additions & 18 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.github/workflows/ci.yml‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,8 +183,10 @@ jobs:
183183
- name: Build
184184
if: steps.filter.outputs.changed == 'true'
185185
run: |
186+
rustup target add wasm32-wasip1
186187
rustup target add wasm32-wasip1-threads
187188
pnpm run build-wasm-dev
189+
pnpm run build-wasip1-dev
188190
git diff --exit-code # Must commit everything
189191
- name: Test wasi in browser
190192
if: steps.filter.outputs.changed == 'true'
@@ -194,6 +196,7 @@ jobs:
194196
pnpm exec playwright install chromium
195197
pnpm run build-wasi
196198
pnpm run build-wasm-dev
199+
pnpm run build-wasip1-dev
197200
pnpm run build-npm-dir
198201
pnpm run test-browser
199202
pnpm build-browser-bundle --npmDir npm-dir

‎.github/workflows/reusable_release_napi.yml‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,10 @@ jobs:
8080
target: wasm32-wasip1-threads
8181
build: pnpm build-wasm
8282

83+
- os: ubuntu-latest
84+
target: wasm32-wasip1
85+
build: pnpm build-wasip1
86+
8387
- os: ubuntu-latest
8488
target: s390x-unknown-linux-gnu
8589
build: |

‎napi/minify/browser.js‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export * from '@oxc-minify/binding-wasm32-wasi'
1+
export * from '@oxc-minify/binding-wasm32-wasip1'

‎napi/minify/index.js‎

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -565,7 +565,7 @@ function createLoadErrorChain(errors) {
565565
//
566566
// NAPI_RS_WASI_FLAVOR selects one exact generated flavor and implies strict
567567
// WASI loading. It never crosses into another flavor or falls back to native.
568-
const __napiWasiFlavors = ['wasm32-wasi']
568+
const __napiWasiFlavors = ['wasm32-wasi', 'wasm32-wasip1']
569569
const __napiWasiFlavor = process.env.NAPI_RS_WASI_FLAVOR
570570
const __napiWasiFlavorRequested =
571571
typeof __napiWasiFlavor === 'string' && __napiWasiFlavor.length > 0
@@ -655,6 +655,27 @@ if (!nativeBinding || forceWasi) {
655655
loadErrors.push(candidateError)
656656
}
657657
}
658+
if (!wasiBindingLoaded && (!__napiWasiFlavorRequested || __napiWasiFlavor === 'wasm32-wasip1')) {
659+
let candidateError = null
660+
let candidateFailed = false
661+
try {
662+
candidateError = __napiWasiResolveCandidate('./minify.wasip1.cjs', false, ['./minify.wasm32-wasip1.debug.wasm', './minify.wasm32-wasip1.wasm'])
663+
candidateFailed = candidateError !== null
664+
if (!candidateFailed) {
665+
wasiBinding = require('./minify.wasip1.cjs')
666+
nativeBinding = wasiBinding
667+
__napiLoadedBindingTarget = 'wasm32-wasip1'
668+
wasiBindingLoaded = true
669+
}
670+
} catch (err) {
671+
candidateError = err
672+
candidateFailed = true
673+
}
674+
if (candidateFailed) {
675+
wasiBindingErrors.push(candidateError)
676+
loadErrors.push(candidateError)
677+
}
678+
}
658679
if (!wasiBindingLoaded && (!__napiWasiFlavorRequested || __napiWasiFlavor === 'wasm32-wasi')) {
659680
let candidateError = null
660681
let candidateFailed = false
@@ -682,6 +703,33 @@ if (!nativeBinding || forceWasi) {
682703
loadErrors.push(candidateError)
683704
}
684705
}
706+
if (!wasiBindingLoaded && (!__napiWasiFlavorRequested || __napiWasiFlavor === 'wasm32-wasip1')) {
707+
let candidateError = null
708+
let candidateFailed = false
709+
try {
710+
candidateError = __napiWasiResolveCandidate('@oxc-minify/binding-wasm32-wasip1', true, undefined)
711+
candidateFailed = candidateError !== null
712+
if (!candidateFailed) {
713+
if (process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') {
714+
const bindingPackageVersion = require('@oxc-minify/binding-wasm32-wasip1/package.json').version
715+
if (bindingPackageVersion !== '0.151.0') {
716+
throw new Error(`WASI binding package version mismatch, expected 0.151.0 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`)
717+
}
718+
}
719+
wasiBinding = require('@oxc-minify/binding-wasm32-wasip1')
720+
nativeBinding = wasiBinding
721+
__napiLoadedBindingTarget = 'wasm32-wasip1'
722+
wasiBindingLoaded = true
723+
}
724+
} catch (err) {
725+
candidateError = err
726+
candidateFailed = true
727+
}
728+
if (candidateFailed) {
729+
wasiBindingErrors.push(candidateError)
730+
loadErrors.push(candidateError)
731+
}
732+
}
685733
if (
686734
!wasiBindingLoaded &&
687735
forceWasi &&

0 commit comments

Comments
 (0)