Slide 1

Slide 1 text

弁護士ドットコム株式会社 Nobuaki Kambe webpack 依存からの脱却! 快適フロントエンド開発を Vite で実現する 2025年10月25日

Slide 2

Slide 2 text

© 2025 Bengo4.com, inc. 自己紹介 Nobuaki Kambe 所属 弁護士ドットコム株式会社 開発本部 クラウドサイン Product Engineering部 担当業務 クラウドサイン フロントエンド 趣味 バイク・映画鑑賞・漫画 2

Slide 3

Slide 3 text

会社紹介 3 3 © 2025 Bengo4.com, inc.

Slide 4

Slide 4 text

© 2025 Bengo4.com, inc. VISION まだないやり方で、世界を前へ。 Drive a paradigm shift for the better world. MISSION 「プロフェッショナル・テック 」で、 次の常識をつくる。 Be the Professional-Tech Company. プロフェッショナルだからできること。 専門知とテクノロジーで、社会に貢献する。 4

Slide 5

Slide 5 text

© 2025 Bengo4.com, inc. 5 5 5 税理士に無料で相談・検索できる日本最大級の 税務相談ポータルサイト 最新の法改正や実務について分かりやすく解説する 日本最大級の企業法務ポータルサイト クラウドサイン は、弁護士ドットコム が運営するサービスです OUR SERVICE AI基盤技術「 LegalBrain 1.0」を組み込んだ リーガル特化型 AIエージェント 契約の締結から管理までデジタルで完結させる 契約マネジメントプラットフォーム 時事問題の弁護士解説を中心としたメディア 日本最大級の無料法律相談ポータルサイト 弁護士事務所、企業法務職向け人材紹介事業

Slide 6

Slide 6 text

© 2025 Bengo4.com, inc. 契約締結から契約書管理まで可能な クラウド型の電子契約 サービス 契約交渉が済んだ完成済の契約書をアップロードし、相手方が承認するだけで契約を締結することができます 書類の受信者はクラウドサインに登録する必要がありません 6

Slide 7

Slide 7 text

© 2025 Bengo4.com, inc. 7 Index © 2025 Bengo4.com, inc. ● ● ● ● ● 従来の開発環境における課題 解決策 実装 成果&まとめ おわりに

Slide 8

Slide 8 text

従来の開発環境における課題 8 © 2025 Bengo4.com, inc.

Slide 9

Slide 9 text

© 2025 Bengo4.com, inc. 組織の拡大 ● エンジニアの人数が年々増加 ● 機能要求の多様化 AI 時代の開発が加速 ( Claude Code、Cursor、GitHub Copilot、Kiro等 ) ● 開発のスピードアップを実現 前提:クラウドサインの状況 ● クラウドサインは、2025年10月19日で10周年 ● レガシーなライブラリと共存しながら webpack でビルドしていた 従来の開発環境における課題 9 節目

Slide 10

Slide 10 text

© 2025 Bengo4.com, inc. 今後も システムの安定稼働 を担保した上で 開発のスピードをあげるための仕組みが重要となってくる 従来の開発環境における課題 10

Slide 11

Slide 11 text

© 2025 Bengo4.com, inc. 従来の開発環境における課題 その中で、開発時にボトルネックとなっていたこと 11

Slide 12

Slide 12 text

© 2025 Bengo4.com, inc. 12 ● ビルド時間:約 90秒 ● 開発サーバー起動時間:約 90秒 ● HMR反映時間:約 4秒 開発環境でかかっていた “ 待ち時間 ” 従来の開発環境における課題 開発生産性の課題

Slide 13

Slide 13 text

© 2025 Bengo4.com, inc. 13 ● バグ修正、 Hotfix対応で迅速な反映ができない ● 長い待ち時間により集中力が切れてコンテキストスイッチが難しい ● 1日に複数回デプロイするため、トータルでのタイムロスが大きい 課 題 従来の開発環境における課題 開発生産性の課題 開発環境でかかっていた “ 待ち時間 ” ● ビルド時間:約 90秒 ● 開発サーバー起動時間:約 90秒 ● HMR反映時間:約 4秒

