@tailwindcss/cli が無視ディレクトリの入力ファイルを監視できるように

tailwindlabs/tailwindcss

@tailwindcss/cli--watch モードで、デフォルトで source (none) として除外されるフォルダにある入力 CSS ファイルの変更も検知し、ビルドが自動再実行されるようになりました。この変更は Issue #17632 で報告された監視不具合を直接解消します。

背景

--watch はファイルシステムの変化をトリガーに再コンパイルしますが、入力ファイル自体が無視ディレクトリにあるとスキャナの対象外となり、変更が反映されませんでした。Issue #17632 では assets/ フォルダがデフォルトで除外されるため、@tailwindcss/cli が期待通りにリビルドしないことが報告されています。開発者は手動でプロセスを再起動するしかなく、開発フローが阻害されていました。

技術的な変更

CHANGELOG エントリの追加

@@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0)

  - Ensure `@tailwindcss/cli` in `--watch` mode doesn't crash on Windows when `@source` points to a directory that doesn't exist ([#20242](https://github.com/tailwindlabs/tailwindcss/pull/20242))
  - Ensure `@tailwindcss/vite` doesn't crash in Deno v2.8.x when `context.parentURL` is not a valid URL ([#20245](https://github.com/tailwindlabs/tailwindcss/pull/20245))
+- Ensure `@tailwindcss/cli` in `--watch` mode rebuilds when the input CSS file changes in an ignored directory ([#20246](https://github.com/tailwindlabs/tailwindcss/pull/20246))

 ## [4.3.1] - 2026-06-12

このエントリは、--watch が入力ファイルの変更を検知できるようになったことをリリースノートとして明示しています。

ビルドコマンドのロジック修正

@@ -260,6 +260,14 @@ export async function handle(args: Result<ReturnType<typeof options>>) {
       negated: true,
     })

+    if (inputFilePath !== null) {
+      sources.push({
+        base: path.dirname(inputFilePath),
+        pattern: path.basename(inputFilePath),
+        negated: false,
+      })
+    }
+
     let scanner = new Scanner({ sources })
     DEBUG && I.end('Setup compiler')

inputFilePath が指定されている場合に、そのディレクトリとファイル名を sources 配列へ追加しています。これにより Scanner が無視設定を上書きし、入力ファイル自体の変更も監視対象になります。既存の negated: true 設定はそのまま残すことで、他の除外パターンは影響を受けません。

監視動作を検証する統合テストの追加

@@ -404,6 +404,57 @@ describe.each([
     },
   )

+  // https://github.com/tailwindlabs/tailwindcss/issues/17632
+  test(
+    'watch mode rebuilds when the input file is in an ignored folder',
+    {
+      fs: {
+        'package.json': json`
+          {
+            "dependencies": {
+              "tailwindcss": "workspace:^",
+              "@tailwindcss/cli": "workspace:^"
+            },
+          }
+        `,
+        'assets/tailwind.config.js': js`
+          module.exports = {
+            content: {
+              relative: true,
+              files: ['html/*.html'],
+            },
+          }
+        `,
+        'assets/html/index.html': html`
+          <div class="underline"></div>
+        `,
+        'assets/css/index.css': css`
+          @import 'tailwindcss' source(none);
+          @config '../tailwind.config.js';
+        `,
+      },
+    },
+    async ({ fs, spawn }) => {
+      let process = await spawn(
+        `${command} --input assets/css/index.css --output dist/out.css --watch`,
+      )
+      await process.onStderr((m) => m.includes('Done in'))
+
+      await fs.expectFileToContain('dist/out.css', [candidate`underline`])
+
+      await fs.write(
+        'assets/css/index.css',
+        css`
+          @import 'tailwindcss' source(none);
+          @config '../tailwind.config.js';
+          @source inline("flex");
+        `,
+      )
+    }
+  )
*** End Patch
*** End Patch

テストは assets/ ディレクトリ以下に配置した index.css を変更し、dist/out.css が正しく更新されることを確認します。fs.write で新たに @source inline("flex") を書き込んだ後でもビルドが走る点が重要です。Issue #17632 を直接参照し、修正の効果をエンドツーエンドで保証しています。

設計判断

入力ファイルを sources 配列に明示的に追加する方針が採用されました。代替案として @source ディレクティブを自動生成する手法も考えられましたが、既存のスキャナロジックを最小変更で拡張でき、後方互換性を保持できる点が選択理由です。negated: false にすることで無視設定を上書きし、無視ディレクトリ内でも確実に変化を捕捉できます。

まとめ

本 PR は @tailwindcss/cli--watch モードにおいて、無視ディレクトリに配置された入力 CSS ファイルの変更を検知できなかった問題を解消します。入力ファイルを監視リストに自動追加するシンプルな実装で、既存のビルドフローと互換性を保ちつつ開発体験を向上させました。

記事メタデータ

Generated by:
gpt-oss-120b for DiffDaily
LLM Trace:
690342ac

この記事はAIによって自動生成されています。内容の正確性については、必ずソースコードやPRを確認してください。

品質レビュー結果

Review Status:
リトライ後承認
Review Count:
2回 (改善を経て承認)
Reviewed by:
gpt-oss-120b for DiffDaily

Review Criteria:

記事構成 ✓ PASS

Title, Context, Technical Detailの存在と明確さ

リード文がタイトル直下に配置され、背景・技術的な変更・設計判断・まとめというセクション構成が揃っており、総論→各論→結論の流れが明確です。

カスタムMarkdown構文 ⚠ WARNING

シンタックスハイライト・GitHubリンク記法の正確性

コードブロックは正しい diff ハイライトで記述されていますが、Issue 番号がリンク形式になっていません([#17632](URL) のようにすべき)。その他の GitHub リンクは正しく記述されています。

対象読者への適合性 ✓ PASS

エンジニア向けの適切な技術レベルと表現

対象は Tailwind CSS の開発者・CLI ユーザーという前提で、専門的な用語や実装詳細が中心です。初心者向けの過度な解説はありません。

パラグラフ・ライティング ✓ PASS

トピックセンテンス・1段落1トピック・段落長

各セクションは総論パラグラフ、具体的な技術説明、結論パラグラフで構成され、段落は1トピック・トピックセンテンスで始まり、空行で区切られています。

Diff内容との照合 ✓ PASS

コードブロックとDiff内容の一致

記事内の diff ブロックは提供された Diff と内容・行番号・追加箇所が一致しており、正確に反映されています。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

使用されている用語(`inputFilePath`, `sources`, `Scanner`, `ignored directory` など)は PR の記述と一致し、誤用はありません。

説明の技術的正確性 ✓ PASS

技術的主張の正確性と論理性

技術的な主張は PR の説明と Diff に裏付けられており、因果関係も正しく記述されています。

事実の突合 ✓ PASS

PR情報による主張の裏付け(ハルシネーション検出)

記事の全ての主張は PR タイトル・説明・Diff で裏付けられており、根拠のない推測や外部情報は含まれていません。

数値・固有名詞の確認 ✓ PASS

PR番号・コミットID・バージョン等の正確性

PR 番号 #20246 と Issue 番号 #17632 が正確に記述されています。日付やバージョン番号も Diff と合わせて正しいです。

タイトル・説明との一致 ✓ PASS

記事タイトル・説明とPR内容の一致

記事タイトルは PR の目的(入力ファイルの監視)を日本語で適切に要約しており、内容と一致しています。

外部知識の正確性 ✓ PASS

PRに記載のない外部知識(LTS、サポート状況など)の不使用

LTS、EOL、リリース日程等の外部知識は一切語られておらず、PR だけに基づいた記述です。

時間表現の正確性 ✓ PASS

時間表現がPR情報と一致しているか

時間表現の歪曲はなく、PR の記述と整合しています。