Skip to content

Commit 3682d72

Browse files
Reload v4 design system when dependencies change (#1119)
I noticed that editing imported CSS files, plugins, and configs in v4 the config wasn't reloading. This PR fixes that by making sure we reload when any of them change.
1 parent 001791a commit 3682d72

File tree

5 files changed

+51
-7
lines changed

5 files changed

+51
-7
lines changed

packages/tailwindcss-language-server/src/projects.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ export interface ProjectService {
110110
onDocumentLinks(params: DocumentLinkParams): DocumentLink[]
111111
sortClassLists(classLists: string[]): string[]
112112

113+
dependencies(): Iterable<string>
113114
reload(): Promise<void>
114115
}
115116

@@ -186,6 +187,11 @@ export async function createProjectService(
186187
getConfiguration: (uri?: string) => Promise<Settings>,
187188
userLanguages: Record<string, string>,
188189
): Promise<ProjectService> {
190+
/* Project dependencies require a design system reload */
191+
let dependencies = new Set<string>()
192+
193+
dependencies.add(projectConfig.configPath)
194+
189195
let enabled = false
190196
const folder = projectConfig.folder
191197
const disposables: Array<Disposable | Promise<Disposable>> = []
@@ -757,6 +763,14 @@ export async function createProjectService(
757763

758764
state.designSystem = designSystem
759765

766+
let deps = designSystem.dependencies()
767+
768+
for (let dep of deps) {
769+
dependencies.add(dep)
770+
}
771+
772+
watchPatterns(Array.from(deps))
773+
760774
originalConfig = { theme: {} }
761775
} catch {
762776
// TODO: Fall back to built-in v4 stuff
@@ -987,6 +1001,14 @@ export async function createProjectService(
9871001
updateCapabilities()
9881002
}
9891003

1004+
for (let entry of projectConfig.config.entries) {
1005+
dependencies.add(entry.path)
1006+
1007+
for (let dep of entry.deps) {
1008+
dependencies.add(dep.path)
1009+
}
1010+
}
1011+
9901012
return {
9911013
projectConfig,
9921014
enabled() {
@@ -996,6 +1018,7 @@ export async function createProjectService(
9961018
enabled = true
9971019
},
9981020

1021+
dependencies: () => dependencies,
9991022
async reload() {
10001023
if (!state.v4) return
10011024

@@ -1029,6 +1052,18 @@ export async function createProjectService(
10291052
state.classList = classList
10301053
state.variants = getVariants(state)
10311054

1055+
let deps = designSystem.dependencies()
1056+
1057+
for (let dep of deps) {
1058+
dependencies.add(dep)
1059+
}
1060+
1061+
watchPatterns(Array.from(deps))
1062+
1063+
// Update capabilities to force color swatches to update across editors
1064+
// TODO: Need to verify how well this works across various editors
1065+
// updateCapabilities()
1066+
10321067
console.log('---- RELOADED ----')
10331068
},
10341069

packages/tailwindcss-language-server/src/tw.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -331,12 +331,7 @@ export class TW {
331331
for (let [, project] of this.projects) {
332332
if (!project.state.v4) continue
333333

334-
let reloadableFiles = [
335-
project.projectConfig.configPath,
336-
...project.projectConfig.config.entries.map((entry) => entry.path),
337-
]
338-
339-
if (!changeAffectsFile(normalizedFilename, reloadableFiles)) continue
334+
if (!changeAffectsFile(normalizedFilename, project.dependencies())) continue
340335

341336
needsSoftRestart = true
342337
break changeLoop

packages/tailwindcss-language-server/src/util/v4/design-system.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,12 @@ async function importFile(id: string) {
4444
* everything from working so we'll let the error handler decide how to proceed.
4545
*/
4646
function createLoader<T>({
47+
dependencies,
4748
legacy,
4849
filepath,
4950
onError,
5051
}: {
52+
dependencies: Set<string>
5153
legacy: boolean
5254
filepath: string
5355
onError: (id: string, error: unknown, resourceType: string) => T
@@ -58,6 +60,8 @@ function createLoader<T>({
5860
try {
5961
let resolved = resolveFrom(base, id)
6062

63+
dependencies.add(resolved)
64+
6165
let url = pathToFileURL(resolved)
6266
url.searchParams.append('t', cacheKey)
6367

@@ -93,6 +97,8 @@ export async function loadDesignSystem(
9397
return null
9498
}
9599

100+
let dependencies = new Set<string>()
101+
96102
let supportsImports = false
97103
try {
98104
await tailwindcss.__unstable__loadDesignSystem(css, {
@@ -115,6 +121,7 @@ export async function loadDesignSystem(
115121

116122
// v4.0.0-alpha.25+
117123
loadModule: createLoader({
124+
dependencies,
118125
legacy: false,
119126
filepath,
120127
onError: (id, err, resourceType) => {
@@ -131,6 +138,8 @@ export async function loadDesignSystem(
131138
loadStylesheet: async (id: string, base: string) => {
132139
let resolved = resolveCssFrom(base, id)
133140

141+
dependencies.add(resolved)
142+
134143
return {
135144
base: path.dirname(resolved),
136145
content: await fs.readFile(resolved, 'utf-8'),
@@ -139,6 +148,7 @@ export async function loadDesignSystem(
139148

140149
// v4.0.0-alpha.24 and below
141150
loadPlugin: createLoader({
151+
dependencies,
142152
legacy: true,
143153
filepath,
144154
onError(id, err) {
@@ -149,6 +159,7 @@ export async function loadDesignSystem(
149159
}),
150160

151161
loadConfig: createLoader({
162+
dependencies,
152163
legacy: true,
153164
filepath,
154165
onError(id, err) {
@@ -161,6 +172,8 @@ export async function loadDesignSystem(
161172

162173
// Step 4: Augment the design system with some additional APIs that the LSP needs
163174
Object.assign(design, {
175+
dependencies: () => dependencies,
176+
164177
compile(classes: string[]): (postcss.Root | null)[] {
165178
let css = design.candidatesToCss(classes)
166179
let errors: any[] = []

packages/tailwindcss-language-server/src/utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ export function normalizeDriveLetter(filepath: string) {
8484
return filepath.replace(WIN_DRIVE_LETTER, (_, letter) => letter.toUpperCase() + ':')
8585
}
8686

87-
export function changeAffectsFile(change: string, files: string[]): boolean {
87+
export function changeAffectsFile(change: string, files: Iterable<string>): boolean {
8888
for (let file of files) {
8989
if (change === file || dirContains(change, file)) {
9090
return true

packages/tailwindcss-language-service/src/util/v4/design-system.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ export interface DesignSystem {
4343
}
4444

4545
export interface DesignSystem {
46+
dependencies(): Set<string>
4647
compile(classes: string[]): postcss.Root[]
4748
toCss(nodes: postcss.Root | postcss.Node[]): string
4849
}

0 commit comments

Comments
 (0)