Slide 14

Slide 14 text

解決策 14 © 2025 Bengo4.com, inc.

Slide 15

Slide 15 text

© 2025 Bengo4.com, inc. 15 解決策 これらの課題を解決するために webpack から Vite への移行に踏み切った

Slide 16

Slide 16 text

© 2025 Bengo4.com, inc. 16 解決策 具体的な移行の実装に入る前に Vite の特徴を整理

Slide 17

Slide 17 text

© 2025 Bengo4.com, inc. 17 解決策 Vite の特徴 ● 事前バンドルで esbuild を使用している(Go 言語で開発) ● JavaScript ベースよりも 10 倍から 100 倍高速 ● ネイティブな ES module で動的に配信 ● 一部、ブラウザに処理を移譲している 開発モード esbuild 本番モード ● 柔軟なプラグインの追加が可能 ● 最適化が優れているため、バンドルサイズ を小さくすることができる (圧縮・Tree-shaking 等) Rollup

Slide 18

Slide 18 text

© 2025 Bengo4.com, inc. 18 解決策 Vite の特徴 ● 事前バンドルで esbuild を使用している(Go 言語で開発) ● JavaScript ベースよりも 10 倍から 100 倍高速 ● ネイティブな ES module で動的に配信 ● 一部、ブラウザに処理を移譲している 開発モード esbuild 本番モード Rollup 全てのファイルをバンドルする従来のバンドルベースの開発と代わり、 必要な時に必要なモジュールを読み込むネイティブ ESM ベースとなっている ● 柔軟なプラグインの追加が可能 ● 最適化が優れているため、バンドルサイズ を小さくすることができる (圧縮・Tree-shaking 等)

Slide 19

Slide 19 text

© 2025 Bengo4.com, inc. 19 解決策 Vite の特徴 開発時 開発者の 生産性を向上 本番時 エンドユーザーの パフォーマンスの向上

Slide 20

Slide 20 text

実装 20 © 2025 Bengo4.com, inc.

Slide 21

Slide 21 text

© 2025 Bengo4.com, inc. 21 実装 Vite の特徴を整理した上でお話したいこと Backend Integration の実装 Backend Integration

Slide 22

Slide 22 text

© 2025 Bengo4.com, inc. ● マルチページアプリケーション (約150個のページが存在) ● Go Revel HTML テンプレート に対して、createApp を使用して Vue コンポーネントをマウント 22 実装 クラウドサインのフロントエンドの前提 HTML Entry Point Page Components Backend Integration

Slide 23

Slide 23 text

© 2025 Bengo4.com, inc. 23 実装 このような前提の元、 既存の Go Revel フレームワークを変更することなく モダンな Vite 開発環境の恩恵を享受する ための実現手法 Backend Integration

Slide 24

Slide 24 text

© 2025 Bengo4.com, inc. 24 実装 Vite の公式が推奨している標準的な統合パターンである Backend Integration を採用 https://ja.vite.dev/guide/backend-integration  Backend Integration

Slide 25

Slide 25 text

© 2025 Bengo4.com, inc. 25 ● build.outDir : public/vite配下を指定 ● build.manifest : manifest.jsonという文字列を指定。これにより、build.outDir からの相対パスとしてファイルを出力する ことが可能(true だと.vite/manifest.jsonになる) ● build.emptyOutDir : true を指定。これにより、ビルド時に出力先のディレクトリを空にすることができる ※manifest.json の有無で環境を判定できるようにするための対応 build: {    ... outDir: '../go/src/bengo4/cloudsign/public/vite', manifest: 'manifest.json', emptyOutDir: true, }, Vite の設定ファイル

Slide 26

Slide 26 text

