Skip to content

feat: Tailwind CSS v4 への移行(Hub は Tailwind を廃止) - #500

Draft
ujiro99 wants to merge 11 commits into
dev-1.4.0from
feat/tailwindcss-v4
Draft

ujiro99 wants to merge 11 commits into
dev-1.4.0from
feat/tailwindcss-v4

Conversation

@ujiro99

@ujiro99 ujiro99 commented Oct 19, 2026 •

Copy link
Copy Markdown
Owner

Closes #497

概要

拡張機能を Tailwind CSS v4 に移行し、Hub では Tailwind CSS(と shadcn/ui)を使うのをやめます。
方針と手順の詳細は docs/design/tailwindcss-v4-migration.md にあります。

content script はユーザーのページ上で動くので、ユーザーのページに影響を与えず、ユーザーのページからも影響を受けないことを前提に設計しています。

変更内容

Extension

  • 設定方式の変更
    • @tailwindcss/vite と、CSS の中で設定を書く方式(@theme)に移行しました。
    • tailwind.config.js と postcss.config.cjs は削除しました。
  • 依存パッケージの変更
    • tailwindcss-animate を tw-animate-css に置き換えました。
    • tailwind-merge を v3 に上げました(shared パッケージも同様)。
  • rem を使わない
    • サイズの値はすべて px にしました(余白の基準 --spacing、文字サイズ --text-*、幅 --container-*、角丸 --radius-*)。これで、ユーザーのページの root font-size が UI に影響しなくなります。
    • 画面幅の区切り(--breakpoint-*)も v3 と同じ px で定義しました。rem のままだと、Chrome の既定の文字サイズ設定に連動してしまうためです。
    • content script の CSS に rem(と rlh などページの root 要素に連動する単位)が含まれていたら、ビルドが失敗するようにしました(findRemUsages)。検査する CSS が見つからない場合もビルドを失敗させます。
  • Shadow DOM 内で @property が効かない問題への対策
    • Chrome は Shadow DOM の中の @property を無視します。そこで、@property で決めている初期値を、優先度の最も低い @layer properties に通常の変数として書き出す PostCSS プラグインを自作しました(postcss-shadow-dom-properties)。
    • CSS は分割されたまま shadow root に注入されるため、レイヤーを使う各ファイルの先頭で @layer properties; を宣言し、注入の順番に関係なく最も優先度の低いレイヤーになるようにしています。
    • ユーザーのページの document.head には何も追加しません。
  • テーマの色は @theme inline で定義しました。v4 の既定のやり方では、ユーザースタイルで指定した色が反映されなくなる退行(E2E-72)があり、それを直すためです。
  • クラスを探すファイルの範囲を src(テストを除く)に限りました。AGENTS.md などの説明文から、不要なクラスが作られないようにするためです。
  • クラス名の変更
    • v4 で名前が変わったクラスを書き換えました(rounded を rounded-sm に、bg-gradient-to-r を bg-linear-to-r に、など)。
    • @apply を使う CSS Modules には @reference を追加しました。

Hub

  • Tailwind CSS、PostCSS、shadcn/ui とその依存パッケージを削除し、普通の CSS(全体用の CSS と CSS Modules)に置き換えました。
  • e2e テストが使うテストページは、DOM 構造を変えずにスタイルだけ置き換えました。

e2e

  • E2E_HUB_BASE_URL を指定すると、デプロイ済みの hub への通信をローカルでビルドした hub に向けられるようにしました(e2e/utils/hubRoute.ts)。手順は packages/hub/AGENTS.md にあります。
    • ローカルに無い JS/CSS などのファイルはデプロイ済みの hub から取得します(拡張が自分で開く録画画面のため)。ページ(HTML)がローカルに無い場合は 404 を返し、テストが失敗するようにしています。

その他

  • 必要な Node のバージョンを 20 以上に上げました(Tailwind v4 の要件)。

