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
800
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
AIのReact習熟度を測る
uhyo
2
720
React、まだ楽しくて草
uhyo
7
4.5k
TypeScript 7.0の現在地と備え方
uhyo
6
3.4k
React 19時代のコンポーネント設計ベストプラクティス
uhyo
20
9.9k
型定義でAIと会話する:型を通じてAIに意図を伝えるテクニック
uhyo
1
93
タグ付きユニオン型を便利に使うテクニックとその注意点
uhyo
3
1.1k
ECMAScript仕様の最新動向: プロセスの変化と仕様のトレンド
uhyo
3
910
TypeScript 6.0で非推奨化されるオプションたち
uhyo
18
8.4k
Claude Code 10連ガチャ
uhyo
4
1.1k
Other Decks in Technology
See All in Technology
フロントエンドイチゲキ実装 ― Figmaデザインと画面設計書からAIに実装・テストを書かせるための”下ごしらえ” / 20260627 Yusuke Mazuka
shift_evolve
PRO
0
120
AI時代における最適なQA組織の作り方
ymty
3
320
Oracle Exadata Database Service on Cloud@Customer X11M (ExaDB-C@C) サービス概要
oracle4engineer
PRO
2
8.3k
AWS Summit 2026で見えたSIerにとっての Amazon Quickの位置づけ
maf_0521
0
150
LiDAR SLAMの実装とセンサ融合 ~Lie群からContinuous-Time LIOまで~
naokiakai
1
760
初めてのDatabricks勉強会
taka_aki
2
220
AIで政治は変わるのか? — 中高生と考えたAI時代の民主主義(東海高校サタデープログラム)
eitarosuda
0
330
AWS PrivateLink × SCIM で実現する セキュアで運⽤負荷の低い Databricks 基盤の構築
tsuda7
0
130
クラウドファンディング版StackChan 3体(4体)をインタラクティブな体験型作品にして展示もした話 / スタックチャンお誕生日会2026
you
PRO
0
270
デジタル・デザイン構想 by Sayaka Ishizuka
y150saya
0
160
データレイクの「見えない問題」を可視化する
sansantech
PRO
1
260
「軸足」は 固定しなくていい - 熱量と強みで描く、しなやかなキャリアの形
kakehashi
PRO
1
310
Featured
See All Featured
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.7k
Chasing Engaging Ingredients in Design
codingconduct
0
230
Information Architects: The Missing Link in Design Systems
soysaucechin
0
990
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
12
1.2k
Navigating the Design Leadership Dip - Product Design Week Design Leaders+ Conference 2024
apolaine
1
360
End of SEO as We Know It (SMX Advanced Version)
ipullrank
3
4.2k
Dominate Local Search Results - an insider guide to GBP, reviews, and Local SEO
greggifford
PRO
0
200
Why Mistakes Are the Best Teachers: Turning Failure into a Pathway for Growth
auna
0
170
svc-hook: hooking system calls on ARM64 by binary rewriting
retrage
2
320
Breaking role norms: Why Content Design is so much more than writing copy - Taylor Woolridge
uxyall
0
330
Visualization
eitanlees
152
17k
Fantastic passwords and where to find them - at NoRuKo
philnash
52
3.7k
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