Add the @tailwindcss/node module to handle shared node specific dependencies between our clients
This commit is contained in:
parent
d607f0a40e
commit
a5c379386b
17 changed files with 304 additions and 41 deletions
|
|
@ -67,11 +67,10 @@ test(
|
|||
}
|
||||
`,
|
||||
'postcss.config.mjs': js`
|
||||
import tailwindcss from '@tailwindcss/postcss'
|
||||
/** @type {import('postcss-load-config').Config} */
|
||||
export default {
|
||||
plugins: {
|
||||
'@tailwindcss/postcss': {},
|
||||
},
|
||||
plugins: [tailwindcss()],
|
||||
}
|
||||
`,
|
||||
'index.html': html`
|
||||
|
|
@ -103,3 +102,128 @@ test(
|
|||
])
|
||||
},
|
||||
)
|
||||
|
||||
test(
|
||||
'Config files (CJS, watch mode)',
|
||||
{
|
||||
fs: {
|
||||
'package.json': json`
|
||||
{
|
||||
"dependencies": {
|
||||
"postcss": "^8",
|
||||
"postcss-cli": "^10",
|
||||
"tailwindcss": "workspace:^",
|
||||
"@tailwindcss/postcss": "workspace:^"
|
||||
}
|
||||
}
|
||||
`,
|
||||
'postcss.config.js': js`
|
||||
/** @type {import('postcss-load-config').Config} */
|
||||
module.exports = {
|
||||
plugins: {
|
||||
'@tailwindcss/postcss': {},
|
||||
},
|
||||
}
|
||||
`,
|
||||
'index.html': html`
|
||||
<div class="text-primary"></div>
|
||||
`,
|
||||
'tailwind.config.js': js`
|
||||
let myColor = require('./my-color.js')
|
||||
module.exports = {
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
primary: myColor,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
`,
|
||||
'my-color.js': js`module.exports = 'blue'`,
|
||||
'src/index.css': css`
|
||||
@import 'tailwindcss';
|
||||
@config '../tailwind.config.js';
|
||||
`,
|
||||
},
|
||||
},
|
||||
async ({ fs, spawn }) => {
|
||||
await spawn('pnpm postcss src/index.css --output dist/out.css --watch --verbose')
|
||||
|
||||
await fs.expectFileToContain('dist/out.css', [
|
||||
//
|
||||
candidate`text-primary`,
|
||||
'color: blue',
|
||||
])
|
||||
|
||||
await fs.write('my-color.js', js`module.exports = 'red'`)
|
||||
|
||||
await fs.expectFileToContain('dist/out.css', [
|
||||
//
|
||||
candidate`text-primary`,
|
||||
'color: red',
|
||||
])
|
||||
},
|
||||
)
|
||||
|
||||
test(
|
||||
'Config files (ESM, watch mode)',
|
||||
{
|
||||
fs: {
|
||||
'package.json': json`
|
||||
{
|
||||
"dependencies": {
|
||||
"postcss": "^8",
|
||||
"postcss-cli": "^10",
|
||||
"tailwindcss": "workspace:^",
|
||||
"@tailwindcss/postcss": "workspace:^"
|
||||
}
|
||||
}
|
||||
`,
|
||||
'postcss.config.mjs': js`
|
||||
import tailwindcss from '@tailwindcss/postcss'
|
||||
/** @type {import('postcss-load-config').Config} */
|
||||
export default {
|
||||
plugins: [tailwindcss()],
|
||||
}
|
||||
`,
|
||||
'index.html': html`
|
||||
<div class="text-primary"></div>
|
||||
`,
|
||||
'tailwind.config.mjs': js`
|
||||
import myColor from './my-color.mjs'
|
||||
export default {
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
primary: myColor,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
`,
|
||||
'my-color.mjs': js`export default 'blue'`,
|
||||
'src/index.css': css`
|
||||
@import 'tailwindcss';
|
||||
@config '../tailwind.config.mjs';
|
||||
`,
|
||||
},
|
||||
},
|
||||
async ({ fs, spawn }) => {
|
||||
await spawn('pnpm postcss src/index.css --output dist/out.css --watch --verbose')
|
||||
|
||||
await fs.expectFileToContain('dist/out.css', [
|
||||
//
|
||||
candidate`text-primary`,
|
||||
'color: blue',
|
||||
])
|
||||
|
||||
await fs.write('my-color.mjs', js`export default 'red'`)
|
||||
|
||||
await fs.expectFileToContain('dist/out.css', [
|
||||
//
|
||||
candidate`text-primary`,
|
||||
'color: red',
|
||||
])
|
||||
},
|
||||
)
|
||||
|
|
|
|||
|
|
@ -257,11 +257,9 @@ test(
|
|||
},
|
||||
},
|
||||
async ({ root, fs, spawn }) => {
|
||||
let process = await spawn(
|
||||
'pnpm postcss src/index.css --output dist/out.css --watch --verbose',
|
||||
{ cwd: path.join(root, 'project-a') },
|
||||
)
|
||||
await process.onStderr((message) => message.includes('Waiting for file changes...'))
|
||||
await spawn('pnpm postcss src/index.css --output dist/out.css --watch --verbose', {
|
||||
cwd: path.join(root, 'project-a'),
|
||||
})
|
||||
|
||||
await fs.expectFileToContain('project-a/dist/out.css', [
|
||||
candidate`underline`,
|
||||
|
|
|
|||
|
|
@ -1,3 +0,0 @@
|
|||
import { register } from 'node:module'
|
||||
|
||||
register(import.meta.resolve('@tailwindcss/cli/esm-loader'))
|
||||
|
|
@ -19,14 +19,10 @@
|
|||
"tailwindcss": "./dist/index.mjs"
|
||||
},
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
"./esm-hook": "./hook/esm.hook.mjs",
|
||||
"./esm-loader": "./hook/esm.loader.mjs",
|
||||
"./require-cache": "./hook/require-cache.cjs"
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
"hook"
|
||||
"dist"
|
||||
],
|
||||
"publishConfig": {
|
||||
"provenance": true,
|
||||
|
|
@ -34,13 +30,14 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@parcel/watcher": "^2.4.1",
|
||||
"@tailwindcss/node": "workspace:^",
|
||||
"@tailwindcss/oxide": "workspace:^",
|
||||
"enhanced-resolve": "^5.17.1",
|
||||
"lightningcss": "catalog:",
|
||||
"mri": "^1.2.0",
|
||||
"picocolors": "^1.0.1",
|
||||
"postcss": "^8.4.41",
|
||||
"postcss-import": "^16.1.0",
|
||||
"postcss": "^8.4.41",
|
||||
"tailwindcss": "workspace:^"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,8 @@
|
|||
import '@tailwindcss/node/esm-cache-hook'
|
||||
|
||||
import watcher from '@parcel/watcher'
|
||||
import { getModuleDependencies } from '@tailwindcss/node'
|
||||
import { clearRequireCache } from '@tailwindcss/node/require-cache'
|
||||
import { Scanner, type ChangedContent } from '@tailwindcss/oxide'
|
||||
import fixRelativePathsPlugin from 'internal-postcss-fix-relative-paths'
|
||||
import { Features, transform } from 'lightningcss'
|
||||
|
|
@ -11,7 +15,6 @@ import atImport from 'postcss-import'
|
|||
import * as tailwindcss from 'tailwindcss'
|
||||
import type { Arg, Result } from '../../utils/args'
|
||||
import { Disposables } from '../../utils/disposables'
|
||||
import { getModuleDependencies } from '../../utils/get-module-dependencies'
|
||||
import {
|
||||
eprintln,
|
||||
formatDuration,
|
||||
|
|
@ -23,10 +26,6 @@ import {
|
|||
import { resolveCssId } from '../../utils/resolve'
|
||||
import { drainStdin, outputFile } from './utils'
|
||||
|
||||
import '@tailwindcss/cli/esm-hook'
|
||||
// @ts-ignore
|
||||
import clearRequireCache from '@tailwindcss/cli/require-cache'
|
||||
|
||||
const css = String.raw
|
||||
|
||||
export function options() {
|
||||
|
|
@ -155,7 +154,6 @@ export async function handle(args: Result<ReturnType<typeof options>>) {
|
|||
return import(configPath).then((m) => m.default ?? m)
|
||||
}
|
||||
|
||||
console.log('RELOAD')
|
||||
let resolvedPath = path.resolve(inputBasePath, configPath)
|
||||
fullRebuildPaths.push(resolvedPath)
|
||||
fullRebuildPaths.push(...getModuleDependencies(resolvedPath))
|
||||
|
|
|
|||
40
packages/@tailwindcss-node/README.md
Normal file
40
packages/@tailwindcss-node/README.md
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
<p align="center">
|
||||
<a href="https://tailwindcss.com" target="_blank">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/tailwindlabs/tailwindcss/HEAD/.github/logo-dark.svg">
|
||||
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/tailwindlabs/tailwindcss/HEAD/.github/logo-light.svg">
|
||||
<img alt="Tailwind CSS" src="https://raw.githubusercontent.com/tailwindlabs/tailwindcss/HEAD/.github/logo-light.svg" width="350" height="70" style="max-width: 100%;">
|
||||
</picture>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
A utility-first CSS framework for rapidly building custom user interfaces.
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/tailwindlabs/tailwindcss/actions"><img src="https://img.shields.io/github/actions/workflow/status/tailwindlabs/tailwindcss/ci.yml?branch=next" alt="Build Status"></a>
|
||||
<a href="https://www.npmjs.com/package/tailwindcss"><img src="https://img.shields.io/npm/dt/tailwindcss.svg" alt="Total Downloads"></a>
|
||||
<a href="https://github.com/tailwindcss/tailwindcss/releases"><img src="https://img.shields.io/npm/v/tailwindcss.svg" alt="Latest Release"></a>
|
||||
<a href="https://github.com/tailwindcss/tailwindcss/blob/master/LICENSE"><img src="https://img.shields.io/npm/l/tailwindcss.svg" alt="License"></a>
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
## Documentation
|
||||
|
||||
For full documentation, visit [tailwindcss.com](https://tailwindcss.com).
|
||||
|
||||
## Community
|
||||
|
||||
For help, discussion about best practices, or any other conversation that would benefit from being searchable:
|
||||
|
||||
[Discuss Tailwind CSS on GitHub](https://github.com/tailwindcss/tailwindcss/discussions)
|
||||
|
||||
For chatting with others using the framework:
|
||||
|
||||
[Join the Tailwind CSS Discord Server](https://discord.gg/7NF8GNe)
|
||||
|
||||
## Contributing
|
||||
|
||||
If you're interested in contributing to Tailwind CSS, please read our [contributing docs](https://github.com/tailwindcss/tailwindcss/blob/next/.github/CONTRIBUTING.md) **before submitting a pull request**.
|
||||
43
packages/@tailwindcss-node/package.json
Normal file
43
packages/@tailwindcss-node/package.json
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
{
|
||||
"name": "@tailwindcss/node",
|
||||
"version": "4.0.0-alpha.19",
|
||||
"description": "A utility-first CSS framework for rapidly building custom user interfaces.",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/tailwindlabs/tailwindcss.git",
|
||||
"directory": "packages/@tailwindcss-node"
|
||||
},
|
||||
"bugs": "https://github.com/tailwindlabs/tailwindcss/issues",
|
||||
"homepage": "https://tailwindcss.com",
|
||||
"scripts": {
|
||||
"build": "tsup-node",
|
||||
"dev": "pnpm run build -- --watch"
|
||||
},
|
||||
"files": [
|
||||
"dist/"
|
||||
],
|
||||
"publishConfig": {
|
||||
"provenance": true,
|
||||
"access": "public"
|
||||
},
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.mjs",
|
||||
"import": "./dist/index.mjs",
|
||||
"require": "./dist/index.js"
|
||||
},
|
||||
"./require-cache": {
|
||||
"types": "./dist/require-cache.d.ts",
|
||||
"default": "./dist/require-cache.js"
|
||||
},
|
||||
"./esm-cache-hook": {
|
||||
"types": "./dist/esm-cache.hook.d.mts",
|
||||
"default": "./dist/esm-cache.hook.mjs"
|
||||
},
|
||||
"./esm-cache-loader": {
|
||||
"types": "./dist/esm-cache.loader.d.mts",
|
||||
"default": "./dist/esm-cache.loader.mjs"
|
||||
}
|
||||
}
|
||||
}
|
||||
8
packages/@tailwindcss-node/src/esm-cache.hook.mts
Normal file
8
packages/@tailwindcss-node/src/esm-cache.hook.mts
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
import { register } from 'node:module'
|
||||
import { pathToFileURL } from 'node:url'
|
||||
|
||||
if (typeof require === 'undefined') {
|
||||
register(import.meta.resolve('@tailwindcss/node/esm-cache-loader'))
|
||||
} else {
|
||||
register(pathToFileURL(require.resolve('@tailwindcss/node/esm-cache-loader')))
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import { isBuiltin } from 'node:module'
|
||||
import { isBuiltin, type ResolveHook } from 'node:module'
|
||||
|
||||
export async function resolve(specifier, context, nextResolve) {
|
||||
export let resolve: ResolveHook = async (specifier, context, nextResolve) => {
|
||||
const result = await nextResolve(specifier, context)
|
||||
|
||||
if (result.url === import.meta.url) return result
|
||||
|
|
@ -15,8 +15,6 @@ export async function resolve(specifier, context, nextResolve) {
|
|||
let url = new URL(result.url)
|
||||
url.searchParams.set('id', id)
|
||||
|
||||
console.log({ url })
|
||||
|
||||
return {
|
||||
...result,
|
||||
url: `${url}`,
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
import fs from 'node:fs'
|
||||
import path from 'node:path'
|
||||
|
||||
let jsExtensions = ['.js', '.cjs', '.mjs']
|
||||
|
||||
3
packages/@tailwindcss-node/src/index.ts
Normal file
3
packages/@tailwindcss-node/src/index.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
import './esm-cache.hook.mjs'
|
||||
|
||||
export * from './get-module-dependencies'
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
module.exports = function clearRequireCache() {
|
||||
export function clearRequireCache() {
|
||||
for (const key in require.cache) {
|
||||
delete require.cache[key]
|
||||
}
|
||||
3
packages/@tailwindcss-node/tsconfig.json
Normal file
3
packages/@tailwindcss-node/tsconfig.json
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"extends": "../tsconfig.base.json",
|
||||
}
|
||||
23
packages/@tailwindcss-node/tsup.config.ts
Normal file
23
packages/@tailwindcss-node/tsup.config.ts
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
import { defineConfig } from 'tsup'
|
||||
|
||||
export default defineConfig([
|
||||
{
|
||||
format: ['cjs', 'esm'],
|
||||
minify: true,
|
||||
dts: true,
|
||||
entry: ['src/index.ts'],
|
||||
},
|
||||
{
|
||||
format: ['esm'],
|
||||
minify: true,
|
||||
dts: true,
|
||||
entry: ['src/esm-cache.hook.mts', 'src/esm-cache.loader.mts'],
|
||||
},
|
||||
|
||||
{
|
||||
format: ['cjs'],
|
||||
minify: true,
|
||||
dts: true,
|
||||
entry: ['src/require-cache.cts'],
|
||||
},
|
||||
])
|
||||
|
|
@ -30,6 +30,7 @@
|
|||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@tailwindcss/node": "workspace:^",
|
||||
"@tailwindcss/oxide": "workspace:^",
|
||||
"lightningcss": "catalog:",
|
||||
"postcss-import": "^16.1.0",
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import { getModuleDependencies } from '@tailwindcss/node'
|
||||
// import '@tailwindcss/node/esm-cache-hook'
|
||||
import { Scanner } from '@tailwindcss/oxide'
|
||||
import fs from 'fs'
|
||||
import fixRelativePathsPlugin from 'internal-postcss-fix-relative-paths'
|
||||
|
|
@ -47,6 +49,7 @@ function tailwindcss(opts: PluginOptions = {}): AcceptedPlugin {
|
|||
compiler: null as null | Awaited<ReturnType<typeof compile>>,
|
||||
css: '',
|
||||
optimizedCss: '',
|
||||
fullRebuildPaths: [] as string[],
|
||||
}
|
||||
})
|
||||
|
||||
|
|
@ -80,25 +83,32 @@ function tailwindcss(opts: PluginOptions = {}): AcceptedPlugin {
|
|||
let inputBasePath = path.dirname(path.resolve(inputFile))
|
||||
|
||||
function createCompiler() {
|
||||
context.fullRebuildPaths = []
|
||||
return compile(root.toString(), {
|
||||
loadPlugin: async (pluginPath) => {
|
||||
if (pluginPath[0] === '.') {
|
||||
return import(pathToFileURL(path.resolve(inputBasePath, pluginPath)).href).then(
|
||||
(m) => m.default ?? m,
|
||||
)
|
||||
if (pluginPath[0] !== '.') {
|
||||
return import(pluginPath).then((m) => m.default ?? m)
|
||||
}
|
||||
|
||||
return import(pluginPath).then((m) => m.default ?? m)
|
||||
let resolvedPath = path.resolve(inputBasePath, pluginPath)
|
||||
context.fullRebuildPaths.push(resolvedPath)
|
||||
context.fullRebuildPaths.push(...getModuleDependencies(resolvedPath))
|
||||
return import(pathToFileURL(resolvedPath).href + '?id=' + Date.now()).then(
|
||||
(m) => m.default ?? m,
|
||||
)
|
||||
},
|
||||
|
||||
loadConfig: async (configPath) => {
|
||||
if (configPath[0] === '.') {
|
||||
return import(pathToFileURL(path.resolve(inputBasePath, configPath)).href).then(
|
||||
(m) => m.default ?? m,
|
||||
)
|
||||
if (configPath[0] !== '.') {
|
||||
return import(configPath).then((m) => m.default ?? m)
|
||||
}
|
||||
|
||||
return import(configPath).then((m) => m.default ?? m)
|
||||
let resolvedPath = path.resolve(inputBasePath, configPath)
|
||||
context.fullRebuildPaths.push(resolvedPath)
|
||||
context.fullRebuildPaths.push(...getModuleDependencies(resolvedPath))
|
||||
return import(pathToFileURL(resolvedPath).href + '?id=' + Date.now()).then(
|
||||
(m) => m.default ?? m,
|
||||
)
|
||||
},
|
||||
})
|
||||
}
|
||||
|
|
@ -111,11 +121,23 @@ function tailwindcss(opts: PluginOptions = {}): AcceptedPlugin {
|
|||
|
||||
// Track file modification times to CSS files
|
||||
{
|
||||
// console.log({ fullRebuildPaths: context.fullRebuildPaths })
|
||||
for (let file of context.fullRebuildPaths) {
|
||||
result.messages.push({
|
||||
type: 'dependency',
|
||||
plugin: '@tailwindcss/postcss',
|
||||
file,
|
||||
parent: result.opts.from,
|
||||
})
|
||||
}
|
||||
|
||||
let files = result.messages.flatMap((message) => {
|
||||
if (message.type !== 'dependency') return []
|
||||
return message.file
|
||||
})
|
||||
files.push(inputFile)
|
||||
// console.log({ files })
|
||||
|
||||
for (let file of files) {
|
||||
let changedTime = fs.statSync(file, { throwIfNoEntry: false })?.mtimeMs ?? null
|
||||
if (changedTime === null) {
|
||||
|
|
|
|||
8
pnpm-lock.yaml
generated
8
pnpm-lock.yaml
generated
|
|
@ -138,6 +138,9 @@ importers:
|
|||
'@parcel/watcher':
|
||||
specifier: ^2.4.1
|
||||
version: 2.4.1(patch_hash=pnjyuz76kbyy7yxsvyvmenfmha)
|
||||
'@tailwindcss/node':
|
||||
specifier: workspace:^
|
||||
version: link:../@tailwindcss-node
|
||||
'@tailwindcss/oxide':
|
||||
specifier: workspace:^
|
||||
version: link:../../crates/node
|
||||
|
|
@ -170,8 +173,13 @@ importers:
|
|||
specifier: workspace:^
|
||||
version: link:../internal-postcss-fix-relative-paths
|
||||
|
||||
packages/@tailwindcss-node: {}
|
||||
|
||||
packages/@tailwindcss-postcss:
|
||||
dependencies:
|
||||
'@tailwindcss/node':
|
||||
specifier: workspace:^
|
||||
version: link:../@tailwindcss-node
|
||||
'@tailwindcss/oxide':
|
||||
specifier: workspace:^
|
||||
version: link:../../crates/node
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue