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
300
1
Share
大規模サービスにおける レガシーコードからReactへの移行
React Tokyo フェス 2026 スポンサーセッションの発表資料です。
MagicPod
February 28, 2026
More Decks by MagicPod
See All by MagicPod
プログラミング不要! テスト自動化における生成AI使いこなし術
magicpod
1
170
今日から始められるテスト自動化 〜 基礎知識から生成AI活用まで 〜
magicpod
1
270
昨年の開発まとめ&今年の展望 2026
magicpod
0
360
【NTTドコモ様】ドコモで実践するMagicPod活用による 開発の効率化と付随して得られたもの
magicpod
0
460
MagicPodオンボーディング 導入の流れと導入初期によくある質問
magicpod
0
120
MagicPod Autopilot開発者Q&Aセッション
magicpod
1
120
AIを活用した自動サービス MagicPodのご紹介
magicpod
0
67
ノーコード × 生成AIの MagicPod Autopilotを使ったE2Eテスト生成
magicpod
0
730
ブランチ機能でQAチームのコラボレーションを加速しよう
magicpod
0
410
Other Decks in Technology
See All in Technology
2026年度新卒技術研修 サイバーエージェントのデータベース 活用事例とパフォーマンス調査入門
cyberagentdevelopers
PRO
7
7.8k
システムは「動く」だけでは 足りない - 非機能要件・分散システム・トレードオフの基礎
nwiizo
26
8.4k
Master Dataグループ紹介資料
sansan33
PRO
1
4.6k
AI環境整備はどのくらい開発生産性を変えうるか? #AI駆動開発 #AI自走環境
ucchi0909
0
130
NOSTR, réseau social et espace de liberté décentralisé
rlifchitz
0
160
ログ基盤・プラグイン・ダッシュボード、全部整えた。でも最後は人だった。
makikub
5
1.7k
AIエージェントを構築して感じた、AI時代のCDKとの向き合い方
smt7174
1
190
ふりかえりを 「あそび」にしたら、 学習が勝手に進んだ / Playful Retros Drive Learning
katoaz
0
460
ある製造業の会社全体のAI化に1エンジニアが挑んだ話
kitami
2
900
Introduction to Bill One Development Engineer
sansan33
PRO
0
400
あるアーキテクチャ決定と その結果/architecture-decision-and-its-result
hanhan1978
2
590
え!?初参加で 300冊以上 も頒布!? これは大成功!そのはずなのに わいの財布は 赤字 の件
hellohazime
0
140
Featured
See All Featured
Stop Working from a Prison Cell
hatefulcrawdad
274
21k
Evolving SEO for Evolving Search Engines
ryanjones
0
180
JAMstack: Web Apps at Ludicrous Speed - All Things Open 2022
reverentgeek
1
410
Google's AI Overviews - The New Search
badams
0
960
Writing Fast Ruby
sferik
630
63k
Product Roadmaps are Hard
iamctodd
PRO
55
12k
Ethics towards AI in product and experience design
skipperchong
2
250
DevOps and Value Stream Thinking: Enabling flow, efficiency and business value
helenjbeal
1
160
Information Architects: The Missing Link in Design Systems
soysaucechin
0
870
[SF Ruby Conf 2025] Rails X
palkan
2
930
<Decoding/> the Language of Devs - We Love SEO 2024
nikkihalliwell
1
180
Pawsitive SEO: Lessons from My Dog (and Many Mistakes) on Thriving as a Consultant in the Age of AI
davidcarrasco
0
110
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