diff --git a/integrations/postcss/config.test.ts b/integrations/postcss/config.test.ts index 6ea7f27f8..b81924e0c 100644 --- a/integrations/postcss/config.test.ts +++ b/integrations/postcss/config.test.ts @@ -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` +
+ `, + '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` + + `, + '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', + ]) + }, +) diff --git a/integrations/postcss/index.test.ts b/integrations/postcss/index.test.ts index 61948ca74..9ac472a64 100644 --- a/integrations/postcss/index.test.ts +++ b/integrations/postcss/index.test.ts @@ -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`, diff --git a/packages/@tailwindcss-cli/hook/esm.hook.mjs b/packages/@tailwindcss-cli/hook/esm.hook.mjs deleted file mode 100644 index bde8538b0..000000000 --- a/packages/@tailwindcss-cli/hook/esm.hook.mjs +++ /dev/null @@ -1,3 +0,0 @@ -import { register } from 'node:module' - -register(import.meta.resolve('@tailwindcss/cli/esm-loader')) diff --git a/packages/@tailwindcss-cli/package.json b/packages/@tailwindcss-cli/package.json index 944fdb2ca..ded459fb8 100644 --- a/packages/@tailwindcss-cli/package.json +++ b/packages/@tailwindcss-cli/package.json @@ -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": { diff --git a/packages/@tailwindcss-cli/src/commands/build/index.ts b/packages/@tailwindcss-cli/src/commands/build/index.ts index c5db54c46..b6f21a485 100644 --- a/packages/@tailwindcss-cli/src/commands/build/index.ts +++ b/packages/@tailwindcss-cli/src/commands/build/index.ts @@ -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
+
+
+
+ A utility-first CSS framework for rapidly building custom user interfaces. +
+ + + +--- + +## 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**. diff --git a/packages/@tailwindcss-node/package.json b/packages/@tailwindcss-node/package.json new file mode 100644 index 000000000..510a6edec --- /dev/null +++ b/packages/@tailwindcss-node/package.json @@ -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" + } + } +} diff --git a/packages/@tailwindcss-node/src/esm-cache.hook.mts b/packages/@tailwindcss-node/src/esm-cache.hook.mts new file mode 100644 index 000000000..a3ea7b424 --- /dev/null +++ b/packages/@tailwindcss-node/src/esm-cache.hook.mts @@ -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'))) +} diff --git a/packages/@tailwindcss-cli/hook/esm.loader.mjs b/packages/@tailwindcss-node/src/esm-cache.loader.mts similarity index 75% rename from packages/@tailwindcss-cli/hook/esm.loader.mjs rename to packages/@tailwindcss-node/src/esm-cache.loader.mts index b7508c778..1f06423f9 100644 --- a/packages/@tailwindcss-cli/hook/esm.loader.mjs +++ b/packages/@tailwindcss-node/src/esm-cache.loader.mts @@ -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}`, diff --git a/packages/@tailwindcss-cli/src/utils/get-module-dependencies.ts b/packages/@tailwindcss-node/src/get-module-dependencies.ts similarity index 97% rename from packages/@tailwindcss-cli/src/utils/get-module-dependencies.ts rename to packages/@tailwindcss-node/src/get-module-dependencies.ts index 592306641..9683918de 100644 --- a/packages/@tailwindcss-cli/src/utils/get-module-dependencies.ts +++ b/packages/@tailwindcss-node/src/get-module-dependencies.ts @@ -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'] diff --git a/packages/@tailwindcss-node/src/index.ts b/packages/@tailwindcss-node/src/index.ts new file mode 100644 index 000000000..bb701e042 --- /dev/null +++ b/packages/@tailwindcss-node/src/index.ts @@ -0,0 +1,3 @@ +import './esm-cache.hook.mjs' + +export * from './get-module-dependencies' diff --git a/packages/@tailwindcss-cli/hook/require-cache.cjs b/packages/@tailwindcss-node/src/require-cache.cts similarity index 60% rename from packages/@tailwindcss-cli/hook/require-cache.cjs rename to packages/@tailwindcss-node/src/require-cache.cts index d073d8701..96f8f0e0e 100644 --- a/packages/@tailwindcss-cli/hook/require-cache.cjs +++ b/packages/@tailwindcss-node/src/require-cache.cts @@ -1,4 +1,4 @@ -module.exports = function clearRequireCache() { +export function clearRequireCache() { for (const key in require.cache) { delete require.cache[key] } diff --git a/packages/@tailwindcss-node/tsconfig.json b/packages/@tailwindcss-node/tsconfig.json new file mode 100644 index 000000000..6ae022f65 --- /dev/null +++ b/packages/@tailwindcss-node/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "../tsconfig.base.json", +} diff --git a/packages/@tailwindcss-node/tsup.config.ts b/packages/@tailwindcss-node/tsup.config.ts new file mode 100644 index 000000000..b1743944e --- /dev/null +++ b/packages/@tailwindcss-node/tsup.config.ts @@ -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'], + }, +]) diff --git a/packages/@tailwindcss-postcss/package.json b/packages/@tailwindcss-postcss/package.json index f5799c934..0258f48b6 100644 --- a/packages/@tailwindcss-postcss/package.json +++ b/packages/@tailwindcss-postcss/package.json @@ -30,6 +30,7 @@ } }, "dependencies": { + "@tailwindcss/node": "workspace:^", "@tailwindcss/oxide": "workspace:^", "lightningcss": "catalog:", "postcss-import": "^16.1.0", diff --git a/packages/@tailwindcss-postcss/src/index.ts b/packages/@tailwindcss-postcss/src/index.ts index f01c8e32a..8ca907e29 100644 --- a/packages/@tailwindcss-postcss/src/index.ts +++ b/packages/@tailwindcss-postcss/src/index.ts @@ -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