mirror of
https://github.com/tailwindlabs/tailwindcss.git
synced 2025-12-08 21:36:08 +00:00
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: 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>
68 lines
1.8 KiB
JavaScript
68 lines
1.8 KiB
JavaScript
import { exec, execSync } from 'node:child_process'
|
|
import fs from 'node:fs/promises'
|
|
import { platform } from 'node:os'
|
|
import path, { dirname } from 'node:path'
|
|
import url from 'node:url'
|
|
|
|
const __dirname = path.dirname(url.fileURLToPath(import.meta.url))
|
|
let root = path.resolve(__dirname, '..')
|
|
|
|
let command = platform() === 'win32' ? 'cd' : 'pwd'
|
|
let rawPaths = execSync(`pnpm --silent --filter=!./playgrounds/* -r exec ${command}`).toString()
|
|
|
|
let paths = rawPaths
|
|
.trim()
|
|
.split(/\r?\n/)
|
|
.map((x) => path.join(x, 'package.json'))
|
|
|
|
let workspaces = new Map()
|
|
|
|
// Track all the workspaces
|
|
for (let path of paths) {
|
|
let pkg = await fs.readFile(path, 'utf8').then(JSON.parse)
|
|
if (pkg.private) continue
|
|
workspaces.set(pkg.name, { version: pkg.version ?? '', dir: dirname(path) })
|
|
}
|
|
|
|
// Clean dist folder
|
|
await fs.rm(path.join(root, 'dist'), { recursive: true, force: true })
|
|
|
|
Promise.all(
|
|
[...workspaces.entries()].map(async ([name, { version, dir }]) => {
|
|
function pack() {
|
|
return new Promise((resolve) => {
|
|
exec(
|
|
`pnpm pack --pack-gzip-level=0 --pack-destination="${path.join(root, 'dist').replace(/\\/g, '\\\\')}"`,
|
|
{ cwd: dir },
|
|
(err, stdout, stderr) => {
|
|
if (err) {
|
|
console.error(err, stdout, stderr)
|
|
}
|
|
|
|
resolve(lastLine(stdout.trim()))
|
|
},
|
|
)
|
|
})
|
|
}
|
|
|
|
let filename = await pack()
|
|
// Remove version suffix
|
|
await fs.rename(
|
|
path.join(root, 'dist', path.basename(filename)),
|
|
path.join(root, 'dist', pkgToFilename(name)),
|
|
)
|
|
}),
|
|
).then(() => {
|
|
console.log('Done.')
|
|
})
|
|
|
|
function pkgToFilename(name) {
|
|
return `${name.replace('@', '').replace('/', '-')}.tgz`
|
|
}
|
|
|
|
function lastLine(str) {
|
|
let index = str.lastIndexOf('\n')
|
|
if (index === -1) return str
|
|
return str.slice(index + 1)
|
|
}
|