$30 off During Our Annual Pro Sale. View Details »
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
5
700
10ヶ月かけてstyled-components v4からv5にアップデートした話
2025-04-24 Qiita Conference 2025
uhyo
April 24, 2025
Tweet
Share
More Decks by uhyo
See All by uhyo
タグ付きユニオン型を便利に使うテクニックとその注意点
uhyo
2
830
ECMAScript仕様の最新動向: プロセスの変化と仕様のトレンド
uhyo
2
680
TypeScript 6.0で非推奨化されるオプションたち
uhyo
17
6.4k
Claude Code 10連ガチャ
uhyo
5
970
AI時代、“平均値”ではいられない
uhyo
8
3.4k
意外と難しいGraphQLのスカラー型
uhyo
5
950
RSCの時代にReactとフレームワークの境界を探る
uhyo
13
4.6k
知られざるprops命名の慣習 アクション編
uhyo
12
3.3k
libsyncrpcってなに?
uhyo
0
740
Other Decks in Technology
See All in Technology
M&Aで拡大し続けるGENDAのデータ活用を促すためのDatabricks権限管理 / AEON TECH HUB #22
genda
0
230
モダンデータスタックの理想と現実の間で~1.3億人Vポイントデータ基盤の現在地とこれから~
taromatsui_cccmkhd
2
260
マイクロサービスへの5年間 ぶっちゃけ何をしてどうなったか
joker1007
18
7.5k
[2025-12-12]あの日僕が見た胡蝶の夢 〜人の夢は終わらねェ AIによるパフォーマンスチューニングのすゝめ〜
tosite
0
160
Strands Agents × インタリーブ思考 で変わるAIエージェント設計 / Strands Agents x Interleaved Thinking AI Agents
takanorig
4
1.9k
株式会社ビザスク_AI__Engineering_Summit_Tokyo_2025_登壇資料.pdf
eikohashiba
1
100
20251222_サンフランシスコサバイバル術
ponponmikankan
2
140
20251219 OpenIDファウンデーション・ジャパン紹介 / OpenID Foundation Japan Intro
oidfj
0
470
まだ間に合う! Agentic AI on AWSの現在地をやさしく一挙おさらい
minorun365
17
2.5k
【開発を止めるな】機能追加と並行して進めるアーキテクチャ改善/Keep Shipping: Architecture Improvements Without Pausing Dev
bitkey
PRO
1
120
AWSの新機能をフル活用した「re:Inventエージェント」開発秘話
minorun365
2
420
アプリにAIを正しく組み込むための アーキテクチャ── 国産LLMの現実と実践
kohju
0
200
Featured
See All Featured
Large-scale JavaScript Application Architecture
addyosmani
515
110k
Leadership Guide Workshop - DevTernity 2021
reverentgeek
0
160
The Pragmatic Product Professional
lauravandoore
37
7.1k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
17k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
32
2.8k
Exploring anti-patterns in Rails
aemeredith
2
200
Lightning talk: Run Django tests with GitHub Actions
sabderemane
0
91
Build The Right Thing And Hit Your Dates
maggiecrowley
38
3k
Agile Leadership in an Agile Organization
kimpetersen
PRO
0
52
A Modern Web Designer's Workflow
chriscoyier
698
190k
Documentation Writing (for coders)
carmenintech
77
5.2k
Bioeconomy Workshop: Dr. Julius Ecuru, Opportunities for a Bioeconomy in West Africa
akademiya2063
PRO
0
31
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