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
This commit is contained in:
parent
edf47a012d
commit
8b1bf8006d
2 changed files with 35 additions and 4 deletions
|
|
@ -21,7 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- Sort tags before classes when `@applying` a selector with joined classes ([#9107](https://github.com/tailwindlabs/tailwindcss/pull/9107))
|
||||
- Remove invalid `outline-hidden` utility ([#9147](https://github.com/tailwindlabs/tailwindcss/pull/9147))
|
||||
- Honor the `hidden` attribute on elements in preflight ([#9174](https://github.com/tailwindlabs/tailwindcss/pull/9174))
|
||||
- Don't stop watching atomically renamed files ([#9173](https://github.com/tailwindlabs/tailwindcss/pull/9173))
|
||||
- Don't stop watching atomically renamed files ([#9173](https://github.com/tailwindlabs/tailwindcss/pull/9173), [#9215](https://github.com/tailwindlabs/tailwindcss/pull/9215))
|
||||
- Re-use existing entries in the rule cache ([#9208](https://github.com/tailwindlabs/tailwindcss/pull/9208))
|
||||
- Don't output duplicate utilities ([#9208](https://github.com/tailwindlabs/tailwindcss/pull/9208))
|
||||
- Fix `fontFamily` config TypeScript types ([#9214](https://github.com/tailwindlabs/tailwindcss/pull/9214))
|
||||
|
|
|
|||
37
src/cli.js
37
src/cli.js
|
|
@ -17,6 +17,7 @@ import getModuleDependencies from './lib/getModuleDependencies'
|
|||
import log from './util/log'
|
||||
import packageJson from '../package.json'
|
||||
import normalizePath from 'normalize-path'
|
||||
import micromatch from 'micromatch'
|
||||
import { validateConfig } from './util/validateConfig.js'
|
||||
|
||||
let env = {
|
||||
|
|
@ -837,6 +838,23 @@ async function build() {
|
|||
}
|
||||
|
||||
let config = refreshConfig(configPath)
|
||||
let contentPatterns = refreshContentPatterns(config)
|
||||
|
||||
/**
|
||||
* @param {import('../types/config.js').RequiredConfig} config
|
||||
* @return {{all: string[], dynamic: string[], static: string[]}}
|
||||
**/
|
||||
function refreshContentPatterns(config) {
|
||||
let globs = extractFileGlobs(config)
|
||||
let tasks = fastGlob.generateTasks(globs, { absolute: true })
|
||||
let dynamicPatterns = tasks.filter((task) => task.dynamic).flatMap((task) => task.patterns)
|
||||
let staticPatterns = tasks.filter((task) => !task.dynamic).flatMap((task) => task.patterns)
|
||||
|
||||
return {
|
||||
all: [...staticPatterns, ...dynamicPatterns],
|
||||
dynamic: dynamicPatterns,
|
||||
}
|
||||
}
|
||||
|
||||
if (input) {
|
||||
contextDependencies.add(path.resolve(input))
|
||||
|
|
@ -867,6 +885,7 @@ async function build() {
|
|||
env.DEBUG && console.time('Resolve config')
|
||||
context = null
|
||||
config = refreshConfig(configPath)
|
||||
contentPatterns = refreshContentPatterns(config)
|
||||
env.DEBUG && console.timeEnd('Resolve config')
|
||||
|
||||
env.DEBUG && console.time('Watch new files')
|
||||
|
|
@ -924,7 +943,14 @@ async function build() {
|
|||
// Restore watching any files that are "removed"
|
||||
// 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)
|
||||
// TODO: An an optimization we should allow removal when the config changes
|
||||
watcher.on('unlink', (file) => watcher.add(file))
|
||||
watcher.on('unlink', (file) => {
|
||||
file = normalizePath(file)
|
||||
|
||||
// Only re-add the file if it's not covered by a dynamic pattern
|
||||
if (!micromatch.some([file], contentPatterns.dynamic)) {
|
||||
watcher.add(file)
|
||||
}
|
||||
})
|
||||
|
||||
// Some applications such as Visual Studio (but not VS Code)
|
||||
// will only fire a rename event for atomic writes and not a change event
|
||||
|
|
@ -935,11 +961,16 @@ async function build() {
|
|||
return
|
||||
}
|
||||
|
||||
let watchedPath = path.resolve(meta.watchedPath)
|
||||
let watchedPath = meta.watchedPath
|
||||
|
||||
// Watched path might be the file itself
|
||||
// Or the directory it is in
|
||||
filePath = watchedPath.endsWith(filePath) ? watchedPath : path.resolve(watchedPath, filePath)
|
||||
filePath = watchedPath.endsWith(filePath) ? watchedPath : path.join(watchedPath, filePath)
|
||||
|
||||
// Skip this event since the files it is for does not match any of the registered content globs
|
||||
if (!micromatch.some([filePath], contentPatterns.all)) {
|
||||
return
|
||||
}
|
||||
|
||||
// Skip since we've already queued a rebuild for this file that hasn't happened yet
|
||||
if (pendingRebuilds.has(filePath)) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue