Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
10ヶ月かけてstyled-components v4からv5にアップデートした話
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
uhyo
April 24, 2025
Technology
750
5
Share
10ヶ月かけてstyled-components v4からv5にアップデートした話
2025-04-24 Qiita Conference 2025
uhyo
April 24, 2025
More Decks by uhyo
See All by uhyo
TypeScript 7.0の現在地と備え方
uhyo
7
2.7k
React 19時代のコンポーネント設計ベストプラクティス
uhyo
19
9k
型定義でAIと会話する:型を通じてAIに意図を伝えるテクニック
uhyo
1
68
タグ付きユニオン型を便利に使うテクニックとその注意点
uhyo
3
1.1k
ECMAScript仕様の最新動向: プロセスの変化と仕様のトレンド
uhyo
3
860
TypeScript 6.0で非推奨化されるオプションたち
uhyo
18
8k
Claude Code 10連ガチャ
uhyo
4
1.1k
AI時代、“平均値”ではいられない
uhyo
8
4.3k
意外と難しいGraphQLのスカラー型
uhyo
5
1.1k
Other Decks in Technology
See All in Technology
UIライブラリに依存しすぎないReact Native設計を目指して
grandbig
0
100
マルチエージェント × ハーネスエンジニアリング × GitLab Duo Agent Platformで実現する「AIエージェントに仕事をさせる時代へ。」 / 20260421 GitLab Duo Agent Platform
n11sh1
0
170
扱える不確実性を増やしていく - スタートアップEMが考える「任せ方」
kadoppe
0
310
Microsoft 365 / Microsoft 365 Copilot : 自分の状態を確認する「ラベル」について
taichinakamura
0
300
LLM時代の検索アーキテクチャと技術的意思決定
shibuiwilliam
3
1.4k
Practical TypeProf: Lessons from Analyzing Optcarrot
mame
0
540
データを"持てない"環境でのアノテーション基盤設計
sansantech
PRO
1
130
AI駆動1on1〜AIに自分を育ててもらう〜
yoshiakiyasuda
0
130
AI와 협업하는 조직으로의 여정
arawn
0
490
AI時代のガードレールとしてのAPIガバナンス
nagix
0
300
Agents CLI と Gemini Enterprise Agent Platform で マルチエージェント開発が楽しくなる!
kaz1437
0
110
AWS Agent Registry の基礎・概要を理解する/aws-agent-registry-intro
ren8k
3
390
Featured
See All Featured
Measuring & Analyzing Core Web Vitals
bluesmoon
9
810
HU Berlin: Industrial-Strength Natural Language Processing with spaCy and Prodigy
inesmontani
PRO
0
320
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
SEO in 2025: How to Prepare for the Future of Search
ipullrank
3
3.4k
VelocityConf: Rendering Performance Case Studies
addyosmani
333
25k
Navigating Weather and Climate Data
rabernat
0
170
Between Models and Reality
mayunak
3
270
エンジニアに許された特別な時間の終わり
watany
106
240k
How GitHub (no longer) Works
holman
316
150k
Fireside Chat
paigeccino
42
3.9k
Designing for Timeless Needs
cassininazir
0
200
Product Roadmaps are Hard
iamctodd
PRO
55
12k
Transcript
10ヶ月かけてstyled-components v4からv5にアップデートした話 2025-04-24 Qiita Conference
発表者紹介 uhyo 株式会社カオナビ フロントエンドエキスパート 実は結局CSS Modules (*.module.cssのやつ)が一番では? と思っている。 2
styled-components React向けCSS in JSの代表的ライブラリのひとつ。 // コード例 const Button = styled.button`
background: transparent; border-radius: 3px; border: 2px solid #BF4F74; color: #BF4F74; margin: 0 1em; padding: 0.25em 1em; `; 3
styled-componentsの現状 この記事によくまとまっているので読みましょう。 4 https://blog.re-taro.dev/p/01JQ4914YGQZ02Q5PW5CNRJTJT
styled-componentsの現状 とはいえまとめると、 • 最近メンテナンスモードへの移行が発表され、 新規の利用は推奨されなくなった。 • RSCのような新たなパラダイムに対応するコストが 大きく、(非ゼロランタイムの)CSS in JSに対する
逆風もあるため。 5
とはいえ このトークはその辺りの話題は取り扱わない。 v4 → v5アップデートということで、 その領域まで到達するずっと前の話。 6
This Talk styled-componentsアップデートという作業に 際して発生した様々な問題に対して、 幅広い知見やアイデアをもって対処した結果、 なんとか不具合等を起こさずにアップデート できたという話をします。 7
この話から持ち帰ってほしいもの アプリの基盤部分をいじるような作業は、 難易度が高いが、アプリの運用保守のためには 必要不可欠なもの。 ひとつの具体例を通して、さまざまな知見を 仕入れておけばいつか役に立つということを 知ってほしい。 8
1. なぜstyled-componentsの バージョンを上げたくなったのか 9
バージョンを上げる理由 v4→v5ではランタイムのパフォーマンスが 上がることも馬鹿にならないが、 一番の理由はベンダープレフィクスの自動付与を 無効にしたいから。 10
ベンダープレフィクス CSS等の新機能をブラウザが実装する際に、 実験的機能として独自のプレフィクスを付けて 実装する手法。 昔(10年以上前)は盛んに使われていた。 11
ベンダープレフィクスの自動付与 display: flex; display: -webkit-box; display: -webkit-flex; display: -ms-flexbox; display:
flex; 12 styled-components@4による変換 (正確にはstylisがやっている)
問題のある例 @supports(scrollbar-width: thin) @supports (-webkit-scrollbar-width:thin) or (-moz-scrollbar-width:thin) or (-ms-scrollbar-width:thin) or
(scrollbar-width:thin) { 13
問題のある例 @supports(scrollbar-width: thin) @supports (-webkit-scrollbar-width:thin) or (-moz-scrollbar-width:thin) or (-ms-scrollbar-width:thin) or
(scrollbar-width:thin) { 14 scrollbar-widthはベンダープレフィクスありとなしで挙動が異なるので ベンダープレフィクス無し版のサポートを検出したかったが、できない
v4→v5プロジェクト始動 ぼく「こんなんやってられん。v5に上げれば 自動付与をオフにできるオプションが使えるので、 v5に上げます」 こうしてプロジェクトが始動した。 15
2. v4→v5はどれくらい大変か 16
とりあえず公式ドキュメントを見る メジャーバージョンアップは公式のドキュメント に従うのが定石。v4→v5のドキュメントを見よう。 17
v4→v5の破壊的変更 公式ドキュメントから引用 styled-components v5 does not introduce any breaking public
API changes, … (訳) styled-components v5ではパブリックAPIに対して破壊的変更はあり ません。… https://styled-components.com/docs/faqs#what-do-i-need-to-do-to-migrate-to-v5 18
v4→v5の破壊的変更 ぼく「なるほど、v5は破壊的変更が無いから 上げるだけでいいんだな」 19
v4→v5の破壊的変更 ぼく「なるほど、v5は破壊的変更が無いから 上げるだけでいいんだな」 ※「うそです」のAAをイメージしてChatGPTに生成してもらった憎たらしい猫のイラスト 20
破壊的変更の実際① v4とv5では、内部で使用されているstylisの バージョンの違いからか、セミコロンを忘れた ときの取り扱いが変更されている。 21
破壊的変更の実際① display: flex flex-direction: row; v4: セミコロンが補完されている v5: ただの空白として扱われている 22
セミコロン忘れた!
破壊的変更の実際② v5.2では & の取り扱いが部分的に変更された。 リリースノートではバグ修正と言っているが がっつり破壊的変更である。 23
破壊的変更の実際② const ListItem = styled.div` ${({ selected }) => selected
&& css` .dark & { background-color: red; } `} `; 24
破壊的変更の実際② const ListItem = styled.div` ${({ selected }) => selected
&& css` .dark & { background-color: red; } `} `; 25 v5.2より前: selected: trueなListItemを表す v5.2以降: 全てのListItemを表す
対処の必要がある2つの破壊的変更 •セミコロンを忘れた場合の挙動の違い •&の意味の変更 26
余談: v6に上げるのは断念 v5→v6では型定義が刷新され、 従来問題なかったコードが型エラーになった。 型定義を修正するPRを出してマージされたが、 型チェックのパフォーマンスがものすごく悪化 して苦情が殺到したためリバートされた。 (すみません) https://github.com/styled-components/styled-components/pull/4288 27
3. 破壊的変更の対処 28
stylelintを使う 今回は、stylelintによる静的解析により 破壊的変更を受ける場所を全て洗い出す 方針にした。 styled-componentsのコードは、 postcss-styled-syntaxというパーサーを使えば stylelintで扱うことができる。 29
セミコロンの対処 単純なケースでは、セミコロン漏れは パースエラーとしてstylelintが検知してくれる。 display: flex flex-direction: row; 30 これとか
セミコロンの対処 では、これは? const someCSS = “display: flex”; const Wrapper =
styled.div` ${someCSS} flex-direction: row; `; 31
セミコロンの対処 この例では、JSの実行の結果としてセミコロン 不足のCSS文字列が生成されるため、 単純なパーサーでは問題を検知できない。 const someCSS = “display: flex”; const
Wrapper = styled.div` ${someCSS} flex-direction: row; `; 32
抽象実行による解決 この問題に対しては、JSの抽象実行を実装する ことで、この場合も検知できるようにして対処。 (この場合、${someCSS}を見たらsomeCSSの変数定義を 探してきて中身を代入する) const someCSS = “display: flex”;
const Wrapper = styled.div` ${someCSS} flex-direction: row; `; 33
抽象実行として実装したもの 実際のソースコードを解析するのに必要な構文を 順次特定して実装を進めた。 • importの解決 • 各種演算子 • 関数呼び出し •
オブジェクト など 34
抽象実行のポイント 目的上、偽陽性は許容できるが偽陰性は許容でき ない。これを考慮して抽象実行の仕様を決める。 計算の結果が不明な場合は陽性に倒す。 抽象実行を高度化して精度を上げることで、 偽陽性を減らすことができる。 (型システムの健全性にも通ずる考え方) 35
&の問題の対応 破壊的変更で&の意味が変わってしまったが、 大丈夫な場合もあった。 &:hover { ←影響を受けない /* … */ }
div & { ←影響を受ける /* … */ } 36
&の問題の対応 styled-componentsのソースコードを読んで、 &の意味が変わる正確な条件を特定。 それに対してエラーを発生させるlintルールを 実装した。 37
4. 段階的なリリース 38
動作確認 破壊的変更にはこれで対処できたが、念のために 動作確認が必要。 対象はReactを使っている全ページ! カオナビには対象画面が100画面以上あった。 動作確認対象が膨大すぎて終わる気がしない。 39
幸いにも…… 歴史的経緯から、カオナビのReact使用ページは MPAとSPAが混在していた。 MPAページはそれぞれ独立したエントリー ポイント(JSファイル)を持っていた。 (ひとつのwebpack設定でエントリーポイント複数) 40
段階的リリースをしたい MPAの画面ごとに分けてアップデートを リリースすることで、確認を細分化しリスクを 抑えられる。SPAになっている部分は気合で。 問題はその実現方法だが…… 41
段階的リリースの要件 なるべくソースコードには手を触れず、 簡単な仕組みで、エントリーポイント単位で v4からv5に切り替えたい。 (ソースコードの側で import from “styled-components-4” とかはちょっとやりたくない) 42
段階的リリースの方法 webpackの設定で、 import from “styled-components” を globalThis[“styled-components”]にマッピング。 各エントリーポイントの先頭で、 v4かv5をこのグローバル変数に代入する。 43
完遂までのスケジュール 2月~3月: 計画策定・stylelintルール実装 4月: 休憩(あとテストのリソース調整) 5月: アプデのブロッカーを修正 6月~11月: テスト・順次リリース 実際の修正作業は多分1人月くらい。あとは確認作業!
44
まとめ 45
今回のポイント styled-components v4→v5のアプデを安全に行う ために、さまざまな知見・素養が必要だった。 46
今回のポイント • リンターなど言語処理系を実装するための知識 • 抽象実行や健全性といった静的解析にまつわる知識 • 必要に応じて依存ライブラリのソースコードを読んで 理解する力 • webpackなど基盤を支える仕組みの正確な理解
• 「破壊的変更はありません」を信じない心 47
まとめ 仕組みに乗っかるだけでなく、仕組み自体の知識 を持つことが、難しい問題に立ち向かう上で重要。 プログラムをたくさん書く、大学で学ぶ、 興味を持って仕組みを調べるといった方法で 知識を身に付けましょう。 48