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
uhyo
April 24, 2025
Technology
790
5
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
10ヶ月かけてstyled-components v4からv5にアップデートした話
2025-04-24 Qiita Conference 2025
uhyo
April 24, 2025
More Decks by uhyo
See All by uhyo
React、まだ楽しくて草
uhyo
7
4.3k
TypeScript 7.0の現在地と備え方
uhyo
6
3.3k
React 19時代のコンポーネント設計ベストプラクティス
uhyo
20
9.7k
型定義でAIと会話する:型を通じてAIに意図を伝えるテクニック
uhyo
1
84
タグ付きユニオン型を便利に使うテクニックとその注意点
uhyo
3
1.1k
ECMAScript仕様の最新動向: プロセスの変化と仕様のトレンド
uhyo
3
900
TypeScript 6.0で非推奨化されるオプションたち
uhyo
18
8.3k
Claude Code 10連ガチャ
uhyo
4
1.1k
AI時代、“平均値”ではいられない
uhyo
8
11k
Other Decks in Technology
See All in Technology
失敗を経て、Harness Engineering で 大切にしたいことを考える / Learning from Failure: What Matters in Harness Engineering
bitkey
PRO
1
250
「エンジニア進化論」2028年の開発完全自動化、エンジニアはどう進化するか
cyberagentdevelopers
PRO
4
3.8k
Databricks における 生成AIガバナンスの実践
taka_aki
1
370
Oracle AI Database@Google Cloud:サービス概要のご紹介
oracle4engineer
PRO
6
1.5k
protovalidate-es を導入してみた
bengo4com
0
160
AI駆動開発が変える、大規模開発の前提 ーHuman in the Loop から Human on the Loop へ / AIE2026
visional_engineering_and_design
30
24k
EventBridge Connection
_kensh
5
680
2026TECHFRESH畢業分享會 - Lightning Talk - 資料也要 CI/CD? 用 Airbyte 自動化資料同步
line_developers_tw
PRO
0
620
MCP Appsを作ってみよう
iwamot
PRO
4
410
Claude Code の Sandbox 機能を Anthropic Sandbox Runtime(srt) で試そう!/lets-play-anthropic-sandbox-runtime
tomoki10
1
510
チームで実践する AI-DLC 思考の軌跡を残すチェックポイント設計
belongadmin
0
3.2k
2026 TECHFRESH 畢業分享會 - AI-Native 重塑軟體工程與虛擬講師
line_developers_tw
PRO
0
630
Featured
See All Featured
How to Get Subject Matter Experts Bought In and Actively Contributing to SEO & PR Initiatives.
livdayseo
0
140
Speed Design
sergeychernyshev
33
1.8k
Being A Developer After 40
akosma
91
590k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
16
2k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
55
3.4k
Efficient Content Optimization with Google Search Console & Apps Script
katarinadahlin
PRO
1
610
brightonSEO & MeasureFest 2025 - Christian Goodrich - Winning strategies for Black Friday CRO & PPC
cargoodrich
3
730
How to Ace a Technical Interview
jacobian
281
24k
Building Experiences: Design Systems, User Experience, and Full Site Editing
marktimemedia
0
530
A better future with KSS
kneath
240
18k
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
420
How to Align SEO within the Product Triangle To Get Buy-In & Support - #RIMC
aleyda
2
1.5k
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