Skip to content

Commit 83ce4c0

Browse files
Add experimental @tailwindcss/oxide-wasm32-wasi (#17558)
Closes #17448 Closes #13133 This PR adds an a new Oxide target for `wasm32-wasip1-threads`: `@tailwindcss/oxide-wasm32-wasi`. The goal of this is to enable more environments to run Oxide, including (but not limited to) StackBlitz. We're making use of `napi-rs`'s upcoming v3 features to simplify the setup here, meaning `napi-rs` will configure the WASM target and create an npm package that works across Node and browser environments. ## MacOS AArch64 issues While setting up an integration test for the new WASM target, I ran into an issue where FS reads where not terminating on macOS. After some research I found this to be a limitation of the Node.js container interface right now, see: nodejs/node#47193 ### Windows issues We also found that the Node.js wasi container does not properly support Windows: nodejs/uvwasi#11 For now we, it's probably best for MacOS AArch64 users and Windows users to use the native modules instead. ## Test plan The `@tailwindcss/oxide-wasm32-wasi` npm package can be built locally via `pnpm build` and then run with the Oxide API. A usage example can be taken from the newly added integration test. Furthermore this was tested to work as a polyfill on StackBlitz: https://stackblitz.com/edit/vitejs-vite-uks3gt5p [ci-all] --------- Co-authored-by: Robin Malfait <[email protected]>
1 parent 6e1f533 commit 83ce4c0

20 files changed

+1432
-78
lines changed

.github/workflows/ci.yml

+10-2
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,20 @@ jobs:
6767
uses: actions/cache@v4
6868
with:
6969
path: |
70-
./target/
7170
./crates/node/*.node
72-
./crates/node/index.js
71+
./crates/node/*.wasm
7372
./crates/node/index.d.ts
73+
./crates/node/index.js
74+
./crates/node/browser.js
75+
./crates/node/tailwindcss-oxide.wasi-browser.js
76+
./crates/node/tailwindcss-oxide.wasi.cjs
77+
./crates/node/wasi-worker-browser.mjs
78+
./crates/node/wasi-worker.mjs
7479
key: ${{ runner.os }}-oxide-${{ hashFiles('./crates/**/*') }}
7580

81+
- name: Setup WASM target
82+
run: rustup target add wasm32-wasip1-threads
83+
7684
- name: Install dependencies
7785
run: pnpm install
7886

.github/workflows/integration-tests.yml

+11-3
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ jobs:
3030
- vite
3131
- cli
3232
- postcss
33-
- workers
33+
- oxide
3434
- webpack
3535

3636
# Exclude windows and macos from being built on feature branches
@@ -76,12 +76,20 @@ jobs:
7676
uses: actions/cache@v4
7777
with:
7878
path: |
79-
./target/
8079
./crates/node/*.node
81-
./crates/node/index.js
80+
./crates/node/*.wasm
8281
./crates/node/index.d.ts
82+
./crates/node/index.js
83+
./crates/node/browser.js
84+
./crates/node/tailwindcss-oxide.wasi-browser.js
85+
./crates/node/tailwindcss-oxide.wasi.cjs
86+
./crates/node/wasi-worker-browser.mjs
87+
./crates/node/wasi-worker.mjs
8388
key: ${{ runner.os }}-oxide-${{ hashFiles('./crates/**/*') }}
8489

90+
- name: Setup WASM target
91+
run: rustup target add wasm32-wasip1-threads
92+
8593
- name: Install dependencies
8694
run: pnpm install
8795

.github/workflows/prepare-release.yml

+33-8
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ jobs:
6868
container:
6969
image: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-alpine
7070

71-
name: Build ${{ matrix.target }} (OXIDE)
71+
name: Build ${{ matrix.target }} (oxide)
7272
runs-on: ${{ matrix.os }}
7373
container: ${{ matrix.container }}
7474
timeout-minutes: 15
@@ -82,6 +82,12 @@ jobs:
8282
node-version: ${{ env.NODE_VERSION }}
8383
cache: 'pnpm'
8484

85+
- name: Install gcc-arm-linux-gnueabihf
86+
if: ${{ matrix.target == 'armv7-unknown-linux-gnueabihf' }}
87+
run: |
88+
sudo apt-get update
89+
sudo apt-get install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf -y
90+
8591
# Cargo already skips downloading dependencies if they already exist
8692
- name: Cache cargo
8793
uses: actions/cache@v4
@@ -99,10 +105,15 @@ jobs:
99105
uses: actions/cache@v4
100106
with:
101107
path: |
102-
./oxide/target/
103108
./crates/node/*.node
104-
./crates/node/index.js
109+
./crates/node/*.wasm
105110
./crates/node/index.d.ts
111+
./crates/node/index.js
112+
./crates/node/browser.js
113+
./crates/node/tailwindcss-oxide.wasi-browser.js
114+
./crates/node/tailwindcss-oxide.wasi.cjs
115+
./crates/node/wasi-worker-browser.mjs
116+
./crates/node/wasi-worker.mjs
106117
key: ${{ runner.os }}-${{ matrix.target }}-oxide-${{ hashFiles('./crates/**/*') }}
107118

108119
- name: Install Node.JS
@@ -122,7 +133,7 @@ jobs:
122133
run: pnpm install --ignore-scripts --filter=!./playgrounds/*
123134

124135
- name: Build release
125-
run: pnpm run --filter ${{ env.OXIDE_LOCATION }} build
136+
run: pnpm run --filter ${{ env.OXIDE_LOCATION }} build:platform --target=${{ matrix.target }}
126137
env:
127138
RUST_TARGET: ${{ matrix.target }}
128139
JEMALLOC_SYS_WITH_LG_PAGE: ${{ matrix.page-size }}
@@ -172,7 +183,7 @@ jobs:
172183
node -v
173184
echo "~~~~ pnpm --version ~~~~"
174185
pnpm --version
175-
pnpm run --filter ${{ env.OXIDE_LOCATION }} build
186+
pnpm run --filter ${{ env.OXIDE_LOCATION }} build:platform
176187
strip -x ${{ env.OXIDE_LOCATION }}/*.node
177188
ls -la ${{ env.OXIDE_LOCATION }}
178189
- name: Upload artifacts
@@ -233,12 +244,20 @@ jobs:
233244
uses: actions/cache@v4
234245
with:
235246
path: |
236-
./oxide/target/
237247
./crates/node/*.node
238-
./crates/node/index.js
248+
./crates/node/*.wasm
239249
./crates/node/index.d.ts
250+
./crates/node/index.js
251+
./crates/node/browser.js
252+
./crates/node/tailwindcss-oxide.wasi-browser.js
253+
./crates/node/tailwindcss-oxide.wasi.cjs
254+
./crates/node/wasi-worker-browser.mjs
255+
./crates/node/wasi-worker.mjs
240256
key: ${{ runner.os }}-${{ matrix.target }}-oxide-${{ hashFiles('./crates/**/*') }}
241257

258+
- name: Setup WASM target
259+
run: rustup target add wasm32-wasip1-threads
260+
242261
- name: Install dependencies
243262
run: pnpm --filter=!./playgrounds/* install
244263

@@ -281,12 +300,18 @@ jobs:
281300
echo "$RELEASE_NOTES" >> $GITHUB_ENV
282301
echo "EOF" >> $GITHUB_ENV
283302
284-
- name: Upload Standalone Artifacts
303+
- name: Upload standalone artifacts
285304
uses: actions/upload-artifact@v4
286305
with:
287306
name: tailwindcss-standalone
288307
path: packages/@tailwindcss-standalone/dist/
289308

309+
- name: Upload npm package tarballs
310+
uses: actions/upload-artifact@v4
311+
with:
312+
name: npm-package-tarballs
313+
path: dist/*.tgz
314+
290315
- name: Prepare GitHub Release
291316
uses: softprops/action-gh-release@v2
292317
with:

.github/workflows/release-insiders.yml

+32-7
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ jobs:
6767
container:
6868
image: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-alpine
6969

70-
name: Build ${{ matrix.target }} (OXIDE)
70+
name: Build ${{ matrix.target }} (oxide)
7171
runs-on: ${{ matrix.os }}
7272
container: ${{ matrix.container }}
7373
timeout-minutes: 15
@@ -81,6 +81,12 @@ jobs:
8181
node-version: ${{ env.NODE_VERSION }}
8282
cache: 'pnpm'
8383

84+
- name: Install gcc-arm-linux-gnueabihf
85+
if: ${{ matrix.target == 'armv7-unknown-linux-gnueabihf' }}
86+
run: |
87+
sudo apt-get update
88+
sudo apt-get install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf -y
89+
8490
# Cargo already skips downloading dependencies if they already exist
8591
- name: Cache cargo
8692
uses: actions/cache@v4
@@ -98,10 +104,15 @@ jobs:
98104
uses: actions/cache@v4
99105
with:
100106
path: |
101-
./oxide/target/
102107
./crates/node/*.node
103-
./crates/node/index.js
108+
./crates/node/*.wasm
104109
./crates/node/index.d.ts
110+
./crates/node/index.js
111+
./crates/node/browser.js
112+
./crates/node/tailwindcss-oxide.wasi-browser.js
113+
./crates/node/tailwindcss-oxide.wasi.cjs
114+
./crates/node/wasi-worker-browser.mjs
115+
./crates/node/wasi-worker.mjs
105116
key: ${{ runner.os }}-${{ matrix.target }}-oxide-${{ hashFiles('./crates/**/*') }}
106117

107118
- name: Install Node.JS
@@ -121,7 +132,7 @@ jobs:
121132
run: pnpm install --ignore-scripts --filter=!./playgrounds/*
122133

123134
- name: Build release
124-
run: pnpm run --filter ${{ env.OXIDE_LOCATION }} build
135+
run: pnpm run --filter ${{ env.OXIDE_LOCATION }} build:platform --target=${{ matrix.target }}
125136
env:
126137
RUST_TARGET: ${{ matrix.target }}
127138
JEMALLOC_SYS_WITH_LG_PAGE: ${{ matrix.page-size }}
@@ -171,7 +182,7 @@ jobs:
171182
echo "~~~~ pnpm --version ~~~~"
172183
pnpm --version
173184
pnpm install --ignore-scripts --filter=!./playgrounds/* || true
174-
pnpm run --filter ${{ env.OXIDE_LOCATION }} build
185+
pnpm run --filter ${{ env.OXIDE_LOCATION }} build:platform
175186
strip -x ${{ env.OXIDE_LOCATION }}/*.node
176187
ls -la ${{ env.OXIDE_LOCATION }}
177188
- name: Upload artifacts
@@ -230,12 +241,20 @@ jobs:
230241
uses: actions/cache@v4
231242
with:
232243
path: |
233-
./oxide/target/
234244
./crates/node/*.node
235-
./crates/node/index.js
245+
./crates/node/*.wasm
236246
./crates/node/index.d.ts
247+
./crates/node/index.js
248+
./crates/node/browser.js
249+
./crates/node/tailwindcss-oxide.wasi-browser.js
250+
./crates/node/tailwindcss-oxide.wasi.cjs
251+
./crates/node/wasi-worker-browser.mjs
252+
./crates/node/wasi-worker.mjs
237253
key: ${{ runner.os }}-${{ matrix.target }}-oxide-${{ hashFiles('./crates/**/*') }}
238254

255+
- name: Setup WASM target
256+
run: rustup target add wasm32-wasip1-threads
257+
239258
- name: Install dependencies
240259
run: pnpm --filter=!./playgrounds/* install
241260

@@ -272,6 +291,12 @@ jobs:
272291
- name: Lock pre-release versions
273292
run: node ./scripts/lock-pre-release-versions.mjs
274293

294+
- name: Upload npm package tarballs
295+
uses: actions/upload-artifact@v4
296+
with:
297+
name: npm-package-tarballs
298+
path: dist/*.tgz
299+
275300
- name: Publish
276301
run: pnpm --recursive publish --tag ${{ env.RELEASE_CHANNEL }} --no-git-checks
277302
env:

.github/workflows/release.yml

+26-7
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ jobs:
6767
container:
6868
image: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-alpine
6969

70-
name: Build ${{ matrix.target }} (OXIDE)
70+
name: Build ${{ matrix.target }} (oxide)
7171
runs-on: ${{ matrix.os }}
7272
container: ${{ matrix.container }}
7373
timeout-minutes: 15
@@ -81,6 +81,12 @@ jobs:
8181
node-version: ${{ env.NODE_VERSION }}
8282
cache: 'pnpm'
8383

84+
- name: Install gcc-arm-linux-gnueabihf
85+
if: ${{ matrix.target == 'armv7-unknown-linux-gnueabihf' }}
86+
run: |
87+
sudo apt-get update
88+
sudo apt-get install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf -y
89+
8490
# Cargo already skips downloading dependencies if they already exist
8591
- name: Cache cargo
8692
uses: actions/cache@v4
@@ -98,10 +104,15 @@ jobs:
98104
uses: actions/cache@v4
99105
with:
100106
path: |
101-
./oxide/target/
102107
./crates/node/*.node
103-
./crates/node/index.js
108+
./crates/node/*.wasm
104109
./crates/node/index.d.ts
110+
./crates/node/index.js
111+
./crates/node/browser.js
112+
./crates/node/tailwindcss-oxide.wasi-browser.js
113+
./crates/node/tailwindcss-oxide.wasi.cjs
114+
./crates/node/wasi-worker-browser.mjs
115+
./crates/node/wasi-worker.mjs
105116
key: ${{ runner.os }}-${{ matrix.target }}-oxide-${{ hashFiles('./crates/**/*') }}
106117

107118
- name: Install Node.JS
@@ -121,7 +132,7 @@ jobs:
121132
run: pnpm install --ignore-scripts --filter=!./playgrounds/*
122133

123134
- name: Build release
124-
run: pnpm run --filter ${{ env.OXIDE_LOCATION }} build
135+
run: pnpm run --filter ${{ env.OXIDE_LOCATION }} build:platform --target=${{ matrix.target }}
125136
env:
126137
RUST_TARGET: ${{ matrix.target }}
127138
JEMALLOC_SYS_WITH_LG_PAGE: ${{ matrix.page-size }}
@@ -171,7 +182,7 @@ jobs:
171182
echo "~~~~ pnpm --version ~~~~"
172183
pnpm --version
173184
pnpm install --ignore-scripts --filter=!./playgrounds/* || true
174-
pnpm run --filter ${{ env.OXIDE_LOCATION }} build
185+
pnpm run --filter ${{ env.OXIDE_LOCATION }} build:platform
175186
strip -x ${{ env.OXIDE_LOCATION }}/*.node
176187
ls -la ${{ env.OXIDE_LOCATION }}
177188
- name: Upload artifacts
@@ -225,12 +236,20 @@ jobs:
225236
uses: actions/cache@v4
226237
with:
227238
path: |
228-
./oxide/target/
229239
./crates/node/*.node
230-
./crates/node/index.js
240+
./crates/node/*.wasm
231241
./crates/node/index.d.ts
242+
./crates/node/index.js
243+
./crates/node/browser.js
244+
./crates/node/tailwindcss-oxide.wasi-browser.js
245+
./crates/node/tailwindcss-oxide.wasi.cjs
246+
./crates/node/wasi-worker-browser.mjs
247+
./crates/node/wasi-worker.mjs
232248
key: ${{ runner.os }}-${{ matrix.target }}-oxide-${{ hashFiles('./crates/**/*') }}
233249

250+
- name: Setup WASM target
251+
run: rustup target add wasm32-wasip1-threads
252+
234253
- name: Install dependencies
235254
run: pnpm --filter=!./playgrounds/* install
236255

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Added
11+
12+
- Add experimental `@tailwindcss/oxide-wasm32-wasi` target ([#17558](https://github.com/tailwindlabs/tailwindcss/pull/17558))
13+
1014
### Fixed
1115

1216
- Ensure `color-mix(…)` polyfills do not cause used CSS variables to be removed ([#17555](https://github.com/tailwindlabs/tailwindcss/pull/17555))

Cargo.lock

+4-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/node/.gitignore

+8-3
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ dist
121121
.AppleDouble
122122
.LSOverride
123123

124-
# Icon must end with two
124+
# Icon must end with two
125125
Icon
126126

127127

@@ -194,8 +194,13 @@ Cargo.lock
194194
!.yarn/sdks
195195
!.yarn/versions
196196

197-
*.node
198-
199197
# Generated
198+
*.node
199+
*.wasm
200200
index.d.ts
201201
index.js
202+
browser.js
203+
tailwindcss-oxide.wasi-browser.js
204+
tailwindcss-oxide.wasi.cjs
205+
wasi-worker-browser.mjs
206+
wasi-worker.mjs

0 commit comments

Comments
 (0)