Repository: tailwindlabs/tailwindcss
File: packages/@tailwindcss-cli/src/commands/build/index.ts (TypeScript)

Code before:
          // Scan the entire `base` directory for full rebuilds.
          if (rebuildStrategy === 'full') {
            // Clear all watchers
            cleanupWatchers()

            // Collect the new `input` and `cssImportPaths`.
            ;[input, cssImportPaths] = await handleImports(
              args['--input']
                ? await fs.readFile(args['--input'], 'utf-8')
                : css`
                    @import 'tailwindcss';
                  `,
              args['--input'] ?? base,
            )
            clearRequireCache(resolvedFullRebuildPaths)
            fullRebuildPaths = cssImportPaths.slice()

            // 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.map(({ base, pattern }) => ({
                // Globs are relative to the input.css file
                base: base ? path.dirname(path.resolve(inputBasePath, base)) : inputBasePath,
                pattern,
              })),
            })

            // Scan the directory for candidates
            let candidates = scanner.scan()

            // Setup new watchers
            cleanupWatchers = await createWatchers(watchDirectories(base, scanner), handle)

            // Re-compile the CSS
            compiledCss = compiler.build(candidates)
          }

          // Scan changed files only for incremental rebuilds.
          else if (rebuildStrategy === 'incremental') {
            let newCandidates = scanner.scanFiles(changedFiles)

            // No candidates found which means we don't need to rebuild. This can
            // happen if a file is detected but doesn't match any of the globs.
            if (newCandidates.length <= 0) return

            compiledCss = compiler.build(newCandidates)
          }


Review comment (bug):
This makes me wonder if we shouldn't call this something else? We can't resolve the base inside tailwindcss core (if we do, we need to make it aware of paths etc. which feels wrong if it doesn't do IO?) so instead, we have to translate the paths that are relative to the input CSS file here to the proper base dirname.

My proposal is to call it `origin` instead of `base`. That would also make it clearer why `origin` can be `null` (i.e it's origin is the input CSS file)

I went with `base` for consistency with the other places where we use globs.

Update: I went ahead and called it `origin` for now. Still curious what you think here, though!

cc @thecrypticace @RobinMalfait @adamwathan 

Code after:

          // Scan the entire `base` directory for full rebuilds.
          if (rebuildStrategy === 'full') {
            // Clear all watchers
            cleanupWatchers()

            // Collect the new `input` and `cssImportPaths`.
            ;[input, cssImportPaths] = await handleImports(
              args['--input']
                ? await fs.readFile(args['--input'], 'utf-8')
                : css`
                    @import 'tailwindcss';
                  `,
              args['--input'] ?? base,
            )
            clearRequireCache(resolvedFullRebuildPaths)
            fullRebuildPaths = cssImportPaths.slice()

            // 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.map(({ origin, pattern }) => ({
                // Ensure the glob is relative to the input CSS file or the
                // config file where it is specified.
                base: origin ? path.dirname(path.resolve(inputBasePath, origin)) : inputBasePath,
                pattern,
              })),
            })

            // Scan the directory for candidates
            let candidates = scanner.scan()

            // Setup new watchers
            cleanupWatchers = await createWatchers(watchDirectories(base, scanner), handle)

            // Re-compile the CSS
            compiledCss = compiler.build(candidates)
          }

          // Scan changed files only for incremental rebuilds.
          else if (rebuildStrategy === 'incremental') {
            let newCandidates = scanner.scanFiles(changedFiles)

            // No candidates found which means we don't need to rebuild. This can
            // happen if a file is detected but doesn't match any of the globs.
            if (newCandidates.length <= 0) return

            compiledCss = compiler.build(newCandidates)