© 2025 Bengo4.com, inc. 26 ● Vite dev serverとGo のサーバーを連携させ るためプロキシと HMR の統合の設定をする ● この設定により、開発時でもログイン状態や 認証の維持が可能となっている server: { port: 8080, host: 'localhost', proxy: { '^/(?!src/|node_modules/|@vite/client|@id/).*': { target: {proxyTargetUrl}, changeOrigin: true } }, hmr: { protocol: 'wss', host: 'localhost', port: 8080 } } Vite の設定ファイル

Slide 27

Slide 27 text

© 2025 Bengo4.com, inc. 27 manifest.json の中身の例 ● 本番環境時にサーバー側がこの構造を見て どのファイルを読み込むか、ファイルに対して依 存しているファイルが何かが記載されている https://ja.vite.dev/guide/backend-integration // Record 構造になっています // 各チャンクは、 ManifestChunk インターフェイスに従っています "src/pc/pages/DashboardIndex/index.ts": { "file": "js/DashboardIndex.min.js", "name": "DashboardIndex", "src": "src/pc/pages/DashboardIndex/index.ts", "isEntry": true, "imports": [ "_vendor.min.js", "_index.min.js", "_CsButton.min.js", "_CsInput.min.js", "_CsDialog.min.js", ... ] }, ... }

Slide 28

Slide 28 text

© 2025 Bengo4.com, inc. 28 "scripts": { "dev": "rm -rf ../go/src/bengo4/cloudsign/public/vite/** && vite", "build": "vue-tsc && vite build", }, 環境判定の仕組み ● manifest.json の存在チェックで環境を判定するようにした ○ manifest.json 有り...prd 環境 ○ manifest.json 無し...dev 環境 ● npm run dev を実行した時に明示的なパスを指定して、viteの中身を削除している (manifest.jsonも削除される) ● npm run build を実行した時は、build.outDirの指定先にmanifest.json を生成している

Slide 29

Slide 29 text

