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
5
650
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
RSCの時代にReactとフレームワークの境界を探る
uhyo
10
3.5k
知られざるprops命名の慣習 アクション編
uhyo
11
3k
libsyncrpcってなに?
uhyo
0
660
Next.jsと状態管理のプラクティス
uhyo
7
11k
更新系と状態
uhyo
9
3.7k
React 19アップデートのために必要なこと
uhyo
8
2.7k
color-scheme: light dark; を完全に理解する
uhyo
8
710
React 19 + Jotaiを試して気づいた注意点
uhyo
9
3.6k
TypeScriptの次なる大進化なるか!? 条件型を返り値とする関数の型推論
uhyo
3
3.3k
Other Decks in Technology
See All in Technology
人工衛星のファームウェアをRustで書く理由
koba789
15
8.1k
Practical Agentic AI in Software Engineering
uzyn
0
110
2025年になってもまだMySQLが好き
yoku0825
8
4.8k
なぜテストマネージャの視点が 必要なのか? 〜 一歩先へ進むために 〜
moritamasami
0
230
20250913_JAWS_sysad_kobe
takuyay0ne
2
230
Android Audio: Beyond Winning On It
atsushieno
0
880
「どこから読む?」コードとカルチャーに最速で馴染むための実践ガイド
zozotech
PRO
0
490
react-callを使ってダイヤログをいろんなとこで再利用しよう!
shinaps
1
250
AIのグローバルトレンド2025 #scrummikawa / global ai trend
kyonmm
PRO
1
300
AIエージェントで90秒の広告動画を制作!台本・音声・映像・編集をつなぐAWS最新アーキテクチャの実践
nasuvitz
0
200
今!ソフトウェアエンジニアがハードウェアに手を出すには
mackee
12
4.8k
slog.Handlerのよくある実装ミス
sakiengineer
4
270
Featured
See All Featured
Why You Should Never Use an ORM
jnunemaker
PRO
59
9.5k
Code Review Best Practice
trishagee
70
19k
Mobile First: as difficult as doing things right
swwweet
224
9.9k
A better future with KSS
kneath
239
17k
Embracing the Ebb and Flow
colly
87
4.8k
Optimising Largest Contentful Paint
csswizardry
37
3.4k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
30
9.7k
A designer walks into a library…
pauljervisheath
207
24k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
34
6k
Bash Introduction
62gerente
615
210k
RailsConf 2023
tenderlove
30
1.2k
Why Our Code Smells
bkeepers
PRO
339
57k
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