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
大規模サービスにおける レガシーコードからReactへの移行
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
MagicPod
February 28, 2026
Technology
410
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
大規模サービスにおける レガシーコードからReactへの移行
React Tokyo フェス 2026 スポンサーセッションの発表資料です。
MagicPod
February 28, 2026
More Decks by MagicPod
See All by MagicPod
はじめての MagicPod生成AI機能 機能紹介から活用方法まで
magicpod
0
170
プログラミング不要! テスト自動化における生成AI使いこなし術
magicpod
1
300
今日から始められるテスト自動化 〜 基礎知識から生成AI活用まで 〜
magicpod
1
540
昨年の開発まとめ&今年の展望 2026
magicpod
0
540
【NTTドコモ様】ドコモで実践するMagicPod活用による 開発の効率化と付随して得られたもの
magicpod
0
700
MagicPodオンボーディング 導入の流れと導入初期によくある質問
magicpod
0
170
MagicPod Autopilot開発者Q&Aセッション
magicpod
1
130
AIを活用した自動サービス MagicPodのご紹介
magicpod
0
89
ノーコード × 生成AIの MagicPod Autopilotを使ったE2Eテスト生成
magicpod
0
960
Other Decks in Technology
See All in Technology
10年目を迎えた「ABEMA」がどのように AI 活用を推進して、AI 駆動開発にシフトしているのか / How ABEMA, entering its 10th year, is promoting the use of AI and shifting toward AI-driven development
miyukki
0
360
探索・可視化・自動化を一本化 Amazon Quickでデータ活用スピードを上げる方法
koheiyoshikawa
0
160
AI Coding Agent時代のcdk-nagガードレール 〜組織ルールを強制CIで守り抜く設計の挑戦〜
mhrtech
3
480
なぜ、あなたのAPIは使われないのか? AX時代の設計原則、ガードレール、運用体制
yokawasa
1
190
インシデント事例と パッケージの全量解析に学ぶ ソフトウェアサプライチェーンの守り方 / supply-chain-attack-defense
flatt_security
0
840
複数プロダクトで進めるAI機能実装 ── 実践から得たリアルな学びとロードマップ実現への挑戦 / AICon2026_yanari
rakus_dev
0
260
シンガポールで登壇してきます
yama3133
0
340
DatabricksにおけるMCPソリューション
taka_aki
1
330
2026年のソフトウェア開発を考える(2026/07版) / Agentic Software Engineering 2026-07 Findy Edition
twada
PRO
18
7.6k
Type-safe IaC for Dart
coborinai
0
180
Kaggleで成長するために意識したこと
prgckwb
2
440
全社でのソフトウェアサプライチェーン攻撃対策をやってみた with Takumi Guard
z63d
0
200
Featured
See All Featured
Why Your Marketing Sucks and What You Can Do About It - Sophie Logan
marketingsoph
0
300
Docker and Python
trallard
47
4k
How GitHub (no longer) Works
holman
316
150k
How to Ace a Technical Interview
jacobian
281
24k
Design of three-dimensional binary manipulators for pick-and-place task avoiding obstacles (IECON2024)
konakalab
0
490
Future Trends and Review - Lecture 12 - Web Technologies (1019888BNR)
signer
PRO
0
3.6k
Speed Design
sergeychernyshev
33
1.9k
Heart Work Chapter 1 - Part 1
lfama
PRO
8
36k
The untapped power of vector embeddings
frankvandijk
2
1.8k
Game over? The fight for quality and originality in the time of robots
wayneb77
1
220
Taking LLMs out of the black box: A practical guide to human-in-the-loop distillation
inesmontani
PRO
3
2.3k
Thoughts on Productivity
jonyablonski
76
5.3k
Transcript
大規模サービスにおける レガシーコードからReactへの移行 React Tokyo フェス 2026 スポンサーセッション
Kosuke Takahashi 2021年外資系IT企業にエンジニアとして入 社。 2022年MagicPodにエンジニアとして入社。フ ロントエンドからサーバーサイド、運用等幅 広く経験。 MagicPod ソフトウェアエンジニア 自己紹介
AIが自動テストの作成からメンテナンスまでサポート。 効果的なテスト自動化で、開発全体の効率UPへ。 ノーコードテスト自動化ツール
目次 1.なぜReactに移行するのか? 2.課題の詳細 3.どのように移行するのか? 4.現時点の状況, まとめ
目次 1.なぜReactに移行するのか? 2.課題の詳細 3.どのように移行するのか? 4.現時点の状況, まとめ
認知コストが高く、保守性が乏しい HTMLファイル ファイル数: 139 総行数: 11160行 1番行数の多いファイル: 749行 CSSファイル ファイル数:
44 総行数: 13754行 1番行数の多いファイル: 1517行 JSファイル(jQuery) ファイル数: 47 総行数: 28381行 一番行数の多いファイル: 5397行 React移行前: 2022年2月 ×モジュール管理 😥 ×コンポーネント分割 😥
目次 1.なぜReactに移行するのか? 2.課題の詳細 3.どのように移行するのか? 4.現時点の状況, まとめ
$(“#area_1”).on(“click”, function (e) { // IDセレクタイベントの登録 ... } $(“#area_2”).on(“click”, function
(e) { // IDセレクタイベントの登録 ... $(“#area_1”).trigger(“click”); // 別セレクタのイベント発火 ... } $(“#area_1_1”).on(“click”, function (e) { // IDセレクタイベントの登録 ... e.stopPropagation(); // イベントの伝播をやめる ... } $(“.container”).on(“click”, function (e) { // クラスセレクタイベントの登録 ... } $(“#area_2”).addClass(“container”); // クラスの付与 課題1: イベント管理の複雑化 area_1_1 area_1 area_2 何でも書けてしまうが故に、メンテナンスが難しい 😥 認知コストが高く、変更容易性は低い 😥 レガシーコード(jQuery)
$(“#area_1”).on(“click”, function (e) { // IDセレクタイベントの登録 ... } $(“#area_2”).on(“click”, function
(e) { // IDセレクタイベントの登録 ... $(“#area_1”).trigger(“click”); // 別セレクタのイベント発火 ... } $(“#area_1_1”).on(“click”, function (e) { // IDセレクタイベントの登録 ... e.stopPropagation(); // イベントの伝播をやめる ... } $(“.container”).on(“click”, function (e) { // クラスセレクタイベントの登録 ... } $(“#area_2”).addClass(“container”); // クラスの付与 課題1: イベント管理の複雑化 どのHTML要素に、どのイベントが紐づいているかわかりやすい 😄 const AreaButtons = { funcA, funcB, funcC, }: prpps) => { return ( <button id=”area_1" onclick=funcA /> <button id=”area_2" onclick=funcB /> <button id=”area_1_1" onclick=funcC /> ) } レガシーコード(jQuery) React
global変数, var, letの乱用 😥 型がわからない 😥 /* global global_variable_a, global_variable_b,
global_c, function_a, promise_function_a */ /* exported variable_d, function_b, $element_a */ let variable_a = null; var variable_b = 0; const default_value = 100; ... function abc() { variable_a = “xxx”; if (varible_b == “yyy”) { varible_b = default_value + 10; } } ... abc(); 課題2: 状態管理の複雑化 レガシーコード(jQuery)
const, 型で安心 😄 /* global global_variable_a, global_variable_b, global_c, function_a, promise_function_a
*/ /* exported variable_d, function_b, $element_a */ let variable_a = null; var variable_b = 0; const default_value = 100; ... function abc() { variable_a = “xxx”; if (varible_b == “yyy”) { varible_b = default_value + 10; } } ... abc(); 課題2: 状態管理の複雑化 export const funcA = ( variable_a: number, fvariable_b: number, ) => { const default_value = 100; const variable_c = variable_a + fvariable_b; const [showSomething, setShowSomething] = useState(false); const funcABC = () => { if (variable_c > default_value) { setShowSomething(true); } }; return { variable_c, funcABC, }; }; レガシーコード(jQuery) React
課題3: UIロジックと状態管理ロジックの混在 UIを生成するロジックと、状態管理のロジックが混在することにより可読性と保守性が下がる 😥 テストが書きづらい 😥 function abc() { let
first_name = $(“#area_1”).data(“first_name”); if (first_name == “”) { first_name = “default_first_name”; } let last_name = $(“#area_1”).data(“last_name”); if (last_name !=) { last_name = last_name + “ san”; } $('<div/>') .data(“first_name”, first_name) .data(“last_name”, last_name) .appendTo('#area_1'); } レガシーコード(jQuery)
課題3: UIロジックと状態管理ロジックの混在 function abc() { let first_name = $(“#area_1”).data(“first_name”); if
(first_name == “”) { first_name = “default_first_name”; } let last_name = $(“#area_1”).data(“last_name”); if (last_name !=) { last_name = last_name + “ san”; } $('<div/>') .data(“first_name”, first_name) .data(“last_name”, last_name) .appendTo('#area_1'); } それぞれの関心ごとでファイルを分割することで、可読性と保守性が上がる 😄 テストが書きやすい 😄 // index.tsx const componentA = ({firstName, lastName}) => { const [updatedFirstName, updatedLastName] = useComponentA(firstName, lastName); return ( <div id="area_1"> <div data-first-name={first_name} data-last-name={last_name}></div> </div> ); } // hooks.ts export const useComponentA = (firstName: string, lastName: string) => { const updatedFirstName = firstName || "defaultFirstName"; const updatedLastName = lastName || "defaultLastName"; return { updatedFirstName, updatedLastName, }; }; React レガシーコード(jQuery)
目次 1.なぜReactに移行するのか? 2.課題の詳細 3.どのように移行するのか? 4.現時点の状況, まとめ
Django (+ jQuery) As-Is, To-be Django (+ React) S3 (React)
nginx nginx CloudFront あるべき姿 現状
Django (+ jQuery) As-Is, To-be Django (+ React) S3 (React)
nginx nginx CloudFront あるべき姿 現状 今回の範囲
Django側(HTML, jQuery) 移行するページやコンポーネントに対して、任意のidを適用する React側 付与したidから要素を取得し、それをReact rootとしDOMを構築する const domNode = document.getElementById(”rootA”);
const root = createRoot(domNode); root.render( <ComponentA/> ); 移行方法(静的) <div id="rootA"></div> HTML, jQuery React
Pub/Subで、動的なイベントをハンドルする react_main.jQueryEventHub.publish({ eventName: “ChangeEvent”, data: { message: “sampleMessage” } })
移行方法(動的) useEffect(<T extends GuidanceKeys>() => { const deviceAlertSubscription = jQueryEventHub.subscribe<{ message: string; }>('ChangeEvent', (event) => { const message = event.data.message; if (message == “sampleMessage”) { showMessage(message); } }); return () => subscription.unsubscribe(); }, []); HTML, jQuery React
機能フラグによる段階的リリース 完成したコンポーネントから即時リリース 少数ユーザーへ段階的に公開し、全ユーザーへの影響を最小化 E2Eテストによる品質担保 MagicPodを使用した自動テスト 複数ユースケースの検証 画像差分チェックによるスタイル崩れ検知 バグバッシュ チームで変更箇所周辺を探索的にテスト リリース戦略
目次 1.なぜReactに移行するのか? 2.課題の詳細 3.どのように移行するのか? 4.現時点の状況, まとめ
移行の現状 (jQuery → jQuery+React) HTMLファイル(index.tsx) ファイル数: 499 総行数: 63550行 1番行数の多いファイル:
1308行 CSSファイル(style.ts) ファイル数: 347 総行数: 22409行 1番行数の多いファイル: 432行 JSファイル(hooks.ts) ファイル数: 369 総行数: 47998行 1番行数の多いファイル: 2671行 HTMLファイル ファイル数: 139 総行数: 11160行 1番行数の多いファイル: 749行 CSSファイル ファイル数: 44 総行数: 13754行 1番行数の多いファイル: 1517行 JSファイル ファイル数: 47 総行数: 28381行 一番行数の多いファイル: 5397行 HTMLファイル ファイル数: 104 総行数: 7264行 1番行数の多いファイル: 959行 CSSファイル ファイル数: 31 総行数: 13554行 1番行数の多いファイル: 2468行 JSファイル ファイル数: 34 総行数: 28782行 1番行数の多いファイル: 7743行 レガシーコード レガシーコード React 2022年2月 2026年2月(新機能含む)
良かったこと 新機能を開発しやすい 1ファイルあたりの行数が抑えられている 可読性, 変更容易性が向上 チームや組織でデザインの基準を合わせられる コンポーネント管理, 再利用可能 テストコードが増える 主にロジック(hooks.ts)のテストが増える
保守性が向上 トラブルやバグが発生した時に、テストを書いて修正ができる AIの進化 今後、より簡単に移行が進められる可能性がある
苦悩・課題感 教育・キャッチアップコスト jQuery中心だったエンジニアの学習コスト 他チームへの教育・知識共有 レガシーコード移行の難しさ 仕様が曖昧な既存コードの存在 元のコードがレガシーだと、移行後のコードもレガシー 移行に伴う工数増加 既存コードの理解に時間を要する 肥大化したファイルの分割・移行コスト
ユーザーへのインパクト 単なる技術的な移行では、コストの割にインパクトが少ない ビジネスメンバーの理解を得づらい
AIが自動テストの作成からメンテナンスまでサポート。 効果的なテスト自動化で、開発全体の効率UPへ。 ノーコードテスト自動化ツール
特徴1:ノーコードでテスト自動化が可能 1 テストステップを作成 テスト結果と結果詳細画面への導線 画面上から テスト対象要素を選択 要素自動検出を開始 2 3 4
テスト対象アプリケーションに変更等があると、そのままではテストは失敗してしまいます。 MagicPodのAIはテストを自動で修復して実行を継続。実行後に修正案を提案します。 自動修復が働くと「要確認」 と表示されます ! 特徴2:AIによる自動修復でメンテナンス工数を低減
これからのテスト自動化:作成〜運用をAIがサポート MagicPod Autopilot ユーザーの指示に基づき、テスト を自動で作成します。既存テスト の修正などにも幅広く対応しま す。 画面の内容やテキストを理解し、 従来は人間が検証する必要があっ たテスト項目も自動化します。
UIに変更があった場合に、AIがテ ストケース側の修正を提案・修復 します。 AIアサーション AI自動修復 テスト作成 結果確認 テストメンテナンス MagicPodは、テスト作成のMagicPod Autopilot、結果確認のAIアサーション、 メンテナンスのAI自動修復と、AIの力で自動テストを幅広くサポート。
Autopilotのチャットから指示を出します。 Autopilotのチャット形式の入力欄に「***を行うテストを作成して」などの指示を 出すことで、Autopilotが自動で適切なテストを検討・作成し実行します。 AIによる自動テストの作成
結果が期待通りかどうか、AIが合否判定 「表示された商品がすべてクリスマス関連 のものであること」をAIで確認 ハロウィーン関連の商品が 表示されています! 整合性を確認するテスト ネットショップで、検索ワードに対して正しい商品一覧が表示されているかを確認する。 例 1 2
3 検索欄に「クリスマス雑貨」を入力 「検索」ボタンを押す Failed! Failed! クリスマス雑貨
None