Skip to content

Commit 15e8009

Browse files
Add support for @plugin and @config in v4 (#316)
* Support `@plugin` and `@config` in v4 * Rework fixture installation script * Add basic v4 test * Add v4 configs test * Update changelog
1 parent 9844623 commit 15e8009

17 files changed

+167
-17
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
88
## [Unreleased]
99

1010
- Improved performance with large Svelte, Liquid, and Angular files ([#312](https://github.com/tailwindlabs/prettier-plugin-tailwindcss/pull/312))
11+
- Add support for @plugin and @config in v4 ([#316](https://github.com/tailwindlabs/prettier-plugin-tailwindcss/pull/316))
1112

1213
## [0.6.6] - 2024-08-09
1314

scripts/install-fixture-deps.js

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,23 @@ import * as fs from 'node:fs/promises'
33
import * as path from 'node:path'
44
import { fileURLToPath } from 'node:url'
55
import { promisify } from 'node:util'
6-
7-
const execAsync = promisify(exec)
6+
import glob from 'fast-glob'
87

98
const __dirname = path.dirname(fileURLToPath(import.meta.url))
109

11-
let fixturesDir = path.resolve(__dirname, '../tests/fixtures')
12-
let fixtureDirs = await fs.readdir(fixturesDir)
13-
let fixtures = fixtureDirs.map((name) => path.join(fixturesDir, name))
10+
const fixtures = glob.sync(
11+
['tests/fixtures/*/package.json', 'tests/fixtures/v4/*/package.json'],
12+
{
13+
cwd: path.resolve(__dirname, '..'),
14+
},
15+
)
16+
17+
const execAsync = promisify(exec)
1418

1519
await Promise.all(
1620
fixtures.map(async (fixture) => {
17-
let exists = await fs.access(path.join(fixture, 'package.json')).then(
18-
() => true,
19-
() => false,
20-
)
21-
22-
if (!exists) return
23-
2421
console.log(`Installing dependencies for ${fixture}`)
2522

26-
await execAsync('npm install', { cwd: fixture })
23+
await execAsync('npm install', { cwd: path.dirname(fixture) })
2724
}),
2825
)

src/config.ts

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import loadConfigFallback from 'tailwindcss/loadConfig'
1818
import resolveConfigFallback from 'tailwindcss/resolveConfig'
1919
import type { RequiredConfig } from 'tailwindcss/types/config.js'
2020
import { expiringMap } from './expiring-map.js'
21-
import { resolveIn } from './resolve'
21+
import { resolveFrom, resolveIn } from './resolve'
2222
import type { ContextContainer } from './types'
2323

2424
let localRequire = createRequire(import.meta.url)
@@ -147,6 +147,37 @@ async function loadTailwindConfig(
147147
}
148148
}
149149

150+
/**
151+
* Create a loader function that can load plugins and config files relative to
152+
* the CSS file that uses them. However, we don't want missing files to prevent
153+
* everything from working so we'll let the error handler decide how to proceed.
154+
*
155+
* @param {object} param0
156+
* @returns
157+
*/
158+
function createLoader<T>({
159+
filepath,
160+
onError,
161+
}: {
162+
filepath: string
163+
onError: (id: string, error: unknown) => T
164+
}) {
165+
let baseDir = path.dirname(filepath)
166+
let cacheKey = `${+Date.now()}`
167+
168+
return async function loadFile(id: string) {
169+
try {
170+
let resolved = resolveFrom(baseDir, id)
171+
let url = pathToFileURL(resolved)
172+
url.searchParams.append('t', cacheKey)
173+
174+
return await import(url.href).then((m) => m.default ?? m)
175+
} catch (err) {
176+
return onError(id, err)
177+
}
178+
}
179+
}
180+
150181
async function loadV4(
151182
baseDir: string,
152183
pkgDir: string,
@@ -172,9 +203,23 @@ async function loadV4(
172203
// Load the design system and set up a compatible context object that is
173204
// usable by the rest of the plugin
174205
let design = await tw.__unstable__loadDesignSystem(result.css, {
175-
loadPlugin() {
176-
return () => {}
177-
},
206+
loadPlugin: createLoader({
207+
filepath: entryPoint,
208+
onError(id, err) {
209+
console.error(`Unable to load plugin: ${id}`, err)
210+
211+
return () => {}
212+
},
213+
}),
214+
215+
loadConfig: createLoader({
216+
filepath: entryPoint,
217+
onError(id, err) {
218+
console.error(`Unable to load config: ${id}`, err)
219+
220+
return {}
221+
},
222+
}),
178223
})
179224

180225
return {

src/resolve.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { createRequire as req } from 'node:module'
2+
import resolveFrom from 'resolve-from'
23
import { expiringMap } from './expiring-map'
34

45
const localRequire = req(import.meta.url)
@@ -45,3 +46,5 @@ function freshMaybeResolve(name: string) {
4546
return null
4647
}
4748
}
49+
50+
export { resolveFrom }

tests/fixtures.test.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,17 @@ let fixtures = [
6262
dir: 'custom-jsx',
6363
ext: 'jsx',
6464
},
65+
66+
{
67+
name: 'v4: basic formatting',
68+
dir: 'v4/basic',
69+
ext: 'html',
70+
},
71+
{
72+
name: 'v4: configs and plugins',
73+
dir: 'v4/configs',
74+
ext: 'html',
75+
},
6576
]
6677

6778
let configs = [

tests/fixtures/v4/basic/app.css

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
@import 'tailwindcss';
2+
3+
@theme {
4+
--color-tomato: tomato;
5+
}

tests/fixtures/v4/basic/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<div class="sm:bg-tomato bg-red-500"></div>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<div class="bg-red-500 sm:bg-tomato"></div>

tests/fixtures/v4/basic/package-lock.json

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"dependencies": {
3+
"tailwindcss": "^4.0.0-alpha.23"
4+
},
5+
"prettier": {
6+
"tailwindEntryPoint": "./app.css"
7+
}
8+
}

0 commit comments

Comments
 (0)