Skip to content

Commit

Permalink
chore(napi/transform): support wasm build (#3933)
Browse files Browse the repository at this point in the history
~~Encountered the same problem as
oxc-project/oxc-resolver#190. Fixed in
[email protected], but oxc use `3.x`~~

Fixed in [email protected]
  • Loading branch information
Dunqing authored Jun 30, 2024
1 parent bd1141d commit 3e9e4c9
Show file tree
Hide file tree
Showing 11 changed files with 763 additions and 428 deletions.
16 changes: 16 additions & 0 deletions .github/actions/pnpm/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: Pnpm

description: Install pnpm

runs:
using: composite
steps:
- uses: pnpm/action-setup@v4

- uses: actions/setup-node@v4
with:
node-version-file: .node-version
cache: pnpm

- run: pnpm install --frozen-lockfile
shell: bash
179 changes: 84 additions & 95 deletions .github/workflows/release_napi_transform.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,109 +52,113 @@ jobs:
include:
- os: windows-latest
target: x86_64-pc-windows-msvc
code-target: win32-x64-msvc

- os: windows-latest
target: aarch64-pc-windows-msvc
code-target: win32-arm64-msvc

- os: ubuntu-latest
target: x86_64-unknown-linux-gnu
code-target: linux-x64-gnu

- os: ubuntu-latest
target: aarch64-unknown-linux-gnu
code-target: linux-arm64-gnu
target: x86_64-unknown-linux-musl

- os: ubuntu-latest
target: x86_64-unknown-linux-musl
code-target: linux-x64-musl
target: aarch64-unknown-linux-gnu

- os: ubuntu-latest
target: aarch64-unknown-linux-musl
code-target: linux-arm64-musl

- os: macos-13
- os: ubuntu-latest
target: armv7-unknown-linux-gnueabihf

- os: macos-latest
target: x86_64-apple-darwin
code-target: darwin-x64

- os: macos-14 # M1
- os: macos-latest
target: aarch64-apple-darwin
code-target: darwin-arm64

- os: ubuntu-latest
target: wasm32-wasip1-threads

name: Package ${{ matrix.target }}
runs-on: ${{ matrix.os }}
steps:
- uses: taiki-e/checkout-action@v1

### install musl dependencies ###

- uses: goto-bus-stop/setup-zig@v2
if: ${{ contains(matrix.target, 'musl') }}
with:
version: 0.11.0

- name: Install cargo-zigbuild
if: ${{ contains(matrix.target, 'musl') }}
uses: taiki-e/install-action@v2
with:
tool: cargo-zigbuild

### install non-musl dependencies ###

- name: Install cross
if: ${{ !contains(matrix.target, 'musl') }}
uses: taiki-e/install-action@cross

### Build
- uses: ./.github/actions/pnpm

- name: Add Rust Target
run: rustup target add ${{ matrix.target }}

- name: Build with cross
if: ${{ !contains(matrix.target, 'musl') }}
run: cross build --release -p oxc_transform_napi --target=${{ matrix.target }}
- uses: goto-bus-stop/setup-zig@v2
if: ${{ contains(matrix.target, 'musl') }}
with:
version: 0.13.0

- name: Build with zig
- name: Build with zig cross
if: ${{ contains(matrix.target, 'musl') }}
env:
RUSTFLAGS: "-C target-feature=-crt-static"
run: cargo zigbuild --release -p oxc_transform_napi --target=${{ matrix.target }}
run: pnpm build -x --target ${{ matrix.target }}

### Build Done
- name: Build with napi cross
if: ${{ contains(matrix.target, 'gnu') }}
run: pnpm build --use-napi-cross --target ${{ matrix.target }}

- name: Move file on ${{ matrix.os }}
run: |
shopt -s extglob
ls target/${{ matrix.target }}/release/*.@(so|dll|dylib)
mv target/${{ matrix.target }}/release/*.@(so|dll|dylib) napi/transform/transform.${{ matrix.code-target }}.node
ls napi/transform
- name: Build
if: ${{ !contains(matrix.target, 'gnu') && !contains(matrix.target, 'musl') }}
run: pnpm build --target ${{ matrix.target }}

- name: Test
working-directory: napi/transform
if: ${{ contains(matrix.target, 'x86') && !contains(matrix.target, 'musl') }} # Need docker for aarch64
if: matrix.target == 'x86_64-pc-windows-msvc' || matrix.target == 'aarch64-apple-darwin' || matrix.target == 'wasm32-wasip1-threads'
run: pnpm test

- name: Output docker params
if: ${{ contains(matrix.target, 'linux') }}
id: docker
run: |
ls
node test.mjs
node -e "
if ('${{ matrix.target }}'.startsWith('aarch64')) {
console.log('PLATFORM=linux/arm64')
} else if ('${{ matrix.target }}'.startsWith('armv7')) {
console.log('PLATFORM=linux/arm/v7')
} else {
console.log('PLATFORM=linux/amd64')
}
" >> $GITHUB_OUTPUT
node -e "
if ('${{ matrix.target }}'.endsWith('-musl')) {
console.log('IMAGE=node:lts-alpine')
} else {
console.log('IMAGE=node:lts-slim')
}
" >> $GITHUB_OUTPUT
echo "PNPM_STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_OUTPUT
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
if: ${{ contains(matrix.target, 'linux') }}
with:
platforms: all

# The binary is zipped to fix permission loss https://github.com/actions/upload-artifact#permission-loss
- name: Archive Binary
if: runner.os == 'Windows'
run: 7z a ${{ matrix.code-target }}.zip napi/transform/transform.${{ matrix.code-target }}.node
- run: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
if: ${{ contains(matrix.target, 'linux') }}

# The binary is zipped to fix permission loss https://github.com/actions/upload-artifact#permission-loss
- name: Archive Binary
if: runner.os != 'Windows'
run: tar czf ${{ matrix.code-target }}.tar.gz napi/transform/transform.${{ matrix.code-target }}.node
- name: Run linux test
uses: addnab/docker-run-action@v3
if: ${{ contains(matrix.target, 'linux') }}
with:
image: ${{ steps.docker.outputs.IMAGE }}
options: -v ${{ steps.docker.outputs.PNPM_STORE_PATH }}:${{ steps.docker.outputs.PNPM_STORE_PATH }} -v ${{ github.workspace }}:/oxc_resolver -w /oxc_resolver --platform ${{ steps.docker.outputs.PLATFORM }}
run: |
corepack enable
pnpm test
- name: Upload artifact
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
if-no-files-found: error
name: binaries-${{ matrix.code-target }}
name: bindings-${{ matrix.target }}
path: |
*.zip
*.tar.gz
napi/transform/*.node
napi/transform/*.wasm
publish:
name: Publish NAPI
Expand All @@ -166,47 +170,32 @@ jobs:
steps:
- uses: taiki-e/checkout-action@v1

- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version-file: .node-version
registry-url: 'https://registry.npmjs.org'
- uses: ./.github/actions/pnpm

- name: Download Artifacts
uses: actions/download-artifact@v4
with:
merge-multiple: true
path: /npm/oxc-transform/artifacts

- name: Unzip
uses: montudor/action-zip@v1
with:
args: unzip -qq *.zip -d .

- name: Untar
run: ls *.gz | xargs -i tar xvf {}

- name: Generate npm packages
- name: Prepare dirs and artifacts
run: |
ls
ls napi/transform
node npm/oxc-transform/scripts/generate-packages.mjs
cat npm/oxc-transform/package.json
for package in npm/oxc-transform*
do
ls $package
cat $package/package.json
echo '----'
done
pnpm i
pnpm napi create-npm-dirs --cwd ../../npm/oxc-transform
pnpm napi artifacts --cwd ../../npm/oxc-transform
working-directory: /napi/transform


- name: Publish npm packages as latest
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
# NOTE: The trailing slash on $package/ changes it to publishing the directory
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
shell: bash
run: |
# publish subpackages first
for package in npm/oxc-transform-*
do
npm publish $package/ --tag latest --provenance --access public
done
# publish root package last
npm publish npm/oxc-transform/ --provenance --access public --tag latest
cp index.js ../../npm/oxc-transform/index.js
cp index.d.ts ../../npm/oxc-transform/index.d.ts
cp browser.js ../../npm/oxc-transform/browser.js
echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ~/.npmrc
pnpm napi pre-publish --cwd ../../npm/oxc-transform --no-gh-release -t npm
npm publish ../../npm/oxc-transform --tag latest --provenance --access public
working-directory: /napi/transform
1 change: 1 addition & 0 deletions napi/transform/browser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from '@oxc-transform/binding-wasm32-wasi'
66 changes: 41 additions & 25 deletions napi/transform/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
/* tslint:disable */
/* auto-generated by NAPI-RS */
/* eslint-disable */
export interface ArrowFunctionsBindingOptions {
spec: boolean
}

/* auto-generated by NAPI-RS */
export interface Es2015BindingOptions {
arrowFunction?: ArrowFunctionsBindingOptions
}

export interface TypeScriptBindingOptions {
jsxPragma: string
jsxPragmaFrag: string
onlyRemoveTypeImports: boolean
allowNamespaces: boolean
allowDeclareFields: boolean
/** TypeScript Isolated Declarations for Standalone DTS Emit */
export function isolatedDeclaration(filename: string, sourceText: string): IsolatedDeclarationsResult

export interface IsolatedDeclarationsResult {
sourceText: string
errors: Array<string>
}

export interface ReactBindingOptions {
runtime: 'classic' | 'automatic'
development: boolean
Expand All @@ -21,17 +27,7 @@ export interface ReactBindingOptions {
useBuiltIns?: boolean
useSpread?: boolean
}
export interface ArrowFunctionsBindingOptions {
spec: boolean
}
export interface Es2015BindingOptions {
arrowFunction?: ArrowFunctionsBindingOptions
}
export interface TransformBindingOptions {
typescript: TypeScriptBindingOptions
react: ReactBindingOptions
es2015: Es2015BindingOptions
}

export interface Sourcemap {
file?: string
mappings?: string
Expand All @@ -40,15 +36,35 @@ export interface Sourcemap {
sourcesContent?: Array<string | undefined | null>
names?: Array<string>
}

export function transform(filename: string, sourceText: string, options: TransformBindingOptions): TransformResult

export interface TransformBindingOptions {
typescript: TypeScriptBindingOptions
react: ReactBindingOptions
es2015: Es2015BindingOptions
/**
* Enable Sourcemaps
*
* * `true` to generate a sourcemap for the code and include it in the result object.
*
* Default: false
*/
sourcemaps: boolean
}

export interface TransformResult {
sourceText: string
/** Sourcemap */
map?: Sourcemap
errors: Array<string>
}
export function transform(filename: string, sourceText: string, options: TransformBindingOptions): TransformResult
export interface IsolatedDeclarationsResult {
sourceText: string
errors: Array<string>

export interface TypeScriptBindingOptions {
jsxPragma: string
jsxPragmaFrag: string
onlyRemoveTypeImports: boolean
allowNamespaces: boolean
allowDeclareFields: boolean
}
/** TypeScript Isolated Declarations for Standalone DTS Emit */
export function isolatedDeclaration(filename: string, sourceText: string): IsolatedDeclarationsResult

Loading

0 comments on commit 3e9e4c9

Please sign in to comment.