mirror of
https://github.com/tailwindlabs/tailwindcss.git
synced 2025-12-08 21:36:08 +00:00
Allow @plugin and @config to point to TS files (#14317)
Tailwind V3 used [jiti](https://github.com/unjs/jiti/) to allow importing of TypeScript files for the config and plugins. This PR adds the new Jiti V2 beta to our `@tailwindcss/node` and uses it if a native `import()` fails. I added a new integration test to the CLI config setup, to ensure it still works with our module cache cleanup.
This commit is contained in:
parent
191c544c67
commit
390e2d3e8d
@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
|
||||
- Support TypeScript for `@plugin` and `@config` files ([#14317](https://github.com/tailwindlabs/tailwindcss/pull/14317))
|
||||
|
||||
### Fixed
|
||||
|
||||
- Ensure content globs defined in `@config` files are relative to that file ([#14314](https://github.com/tailwindlabs/tailwindcss/pull/14314))
|
||||
|
||||
@ -84,6 +84,48 @@ test(
|
||||
},
|
||||
)
|
||||
|
||||
test(
|
||||
'Config files (TS)',
|
||||
{
|
||||
fs: {
|
||||
'package.json': json`
|
||||
{
|
||||
"dependencies": {
|
||||
"tailwindcss": "workspace:^",
|
||||
"@tailwindcss/cli": "workspace:^"
|
||||
}
|
||||
}
|
||||
`,
|
||||
'index.html': html`
|
||||
<div class="text-primary"></div>
|
||||
`,
|
||||
'tailwind.config.ts': js`
|
||||
export default {
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
primary: 'blue',
|
||||
},
|
||||
},
|
||||
},
|
||||
} satisfies { theme: { extend: { colors: { primary: string } } } }
|
||||
`,
|
||||
'src/index.css': css`
|
||||
@import 'tailwindcss';
|
||||
@config '../tailwind.config.ts';
|
||||
`,
|
||||
},
|
||||
},
|
||||
async ({ fs, exec }) => {
|
||||
await exec('pnpm tailwindcss --input src/index.css --output dist/out.css')
|
||||
|
||||
await fs.expectFileToContain('dist/out.css', [
|
||||
//
|
||||
candidate`text-primary`,
|
||||
])
|
||||
},
|
||||
)
|
||||
|
||||
test(
|
||||
'Config files (CJS, watch mode)',
|
||||
{
|
||||
@ -138,7 +180,7 @@ test(
|
||||
)
|
||||
|
||||
test(
|
||||
'Config files (MJS, watch mode)',
|
||||
'Config files (ESM, watch mode)',
|
||||
{
|
||||
fs: {
|
||||
'package.json': json`
|
||||
@ -189,3 +231,56 @@ test(
|
||||
])
|
||||
},
|
||||
)
|
||||
|
||||
test(
|
||||
'Config files (TS, watch mode)',
|
||||
{
|
||||
fs: {
|
||||
'package.json': json`
|
||||
{
|
||||
"dependencies": {
|
||||
"tailwindcss": "workspace:^",
|
||||
"@tailwindcss/cli": "workspace:^"
|
||||
}
|
||||
}
|
||||
`,
|
||||
'index.html': html`
|
||||
<div class="text-primary"></div>
|
||||
`,
|
||||
'tailwind.config.ts': js`
|
||||
import myColor from './my-color.ts'
|
||||
export default {
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
primary: myColor,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
`,
|
||||
'my-color.ts': js`export default 'blue'`,
|
||||
'src/index.css': css`
|
||||
@import 'tailwindcss';
|
||||
@config '../tailwind.config.ts';
|
||||
`,
|
||||
},
|
||||
},
|
||||
async ({ fs, spawn }) => {
|
||||
await spawn('pnpm tailwindcss --input src/index.css --output dist/out.css --watch')
|
||||
|
||||
await fs.expectFileToContain('dist/out.css', [
|
||||
//
|
||||
candidate`text-primary`,
|
||||
'color: blue',
|
||||
])
|
||||
|
||||
await fs.write('my-color.ts', js`export default 'red'`)
|
||||
|
||||
await fs.expectFileToContain('dist/out.css', [
|
||||
//
|
||||
candidate`text-primary`,
|
||||
'color: red',
|
||||
])
|
||||
},
|
||||
)
|
||||
|
||||
@ -38,5 +38,8 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"tailwindcss": "workspace:^"
|
||||
},
|
||||
"dependencies": {
|
||||
"jiti": "^2.0.0-beta.3"
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { createJiti, type Jiti } from 'jiti'
|
||||
import path from 'node:path'
|
||||
import { pathToFileURL } from 'node:url'
|
||||
import { compile as _compile } from 'tailwindcss'
|
||||
@ -10,12 +11,12 @@ export async function compile(
|
||||
return await _compile(css, {
|
||||
loadPlugin: async (pluginPath) => {
|
||||
if (pluginPath[0] !== '.') {
|
||||
return import(pluginPath).then((m) => m.default ?? m)
|
||||
return importModule(pluginPath).then((m) => m.default ?? m)
|
||||
}
|
||||
|
||||
let resolvedPath = path.resolve(base, pluginPath)
|
||||
let [module, moduleDependencies] = await Promise.all([
|
||||
import(pathToFileURL(resolvedPath).href + '?id=' + Date.now()),
|
||||
importModule(pathToFileURL(resolvedPath).href + '?id=' + Date.now()),
|
||||
getModuleDependencies(resolvedPath),
|
||||
])
|
||||
|
||||
@ -28,12 +29,12 @@ export async function compile(
|
||||
|
||||
loadConfig: async (configPath) => {
|
||||
if (configPath[0] !== '.') {
|
||||
return import(configPath).then((m) => m.default ?? m)
|
||||
return importModule(configPath).then((m) => m.default ?? m)
|
||||
}
|
||||
|
||||
let resolvedPath = path.resolve(base, configPath)
|
||||
let [module, moduleDependencies] = await Promise.all([
|
||||
import(pathToFileURL(resolvedPath).href + '?id=' + Date.now()),
|
||||
importModule(pathToFileURL(resolvedPath).href + '?id=' + Date.now()),
|
||||
getModuleDependencies(resolvedPath),
|
||||
])
|
||||
|
||||
@ -45,3 +46,19 @@ export async function compile(
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// Attempts to import the module using the native `import()` function. If this
|
||||
// fails, it sets up `jiti` and attempts to import this way so that `.ts` files
|
||||
// can be resolved properly.
|
||||
let jiti: null | Jiti = null
|
||||
async function importModule(path: string): Promise<any> {
|
||||
try {
|
||||
return await import(path)
|
||||
} catch (error) {
|
||||
try {
|
||||
jiti ??= createJiti(import.meta.url, { moduleCache: false, fsCache: false })
|
||||
return await jiti.import(path)
|
||||
} catch {}
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
10
pnpm-lock.yaml
generated
10
pnpm-lock.yaml
generated
@ -174,6 +174,10 @@ importers:
|
||||
version: link:../internal-postcss-fix-relative-paths
|
||||
|
||||
packages/@tailwindcss-node:
|
||||
dependencies:
|
||||
jiti:
|
||||
specifier: ^2.0.0-beta.3
|
||||
version: 2.0.0-beta.3
|
||||
devDependencies:
|
||||
tailwindcss:
|
||||
specifier: workspace:^
|
||||
@ -2127,6 +2131,10 @@ packages:
|
||||
resolution: {integrity: sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==}
|
||||
hasBin: true
|
||||
|
||||
jiti@2.0.0-beta.3:
|
||||
resolution: {integrity: sha512-pmfRbVRs/7khFrSAYnSiJ8C0D5GvzkE4Ey2pAvUcJsw1ly/p+7ut27jbJrjY79BpAJQJ4gXYFtK6d1Aub+9baQ==}
|
||||
hasBin: true
|
||||
|
||||
joycon@3.1.1:
|
||||
resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==}
|
||||
engines: {node: '>=10'}
|
||||
@ -4892,6 +4900,8 @@ snapshots:
|
||||
jiti@1.21.6:
|
||||
optional: true
|
||||
|
||||
jiti@2.0.0-beta.3: {}
|
||||
|
||||
joycon@3.1.1: {}
|
||||
|
||||
js-tokens@4.0.0: {}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user