Auto source detection improvements (#14820)
This PR introduces a new `source(…)` argument and improves on the
existing `@source`. The goal of this PR is to make the automatic source
detection configurable, let's dig in.
By default, we will perform automatic source detection starting at the
current working directory. Auto source detection will find plain text
files (no binaries, images, ...) and will ignore git-ignored files.
If you want to start from a different directory, you can use the new
`source(…)` next to the `@import "tailwindcss/utilities"
layer(utilities) source(…)`.
E.g.:
```css
/* ./src/styles/index.css */
@import 'tailwindcss/utilities' layer(utilities) source('../../');
```
Most people won't split their source files, and will just use the simple
`@import "tailwindcss";`, because of this reason, you can use
`source(…)` on the import as well:
E.g.:
```css
/* ./src/styles/index.css */
@import 'tailwindcss' source('../../');
```
Sometimes, you want to rely on auto source detection, but also want to
look in another directory for source files. In this case, yuo can use
the `@source` directive:
```css
/* ./src/index.css */
@import 'tailwindcss';
/* Look for `blade.php` files in `../resources/views` */
@source '../resources/views/**/*.blade.php';
```
However, you don't need to specify the extension, instead you can just
point the directory and all the same automatic source detection rules
will apply.
```css
/* ./src/index.css */
@import 'tailwindcss';
@source '../resources/views';
```
If, for whatever reason, you want to disable the default source
detection feature entirely, and only want to rely on very specific glob
patterns you define, then you can disable it via `source(none)`.
```css
/* Completely disable the default auto source detection */
@import 'tailwindcss' source(none);
/* Only look at .blade.php files, nothing else */
@source "../resources/views/**/*.blade.php";
```
Note: even with `source(none)`, if your `@source` points to a directory,
then auto source detection will still be performed in that directory. If
you don't want that, then you can simply add explicit files in the globs
as seen in the previous example.
```css
/* Completely disable the default auto source detection */
@import 'tailwindcss' source(none);
/* Run auto source detection in `../resources/views` */
@source "../resources/views";
```
---------
Co-authored-by: Jordan Pittman <jordan@cryptica.me>
Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
This commit is contained in:
parent
c439cdf43c
commit
d68a780f98
24 changed files with 2341 additions and 606 deletions
|
|
@ -137,21 +137,34 @@ export async function handle(args: Result<ReturnType<typeof options>>) {
|
|||
fullRebuildPaths.push(path)
|
||||
},
|
||||
})
|
||||
|
||||
let sources = (() => {
|
||||
// Disable auto source detection
|
||||
if (compiler.root === 'none') {
|
||||
return []
|
||||
}
|
||||
|
||||
// No root specified, use the base directory
|
||||
if (compiler.root === null) {
|
||||
return [{ base, pattern: '**/*' }]
|
||||
}
|
||||
|
||||
// Use the specified root
|
||||
return [compiler.root]
|
||||
})().concat(compiler.globs)
|
||||
|
||||
let scanner = new Scanner({ sources })
|
||||
env.DEBUG && console.timeEnd('[@tailwindcss/cli] Setup compiler')
|
||||
return compiler
|
||||
|
||||
return [compiler, scanner] as const
|
||||
}
|
||||
|
||||
// Compile the input
|
||||
let compiler = await createCompiler(input)
|
||||
let scanner = new Scanner({
|
||||
detectSources: { base },
|
||||
sources: compiler.globs,
|
||||
})
|
||||
let [compiler, scanner] = await createCompiler(input)
|
||||
|
||||
// Watch for changes
|
||||
if (args['--watch']) {
|
||||
let cleanupWatchers = await createWatchers(
|
||||
watchDirectories(base, scanner),
|
||||
watchDirectories(scanner),
|
||||
async function handle(files) {
|
||||
try {
|
||||
// If the only change happened to the output file, then we don't want to
|
||||
|
|
@ -205,13 +218,7 @@ export async function handle(args: Result<ReturnType<typeof options>>) {
|
|||
fullRebuildPaths = inputFilePath ? [inputFilePath] : []
|
||||
|
||||
// Create a new compiler, given the new `input`
|
||||
compiler = await createCompiler(input)
|
||||
|
||||
// Re-scan the directory to get the new `candidates`
|
||||
scanner = new Scanner({
|
||||
detectSources: { base },
|
||||
sources: compiler.globs,
|
||||
})
|
||||
;[compiler, scanner] = await createCompiler(input)
|
||||
|
||||
// Scan the directory for candidates
|
||||
env.DEBUG && console.time('[@tailwindcss/cli] Scan for candidates')
|
||||
|
|
@ -219,7 +226,7 @@ export async function handle(args: Result<ReturnType<typeof options>>) {
|
|||
env.DEBUG && console.timeEnd('[@tailwindcss/cli] Scan for candidates')
|
||||
|
||||
// Setup new watchers
|
||||
cleanupWatchers = await createWatchers(watchDirectories(base, scanner), handle)
|
||||
cleanupWatchers = await createWatchers(watchDirectories(scanner), handle)
|
||||
|
||||
// Re-compile the CSS
|
||||
env.DEBUG && console.time('[@tailwindcss/cli] Build CSS')
|
||||
|
|
@ -287,19 +294,16 @@ export async function handle(args: Result<ReturnType<typeof options>>) {
|
|||
eprintln(`Done in ${formatDuration(end - start)}`)
|
||||
}
|
||||
|
||||
function watchDirectories(base: string, scanner: Scanner) {
|
||||
return [base].concat(
|
||||
scanner.globs.flatMap((globEntry) => {
|
||||
// We don't want a watcher for negated globs.
|
||||
if (globEntry.pattern[0] === '!') return []
|
||||
function watchDirectories(scanner: Scanner) {
|
||||
return scanner.globs.flatMap((globEntry) => {
|
||||
// We don't want a watcher for negated globs.
|
||||
if (globEntry.pattern[0] === '!') return []
|
||||
|
||||
// We don't want a watcher for nested directories, these will be covered
|
||||
// by the `base` directory already.
|
||||
if (globEntry.base.startsWith(base)) return []
|
||||
// We don't want a watcher for files, only directories.
|
||||
if (globEntry.pattern === '') return []
|
||||
|
||||
return globEntry.base
|
||||
}),
|
||||
)
|
||||
return globEntry.base
|
||||
})
|
||||
}
|
||||
|
||||
async function createWatchers(dirs: string[], cb: (files: string[]) => void) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue