Skip to content

Commit 8b1bf80

Browse files
CLI: Ignore watch events for files that don't match globs (#9215)
* Don’t re-add files in the CLI watcher that are covered by dynamic patterns They don’t have the same problem. As long as the parent directory is watched their add/change events will fire correctly * Ignore raw events for files that don’t match the content files * fixup * Update changelog
1 parent edf47a0 commit 8b1bf80

File tree

2 files changed

+35
-4
lines changed

2 files changed

+35
-4
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2121
- Sort tags before classes when `@applying` a selector with joined classes ([#9107](https://github.com/tailwindlabs/tailwindcss/pull/9107))
2222
- Remove invalid `outline-hidden` utility ([#9147](https://github.com/tailwindlabs/tailwindcss/pull/9147))
2323
- Honor the `hidden` attribute on elements in preflight ([#9174](https://github.com/tailwindlabs/tailwindcss/pull/9174))
24-
- Don't stop watching atomically renamed files ([#9173](https://github.com/tailwindlabs/tailwindcss/pull/9173))
24+
- Don't stop watching atomically renamed files ([#9173](https://github.com/tailwindlabs/tailwindcss/pull/9173), [#9215](https://github.com/tailwindlabs/tailwindcss/pull/9215))
2525
- Re-use existing entries in the rule cache ([#9208](https://github.com/tailwindlabs/tailwindcss/pull/9208))
2626
- Don't output duplicate utilities ([#9208](https://github.com/tailwindlabs/tailwindcss/pull/9208))
2727
- Fix `fontFamily` config TypeScript types ([#9214](https://github.com/tailwindlabs/tailwindcss/pull/9214))

src/cli.js

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import getModuleDependencies from './lib/getModuleDependencies'
1717
import log from './util/log'
1818
import packageJson from '../package.json'
1919
import normalizePath from 'normalize-path'
20+
import micromatch from 'micromatch'
2021
import { validateConfig } from './util/validateConfig.js'
2122

2223
let env = {
@@ -837,6 +838,23 @@ async function build() {
837838
}
838839

839840
let config = refreshConfig(configPath)
841+
let contentPatterns = refreshContentPatterns(config)
842+
843+
/**
844+
* @param {import('../types/config.js').RequiredConfig} config
845+
* @return {{all: string[], dynamic: string[], static: string[]}}
846+
**/
847+
function refreshContentPatterns(config) {
848+
let globs = extractFileGlobs(config)
849+
let tasks = fastGlob.generateTasks(globs, { absolute: true })
850+
let dynamicPatterns = tasks.filter((task) => task.dynamic).flatMap((task) => task.patterns)
851+
let staticPatterns = tasks.filter((task) => !task.dynamic).flatMap((task) => task.patterns)
852+
853+
return {
854+
all: [...staticPatterns, ...dynamicPatterns],
855+
dynamic: dynamicPatterns,
856+
}
857+
}
840858

841859
if (input) {
842860
contextDependencies.add(path.resolve(input))
@@ -867,6 +885,7 @@ async function build() {
867885
env.DEBUG && console.time('Resolve config')
868886
context = null
869887
config = refreshConfig(configPath)
888+
contentPatterns = refreshContentPatterns(config)
870889
env.DEBUG && console.timeEnd('Resolve config')
871890

872891
env.DEBUG && console.time('Watch new files')
@@ -924,7 +943,14 @@ async function build() {
924943
// Restore watching any files that are "removed"
925944
// This can happen when a file is pseudo-atomically replaced (a copy is created, overwritten, the old one is unlinked, and the new one is renamed)
926945
// TODO: An an optimization we should allow removal when the config changes
927-
watcher.on('unlink', (file) => watcher.add(file))
946+
watcher.on('unlink', (file) => {
947+
file = normalizePath(file)
948+
949+
// Only re-add the file if it's not covered by a dynamic pattern
950+
if (!micromatch.some([file], contentPatterns.dynamic)) {
951+
watcher.add(file)
952+
}
953+
})
928954

929955
// Some applications such as Visual Studio (but not VS Code)
930956
// will only fire a rename event for atomic writes and not a change event
@@ -935,11 +961,16 @@ async function build() {
935961
return
936962
}
937963

938-
let watchedPath = path.resolve(meta.watchedPath)
964+
let watchedPath = meta.watchedPath
939965

940966
// Watched path might be the file itself
941967
// Or the directory it is in
942-
filePath = watchedPath.endsWith(filePath) ? watchedPath : path.resolve(watchedPath, filePath)
968+
filePath = watchedPath.endsWith(filePath) ? watchedPath : path.join(watchedPath, filePath)
969+
970+
// Skip this event since the files it is for does not match any of the registered content globs
971+
if (!micromatch.some([filePath], contentPatterns.all)) {
972+
return
973+
}
943974

944975
// Skip since we've already queued a rebuild for this file that hasn't happened yet
945976
if (pendingRebuilds.has(filePath)) {

0 commit comments

Comments
 (0)