検証結果

  • ビルド・型チェック・lint・テスト
    • リポジトリのルートで全パッケージのビルドが通りました。
    • 型チェック(tsc)が通りました。
    • lint はエラーが 0 件で、警告は移行前と同じ件数でした。
    • ユニットテストは extension の 1,523 件と hub の 33 件がすべて通りました。
  • v3 との見た目の比較
    • 選択時のメニューは画素単位で一致しました。
    • options page とオンボーディング画面の差は、画像のにじみとアニメーションの途中の違いだけでした。
  • root font-size を 62.5% にしたページでも、メニューのサイズは変わりませんでした。
  • e2e(v4 版の拡張と、ローカルで配信した新しい hub の組み合わせ)
    • 81 件成功、7 件失敗、5 件スキップでした。
    • 失敗した 7 件は main(v3)でも同じく失敗しました。
      • Cloudflare 認証が必要なテスト 4 件(E2E-90/91/92/94)は、この環境に認証用の秘密情報が無いためです。
      • 外部の検索サイトの応答を確かめるテスト 3 件(百度・Naver・Yandex)は、相手サイト側の問題です。

注意点

  • この PR の CI で走る e2e は、デプロイ済みの古いテストページを使います。新しい Hub を本番で確かめるには、マージして GitHub Pages へのデプロイが終わった後に e2e を走らせる必要があります。
  • content script に入る CSS は約 65KB から約 85KB に増えます。

🤖 Generated with Claude Code

https://claude.ai/code/session_01KWGX774FR5iixzXqS7CMpU

ujiro99 and others added 11 commits October 19, 2026 08:49
The hub only serves the e2e test page and static data files, so a CSS
framework brings no benefit. Replace Tailwind classes with plain CSS
(globals.css + CSS Modules) and shadcn/ui components with native
elements, keeping the test page DOM that e2e relies on unchanged.

Also add E2E_HUB_BASE_URL to route the deployed hub to a local build so
hub changes can be verified with e2e before deploying.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KWGX774FR5iixzXqS7CMpU
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KWGX774FR5iixzXqS7CMpU
- postcss-shadow-dom-properties: declare the initial values of
  @property-registered custom properties inside the stylesheet, since
  Chrome ignores @Property in shadow trees (needed by Tailwind CSS v4)
- findRemUsages: detect rem units, which follow the user's page root
  font-size inside the content script's Shadow DOM

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KWGX774FR5iixzXqS7CMpU
- Use @tailwindcss/vite and move the theme from tailwind.config.js to
  CSS (@theme); replace tailwindcss-animate with tw-animate-css and
  update tailwind-merge to v3
- Redefine every rem-based token in px (--spacing: 4px, text, container,
  radius) so the content script UI doesn't follow the user's page root
  font-size, and fail the build if content script CSS contains rem
- Apply the Shadow DOM @Property fallback via PostCSS
- Rename utilities for v4 (shadow, rounded, outline-hidden, ...), add
  @reference to CSS modules using @apply, and restore v3 defaults
  (placeholder color, button cursor)
- Ignore 'Request context disposed' in the e2e hub route helper

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KWGX774FR5iixzXqS7CMpU
…canning

- Use @theme inline for tokens that reference runtime CSS variables.
  With a plain @theme, --color-background was resolved on :root/:host,
  so the popup's per-element --background override (user styles) no
  longer changed bg-background (e2e E2E-72)
- Scan only src/ (excluding tests) for class names; plain text in docs
  generated unused rem-based utilities

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KWGX774FR5iixzXqS7CMpU
Windows opened by the extension (e.g. the PageAction recorder) load the
deployed HTML because their navigation can't be intercepted; forwarding
its hashed assets to the local build returned 404 and broke the page.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KWGX774FR5iixzXqS7CMpU
…olation

- Declare `@layer properties` at the top of every CSS file that uses layers,
  so it stays the lowest-priority layer whatever the chunk injection order.
- Fail the build when no content script CSS could be checked for rem, and
  also detect uppercase REM and other root-relative units (rlh, rex, ...).
- Define breakpoints in px as in v3, so media queries don't follow the
  browser's default font-size setting.
- e2e: return the local 404 for missing hub pages instead of falling back to
  the deployed hub, and match the base path on a segment boundary.
- Fix a lint error in the cn() test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KWGX774FR5iixzXqS7CMpU

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant