Add preliminary standalone CLI experiment
This commit is contained in:
parent
35398e0ffb
commit
cae9d02493
8 changed files with 313 additions and 1 deletions
|
|
@ -60,5 +60,11 @@
|
|||
"typescript": "^5.5.4",
|
||||
"vitest": "^2.0.5"
|
||||
},
|
||||
"packageManager": "pnpm@9.6.0"
|
||||
"packageManager": "pnpm@9.6.0",
|
||||
"pnpm": {
|
||||
"patchedDependencies": {
|
||||
"@parcel/watcher@2.4.1": "patches/@parcel__watcher@2.4.1.patch",
|
||||
"lightningcss@1.26.0": "patches/lightningcss@1.26.0.patch"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
69
packages/@tailwindcss-standalone/build.ts
Normal file
69
packages/@tailwindcss-standalone/build.ts
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
import { $ } from 'bun'
|
||||
import { createHash } from 'node:crypto'
|
||||
import { mkdir, readFile, writeFile } from 'node:fs/promises'
|
||||
import * as path from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
|
||||
const __dirname = fileURLToPath(new URL('.', import.meta.url))
|
||||
|
||||
async function buildForPlatform(triple: string, outfile: string) {
|
||||
// We wrap this in a retry because occasionally the atomic rename fails for some reason
|
||||
for (let i = 0; i < 5; ++i) {
|
||||
try {
|
||||
return await $`bun build --compile --target=${triple} ./src/index.ts --outfile=${outfile}`
|
||||
} catch (err) {
|
||||
if (i < 5) continue
|
||||
|
||||
throw new Error(`Failed to build for platform ${triple}`, { cause: err })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function build(triple: string, file: string) {
|
||||
let start = process.hrtime.bigint()
|
||||
|
||||
let outfile = path.resolve(__dirname, `dist/${file}`)
|
||||
|
||||
await buildForPlatform(triple, outfile)
|
||||
|
||||
await new Promise((resolve) => setTimeout(resolve, 100))
|
||||
|
||||
let content = await readFile(outfile)
|
||||
let sum = createHash('sha256').update(content).digest('hex')
|
||||
|
||||
let elapsed = process.hrtime.bigint() - start
|
||||
|
||||
return {
|
||||
triple,
|
||||
file,
|
||||
sum,
|
||||
elapsed,
|
||||
}
|
||||
}
|
||||
|
||||
await mkdir(path.resolve(__dirname, 'dist'), { recursive: true })
|
||||
|
||||
// Build platform binaries and checksum them
|
||||
let results = await Promise.all([
|
||||
build('bun-linux-arm64', './tailwindcss-linux-arm64'),
|
||||
build('bun-linux-x64', './tailwindcss-linux-x64'),
|
||||
// build('linux-armv7', 'tailwindcss-linux-armv7'),
|
||||
build('bun-darwin-arm64', './tailwindcss-macos-arm64'),
|
||||
build('bun-darwin-x64', './tailwindcss-macos-x64'),
|
||||
build('bun-windows-x64', './tailwindcss-windows-x64.exe'),
|
||||
// buildForPlatform('win32-arm64', 'tailwindcss-windows-arm64'),
|
||||
])
|
||||
|
||||
// Write the checksums to a file
|
||||
let sumsFile = path.resolve(__dirname, 'dist/sha256sums.txt')
|
||||
let sums = results.map(({ file, sum }) => `${sum} ${file}`)
|
||||
|
||||
console.table(
|
||||
results.map(({ triple, sum, elapsed }) => ({
|
||||
triple,
|
||||
sum,
|
||||
elapsed: `${(Number(elapsed) / 1e6).toFixed(0)}ms`,
|
||||
})),
|
||||
)
|
||||
|
||||
await writeFile(sumsFile, sums.join('\n') + '\n')
|
||||
52
packages/@tailwindcss-standalone/package.json
Normal file
52
packages/@tailwindcss-standalone/package.json
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
{
|
||||
"name": "@tailwindcss/standalone",
|
||||
"version": "4.0.0-alpha.18",
|
||||
"description": "Standalone CLI for Tailwind CSS",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/tailwindlabs/tailwindcss.git",
|
||||
"directory": "packages/@tailwindcss-standalone"
|
||||
},
|
||||
"bugs": "https://github.com/tailwindlabs/tailwindcss/issues",
|
||||
"homepage": "https://tailwindcss.com",
|
||||
"scripts": {
|
||||
"lint": "tsc --noEmit",
|
||||
"build": "bun ./build.ts"
|
||||
},
|
||||
"bin": {
|
||||
"tailwindcss": "./dist/index.mjs"
|
||||
},
|
||||
"exports": {
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"publishConfig": {
|
||||
"provenance": true,
|
||||
"access": "public"
|
||||
},
|
||||
"dependencies": {
|
||||
"@tailwindcss/cli": "workspace:^",
|
||||
"tailwindcss": "workspace:^"
|
||||
},
|
||||
"__notes": "These binary packages must be included so Bun can build the CLI for all supported platforms. We also rely on Lightning CSS and Parcel being patched so Bun can statically analyze the executables.",
|
||||
"devDependencies": {
|
||||
"@parcel/watcher-darwin-arm64": "^2.4.2-alpha.0",
|
||||
"@parcel/watcher-darwin-x64": "^2.4.2-alpha.0",
|
||||
"@parcel/watcher-linux-arm64-glibc": "^2.4.2-alpha.0",
|
||||
"@parcel/watcher-linux-arm64-musl": "^2.4.2-alpha.0",
|
||||
"@parcel/watcher-linux-x64-glibc": "^2.4.2-alpha.0",
|
||||
"@parcel/watcher-linux-x64-musl": "^2.4.2-alpha.0",
|
||||
"@parcel/watcher-win32-x64": "^2.4.2-alpha.0",
|
||||
"@types/bun": "^1.1.6",
|
||||
"lightningcss-darwin-arm64": "^1.25.1",
|
||||
"lightningcss-darwin-x64": "^1.25.1",
|
||||
"lightningcss-linux-arm64-gnu": "^1.25.1",
|
||||
"lightningcss-linux-arm64-musl": "^1.25.1",
|
||||
"lightningcss-linux-x64-gnu": "^1.25.1",
|
||||
"lightningcss-linux-x64-musl": "^1.25.1",
|
||||
"lightningcss-win32-x64-msvc": "^1.25.1"
|
||||
}
|
||||
}
|
||||
7
packages/@tailwindcss-standalone/src/index.ts
Normal file
7
packages/@tailwindcss-standalone/src/index.ts
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
import { plugin } from 'bun'
|
||||
import { resolution } from './plugin.ts'
|
||||
|
||||
plugin(resolution)
|
||||
|
||||
await new Promise((resolve) => setTimeout(resolve))
|
||||
await import('../../@tailwindcss-cli/src/index.ts')
|
||||
31
packages/@tailwindcss-standalone/src/plugin.ts
Normal file
31
packages/@tailwindcss-standalone/src/plugin.ts
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
import type { BunPlugin } from 'bun'
|
||||
|
||||
export const resolution: BunPlugin = {
|
||||
name: 'Custom loader',
|
||||
target: 'bun',
|
||||
setup(build) {
|
||||
// onLoad
|
||||
// build.onLoad({ filter: /./ }, async (file) => {
|
||||
// console.log({ file })
|
||||
// return {
|
||||
// loader: 'object',
|
||||
// exports: {},
|
||||
// }
|
||||
// })
|
||||
|
||||
// Replace resolve.ts with the local resolve.standalone.ts
|
||||
build.onResolve({ filter: /./ }, (file) => {
|
||||
console.log('on resolve', { file })
|
||||
|
||||
return undefined
|
||||
|
||||
// return {
|
||||
// path: require.resolve(file.path),
|
||||
// }
|
||||
|
||||
// return Object.assign(file, {
|
||||
// path: require.resolve('./resolve.standalone.ts'),
|
||||
// })
|
||||
})
|
||||
},
|
||||
}
|
||||
34
packages/@tailwindcss-standalone/src/resolve.standalone.ts
Normal file
34
packages/@tailwindcss-standalone/src/resolve.standalone.ts
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
// @ts-ignore
|
||||
import twIndex from 'tailwindcss/index.css' with { type: 'file' }
|
||||
|
||||
// @ts-ignore
|
||||
import twPreflight from 'tailwindcss/preflight.css' with { type: 'file' }
|
||||
|
||||
// @ts-ignore
|
||||
import twTheme from 'tailwindcss/theme.css' with { type: 'file' }
|
||||
|
||||
// @ts-ignore
|
||||
import twUtilities from 'tailwindcss/utilities.css' with { type: 'file' }
|
||||
|
||||
// @ts-ignore
|
||||
// import twPkg from 'tailwindcss/package.json' with { type: 'file' }
|
||||
|
||||
import { createRequire } from 'node:module'
|
||||
|
||||
const localResolve = createRequire(import.meta.url).resolve
|
||||
|
||||
export function resolve(id: string) {
|
||||
if (id === 'tailwindcss/index.css') {
|
||||
return twIndex
|
||||
} else if (id === 'tailwindcss/preflight.css') {
|
||||
return twPreflight
|
||||
} else if (id === 'tailwindcss/theme.css') {
|
||||
return twTheme
|
||||
} else if (id === 'tailwindcss/utilities.css') {
|
||||
return twUtilities
|
||||
} else if (id === 'tailwindcss/package.json') {
|
||||
return twPkg
|
||||
} else {
|
||||
return localResolve(id)
|
||||
}
|
||||
}
|
||||
57
patches/@parcel__watcher@2.4.1.patch
Normal file
57
patches/@parcel__watcher@2.4.1.patch
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
diff --git a/index.js b/index.js
|
||||
index 8afb2b1126dcc687b7ff9b631589da252c1f9c22..15d3b2ffa11f8999ab95d8306f789f2a4613bae3 100644
|
||||
--- a/index.js
|
||||
+++ b/index.js
|
||||
@@ -1,40 +1,22 @@
|
||||
const {createWrapper} = require('./wrapper');
|
||||
|
||||
-let name = `@parcel/watcher-${process.platform}-${process.arch}`;
|
||||
-if (process.platform === 'linux') {
|
||||
- const { MUSL, family } = require('detect-libc');
|
||||
- if (family === MUSL) {
|
||||
- name += '-musl';
|
||||
- } else {
|
||||
- name += '-glibc';
|
||||
- }
|
||||
-}
|
||||
+function loadPackage() {
|
||||
+ if (process.platform === 'linux') {
|
||||
+ const { MUSL, GLIBC, family } = require("detect-libc");
|
||||
|
||||
-let binding;
|
||||
-try {
|
||||
- binding = require(name);
|
||||
-} catch (err) {
|
||||
- handleError(err);
|
||||
- try {
|
||||
- binding = require('./build/Release/watcher.node');
|
||||
- } catch (err) {
|
||||
- handleError(err);
|
||||
- try {
|
||||
- binding = require('./build/Debug/watcher.node');
|
||||
- } catch (err) {
|
||||
- handleError(err);
|
||||
- throw new Error(`No prebuild or local build of @parcel/watcher found. Tried ${name}. Please ensure it is installed (don't use --no-optional when installing with npm). Otherwise it is possible we don't support your platform yet. If this is the case, please report an issue to https://github.com/parcel-bundler/watcher.`);
|
||||
+ if (family === MUSL) {
|
||||
+ return require(`@parcel/watcher-${process.platform}-${process.arch}-musl`);
|
||||
+ } else if (family === GLIBC) {
|
||||
+ return require(`@parcel/watcher-${process.platform}-${process.arch}-glibc`);
|
||||
+ } else {
|
||||
+ throw new Error(`Unsupported libc on: ${process.platform}-${process.arch}`);
|
||||
}
|
||||
+ } else {
|
||||
+ return require(`@parcel/watcher-${process.platform}-${process.arch}`);
|
||||
}
|
||||
}
|
||||
|
||||
-function handleError(err) {
|
||||
- if (err?.code !== 'MODULE_NOT_FOUND') {
|
||||
- throw err;
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-const wrapper = createWrapper(binding);
|
||||
+const wrapper = createWrapper(loadPackage());
|
||||
exports.writeSnapshot = wrapper.writeSnapshot;
|
||||
exports.getEventsSince = wrapper.getEventsSince;
|
||||
exports.subscribe = wrapper.subscribe;
|
||||
56
patches/lightningcss@1.26.0.patch
Normal file
56
patches/lightningcss@1.26.0.patch
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
diff --git a/node/index.js b/node/index.js
|
||||
index a9f2f6d5f3394329fcf8bc06af549030c01167a5..1a7a6dd3612f786495e214090ab943a677a3a612 100644
|
||||
--- a/node/index.js
|
||||
+++ b/node/index.js
|
||||
@@ -1,27 +1,28 @@
|
||||
-let parts = [process.platform, process.arch];
|
||||
-if (process.platform === 'linux') {
|
||||
- const { MUSL, family } = require('detect-libc');
|
||||
- if (family === MUSL) {
|
||||
- parts.push('musl');
|
||||
- } else if (process.arch === 'arm') {
|
||||
- parts.push('gnueabihf');
|
||||
- } else {
|
||||
- parts.push('gnu');
|
||||
- }
|
||||
-} else if (process.platform === 'win32') {
|
||||
- parts.push('msvc');
|
||||
-}
|
||||
+function loadPackage() {
|
||||
+ if (process.platform === "linux") {
|
||||
+ const { MUSL, GLIBC, family } = require("detect-libc");
|
||||
|
||||
-if (process.env.CSS_TRANSFORMER_WASM) {
|
||||
- module.exports = require(`../pkg`);
|
||||
-} else {
|
||||
- try {
|
||||
- module.exports = require(`lightningcss-${parts.join('-')}`);
|
||||
- } catch (err) {
|
||||
- module.exports = require(`../lightningcss.${parts.join('-')}.node`);
|
||||
+ if (family === MUSL) {
|
||||
+ return require(`lightningcss-${process.platform}-${process.arch}-musl`);
|
||||
+ } else if (family === GLIBC) {
|
||||
+ if (process.arch === "arm") {
|
||||
+ return require(`lightningcss-${process.platform}-${process.arch}-gnueabihf`);
|
||||
+ } else {
|
||||
+ return require(`lightningcss-${process.platform}-${process.arch}-gnu`);
|
||||
+ }
|
||||
+ } else {
|
||||
+ throw new Error(
|
||||
+ `Unsupported libc on: ${process.platform}-${process.arch}`
|
||||
+ );
|
||||
+ }
|
||||
+ } else if (process.platform === "win32") {
|
||||
+ return require(`lightningcss-${process.platform}-${process.arch}-msvc`);
|
||||
+ } else {
|
||||
+ return require(`lightningcss-${process.platform}-${process.arch}`);
|
||||
}
|
||||
}
|
||||
|
||||
-module.exports.browserslistToTargets = require('./browserslistToTargets');
|
||||
-module.exports.composeVisitors = require('./composeVisitors');
|
||||
-module.exports.Features = require('./flags').Features;
|
||||
+module.exports = loadPackage();
|
||||
+module.exports.browserslistToTargets = require("./browserslistToTargets");
|
||||
+module.exports.composeVisitors = require("./composeVisitors");
|
||||
+module.exports.Features = require("./flags").Features;
|
||||
Loading…
Add table
Add a link
Reference in a new issue