Right now, we use Rust for `@tailwindcss/oxide` which has 2
responsibilities:
1. Traverse the file system and figure out which files need to be
scanned based on auto source detection and `@source` directives.
2. Given those files, extract possible Tailwind CSS classes which we
call candidates.
Since this is using native code, we use napi-rs to get native `.node`
files on a per platform / arch basis.
So far so good, however, if you are on an OS that doesn't have a
prebuilt binary, you will receive an error that might look like this:
```
Error: Cannot find native binding. npm has a bug related to optional dependencies (https://github.com/npm/cli/issues/4828). Please try `npm i` again after removing both package-lock.json and node_modules directory.
at Object.<anonymous> (/private/var/folders/1k/bdv8blv93xq7qgwjdwc9z88h0000gn/T/tailwind-integrationspYHIVP/node_modules/.pnpm/@tailwindcss+oxide@file+..+..+..+..+..+..+..+Users+robin+github.com+tailwindlabs+tailwi_47ae1688f61c719f66c73e2ff35e430f/node_modules/@tailwindcss/oxide/index.js:573:19)
at Module._compile (node:internal/modules/cjs/loader:1829:14)
at Object..js (node:internal/modules/cjs/loader:1969:10)
at Module.load (node:internal/modules/cjs/loader:1552:32)
at Module._load (node:internal/modules/cjs/loader:1354:12)
at wrapModuleLoad (node:internal/modules/cjs/loader:255:19)
at Module.require (node:internal/modules/cjs/loader:1575:12)
at require (node:internal/modules/helpers:191:16)
at file:///private/var/folders/1k/bdv8blv93xq7qgwjdwc9z88h0000gn/T/tailwind-integrationspYHIVP/index.mjs:5:19
at ModuleJob.run (node:internal/modules/esm/module_job:437:25) {
cause: Error: Cannot find module '@tailwindcss/oxide-darwin-arm64'
```
This means that we have to add support for these platforms, and there
are some open PRs related to this, which could be closed by this PR:
- #20327
- #20276
- #20201
Today we already have support for the big platforms out there:
- Windows arm64
- Windows x64
- macOS arm64
- macOS x64
But then it starts to get a bit out of hand once we start looking at
Linux based versions:
- Android arm eabi
- Android arm64
- Linux arm64 gnu
- Linux arm64 gnueabihf
- Linux arm64 musl
- Linux x64 gnu
- Linux x64 musl
- freebsd x64
... and then we have the pending list from the 3 PRs linked above.
Adding support for all of these is not the end of the world, but it gets
complex if we need to keep supporting more and more. Right now we rely
on a bunch of non-default napi-rs setup in CI just to support these
other platforms.
This PR solves that by using the `wasm32-wasi` build as a universal
fallback. The napi-rs generated loader already knows how to fall back to
`@tailwindcss/oxide-wasm32-wasi`, but that package declared `"cpu":
["wasm32"]`, so npm/pnpm never installed it on real hardware. Removing
that restriction means the package is installed everywhere, and the
loader picks it up whenever no native binding exists.
This PR also fixes a `UVWASI_EACCES` crash on sandboxed platforms
(OpenHarmony, Android): the generated wasm loader preopens `/`, which
those sandboxes deny, so the fallback failed to load on exactly the
platforms that need it (see [this
comment](https://github.com/tailwindlabs/tailwindcss/pull/20276#issuecomment-4950167198)).
We patch `@napi-rs/cli`'s codegen templates via `pnpm patch` to retry
with narrower preopens (`/` → cwd → none). On such platforms, scanning
is limited to files under the current working directory.
## Test plan
Added two integration tests:
1. Trick pnpm (via `supportedArchitectures`) into installing for a
platform we explicitly don't support, and assert `@tailwindcss/oxide`
loads the wasm binding and scans files from disk.
2. Simulate a sandbox that denies preopening `/`, and assert the wasm
binding still loads and scans.
[ci-all]
<!--
👋 Hey, thanks for your interest in contributing to Tailwind!
**Please ask first before starting work on any significant new
features.**
It's never a fun experience to have your pull request declined after
investing a lot of time and effort into a new feature. To avoid this
from happening, we request that contributors create a discussion to
first discuss any significant new features.
For more info, check out the contributing guide:
https://github.com/tailwindcss/tailwindcss/blob/main/.github/CONTRIBUTING.md
-->
## Summary
fix some typos in comments
<!--
Provide a summary of the issue and the changes you're making. How does
your change solve the problem?
-->
## Test plan
<!--
Explain how you tested your changes. Include the exact commands that you
used to verify the change works and include screenshots/screen
recordings of the update behavior in the browser if applicable.
-->
Signed-off-by: xibeiyoumian <xibeiyoumian@outlook.com>
Description:
This pull request corrects minor typos in comments and improves clarity
in two files:
- Fixes a typo in a comment within migrate-js-config.ts ("migrateable" →
"migratable").
- Refines a comment in wasm.test.ts for better readability.
No functional code changes are included.
Closes#17448Closes#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: https://github.com/nodejs/node/issues/47193
### Windows issues
We also found that the Node.js wasi container does not properly support
Windows: https://github.com/nodejs/uvwasi/issues/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 <malfait.robin@gmail.com>