© 2025 Bengo4.com, inc. 29 Backendの対応 ● Go側でアプリケーション起動時に、InitVite とい う関数を発火するようにしている ※アプリケーション起動時= revel.onAppStart ● manifest.json の存在を確認して、 isRunDevServer という変数に存在する・ しないの bool 値 を設定 ● その変数をフロント側に渡すことで 本番環境 or 開発環境かを判定している var ( isRunDevServer bool viteManifest ViteManifest ) func InitVite() { var err error manifestFile, err := os.Open("./public/vite/manifest.json") if err != nil { revel.AppLog.Error("Vite Failed to open manifest.json", err) // vite/manifest.json が存在しない場合は dev server で動作しているとする isRunDevServer = true return } defer manifestFile.Close() if err := json.NewDecoder(manifestFile).Decode(&viteManifest); err != nil { revel.AppLog.Error("Vite Failed to decode manifest.json", err) // エラーの場合も開発モードとして扱う isRunDevServer = true return } ... isRunDevServer = false }

Slide 30

Slide 30 text

© 2025 Bengo4.com, inc. 30 revel.TemplateFuncs["js"] = func(entryPoint string) string { // 開発サーバーで動作している場合 if isRunDevServer { // 開発サーバーのパスを返す return fmt.Sprintf("/%s", entryPoint) } // manifest.json が存在しない場合 if viteManifest == nil { return "" } // 指定されたエントリーポイントが manifest.json に存在しない場合 entry, ok := viteManifest[entryPoint] if !ok { return "" } // エントリーポイントに file プロパティが存在しない場合 if entry.File == "" { return "" } return fmt.Sprintf("/vite/%s", entry.File) }   js:entryPoint に対応する js のパスを返す Backendの対応 〈 Go の関数の中身 〉   isRunDevServer:開発サーバーで   動作しているかを判定する   appendif:value がゼロ値ではない場合に     append を実行する revel.TemplateFuncs["appendif"] = func(viewArgs map[string]any, key string, value any) template.JS { if truth, _ := template.IsTrue(value); !truth { return template.JS("") } if viewArgs[key] == nil { viewArgs[key] = []any{value} } else { viewArgs[key] = append(viewArgs[key].([]any), value) } return template.JS("") } revel.TemplateFuncs["isRunDevServer"] = func() bool { return isRunDevServer }

Slide 31

Slide 31 text

© 2025 Bengo4.com, inc. 31 {{- appendif . "moreScripts" (js "src/pc/pages/AccountLogin/index.ts") -}} Frontendの対応   共通HTMLテンプレート   各ページの HTMLテンプレート ※ AI を駆使して、約150のページ全てを一括実装 {{- if not isRunDevServer -}} {{- end -}} {{if isRunDevServer}} {{end}} ● 共通テンプレートで環境別の処理 ● 各ページのテンプレートは対応しているエントリーファイルを渡して読み込む ● CSSは全てのファイルをまとめている( vite/css/style.css に出力) ポ イ ン ト

Slide 32

Slide 32 text

© 2025 Bengo4.com, inc. 32 dev の構成

Slide 33

Slide 33 text

© 2025 Bengo4.com, inc. 33 prd の構成

Slide 34

Slide 34 text

© 2025 Bengo4.com, inc. 34 実装 CSS 統合 CSS 統合 CSS 分割 各ページで必要なスタイルを読み込むた め、ページ移動のたびに新しい CSS をダ ウンロードする必要がある 設定ファイルが複雑になってしまう (出力された manifest.json の中身を見 て、依存している css を取得...) 最初に全部の CSS を読み込むのは時間 がかかる 複雑な設定が不要 (オプション1つの指定でOK) CSS を読み込んでしまえば、以降は キャッシュにより早く表示が可能 こちらを 選択 CSS分割・統合のメリット・デメリット

Slide 35

Slide 35 text

© 2025 Bengo4.com, inc. 35 実装 CSS 統合 build: {    ...    cssCodeSplit: false, }, CSSをまとめる 方向で決定 https://ja.vite.dev/config/build-options.html#build-csscodesplit メリット・デメリットとクラウドサインのサービスの使用用途上、 2回目以降のパフォーマンスが大事になってくることから CSS をまとめることに決定 実装も、build.cssCodeSplit のオプションを false にするだけでOK

Slide 36

Slide 36 text

成果&まとめ 36 © 2025 Bengo4.com, inc.

Slide 37

Slide 37 text

© 2025 Bengo4.com, inc. 37 webpack Vite 改善効果 ビルド 約90秒 約12秒 ※vue-tscの型チェック込み 87%短縮 開発サーバー起動 (初回表示まで) 約90秒 約2〜3秒 97%短縮 HMR反映時間 (ログイン画面) 約4秒 約0.5秒 88%短縮 成果 Vite 導入により ビルド時間による開発生産性が劇的に向上

Slide 38

Slide 38 text

© 2025 Bengo4.com, inc. ● Vite 公式 Backend Integration 採用 ○ 公式が推奨している方法で確実に対応することができた ● 環境判定は manifest.json ファイルの有無 ○ 複雑な設定が不要でシンプルに実装・判定 することができた 38 今回の Vite 移行が成功した理由 まとめ

Slide 39

Slide 39 text

おわりに 39 © 2025 Bengo4.com, inc.

Slide 40

Slide 40 text

© 2025 Bengo4.com, inc. おわりに We are Hiring 40

Slide 41

Slide 41 text

© 2025 Bengo4.com, inc. 41 https://creators.bengo4.com/ 弁護士ドットコム クリエイターズブログ更新しています。 ぜひご覧ください。 おわりに

Slide 42

Slide 42 text

© 2025 Bengo4.com, inc. 42 おわりに Vue Fes Japan 2025 After Talk でお話します! ● jQuery & jQuery UI との共存 ● webpack&プラグインの削除 ● storybookもViteでビルドできるようにする ● rolldown-viteの検証 今日お話できなかった その他の対応