
この記事は クラウドワークス グループ Advent Calendar 2025 シリーズ1の2日目の記事です。
クラウドソーシングサービス「クラウドワークス」(以下crowdworks.jp)のエンジニア bugfire です。
フロントエンド活動の振り返りをしてみよう
今年も振り返っていきます。 過去分は過去の振り返りにあります。
目次
フロントエンド活動の総括
crowdworks.jpの全体のフロントエンド活動を総括していきます。
AI の活用
Devin・Claude Code・GitHub Copilotなどを用いてコーディング・レビューなどを行っています。
デザインシステム norman が進化中
徐々に浸透して利用箇所が増えています。
normanコンポーネントライブラリ(以下norman components)で増えたものは以下のようなものがあります。
- Bookmark
- Card
- FlashMessage
- FrameGroup/FrameMessage
- ThanksButton
- Textarea
リデザイン
情報設計から変更を行うような大きな変更・利用するコンポーネントをデザインシステム norman を用いたものにするような小さな改善を組み合わせて、どんどん良くしていきます!
過渡期であるため、旧デザインと新デザインが混在している部分もありますが、徐々に解消していきます!
Vue Fes Japan 2025 への参加
今年も有志の方による参加が行われました!
日本でVue.jsを使っている企業一覧に追加
以下のレポジトリに追加依頼PRを作成し追加していただけました!
合同スプリント
合同スプリントは、チーム間の垣根を無くし、チームのドメインに依存しないこと、ロストボールや後回しになっていたことなど、エンジニア全体で取り組む機会として設定されています。
今年は4月と9月で2回実施され、どちらのスプリントでもチーム間の協力があり、フロントエンドの技術的負債をいくつか解消することができました。
フロントエンドでの改善についての一部をご紹介します。
負債の解消
ベストプラクティスは変遷していくため、今となっては負債となっているような実装がいくつもあります。
- Storybook上でスタイルがうまく当たっていないコンポーネントの修正
- Vue.jsのOptions APIをScript setupに変更
- グローバルなSCSS・CSSをコンポーネントに閉じたCSS Modules・Scoped CSS実装に修正
のような多彩な負債解消を行いました!
Node.js v22に更新
昨年v20に更新しましたが、今年はv22に更新を行いました。
10月にはv24もLTSとなったため、更新したいと考えています!
Vite対応のPoC
現状のシステムでViteに変更した場合の可能性を探るべく、Viteでバンドルの動作検証しました。 簡単な検証が行えたため、より深い検証を伴う移行を開始しました。
ドキュメントの充実
レポジトリ内のドキュメントも更新が行われています。
パッケージドキュメントの充実
昨年から追加されたパッケージドキュメントの充実が進んでいます。
バージョンアップ検証時の試験項目をパッケージドキュメントから抽出しdependabotの生成するPRに試験項目をチェックリストで自動的に追加しています。

Vue.js実装範囲の拡大
新規ではVue.jsを中心に実装を行い、既存の改修でも積極的にVue.jsとデザインシステムを利用しています。
Vitestへの移行完了
以下で移行開始したVitestへの移行ですが、完全に移行完了しました!
脱Sprocketsを行いWebpackとViteへ移行進行中
Sprocketsを用いている部分があるため、動作を保ったままWebpackとViteにコードを移動しています。
移行方法の詳細は 脱Sprockets詳細 にあります。
Viteへ移行進行中
StorybookやVitestではすでにViteを活用しておりましたが、メインのビルドにおいてもViteに移行を進めています。
Sprocketsの部分に関しては上の章で説明しました。 Webpackからの移動に関しては、ページ単位で動作確認を取りながら移行を進めています。
移行期であるため以下のような構成になっています。 目標は全てViteでビルドを行うことです。

フレームワークもVue.js一本化を行いたいため、順次進めていきます!
全社共通ヘッダーの導入
全社での体験を統一すべくトップの LP に追加されました。

おわりに
今年も多くのチームがフロントエンドの技術的負債解消やデザインの進化に取り組み、より良い開発環境が整いました。 crowdworks.jp では、フロントエンドなど事業上の課題に取り組みたい方を募集しています!
参考
過去の振り返り
engineer.crowdworks.jp qiita.com engineer.crowdworks.jp engineer.crowdworks.jp engineer.crowdworks.jp
脱Sprockets詳細
画像の移行
- 移行する全ての画像をimportするコードを用意して、Manifestを通じて画像パス・タグを生成するヘルパーを準備して移行しました。
- Webpack - Dependency Management | webpack
- Vite - Features | Vite
- 移動するファイルに関してはinline化を防ぎました。
- Webpack - 対象ファイルは
type: 'asset/resource'としてビルドを行いました。 - Vite - glob import 時に
query: '?no-inline'オプションを指定しました。
- Webpack - 対象ファイルは
- 念の為に表示を確認しながら、対応するhtml.erb全てで実行するヘルパーを書き換えていきました。
以上の方法でWebpackへの移行を挟みViteへ移行が完了しました。
CSSの移行
- 最初にSprockets特有のrequireを分解しました。
- ディレクトリ単位のrequire_directory・require_treeは全てファイル単位のフルパスのrequireに分解しました。
- require_selfは別ファイルに分離してrequireとしました
- ビルド結果が同一であれば動作検証としては完璧です。
- 次にrequireをSCSSの
@importに置き換えました。- 同様でビルド結果で検証できますが、多重require/importで動作が異なるため作業はいくらか必要です。
- 通常のSCSSになってしまえば、SCSSをimportするエントリ用のJS(TS)ファイルを作成して、そのファイルが依存するCSSを読み出す形のヘルパーを作ることで移行します。
以上の方法でWebpackへの移行を挟みViteへ移行が完了しました。
しかし @import は廃止されるため、時限爆弾となって残っています。
現在は新規で変更するケースは少ないため、オフラインで元バージョンでCSSに変換して、ビルドでは変換後のCSSを利用するなど対策が必要となります。
JavaScriptの移行
- CSS同様にSprockets特有のrequireを分解しました。
Sprocketsのエントリに対応したWebpackのエントリを作成し、Sprocketsの末尾のrequireをWebpackの先頭のimportに移動することで、極力動作に影響を与えないようにファイル単位で移動しています。
基本的に互換性を保つような移動をしていますが、複数ファイルから参照されている場合など実行順序を壊すことがあり、一度事故りました。
strictでないJavaScriptもあり、strictモードではエラーとなるため油断は禁物です。
現在は50%ほどWebpackに移行が完了しています。
gemからのasset移動
gemからSprocketsのassetとして追加されているJavaScriptなどは、Gemfileから外して一旦Sprockets上の通常ファイルとしてビルドシステムに組み込んだ上で、Webpackなどに移動していきます。
routesなど動的な部分に関しては、現状で freeze した上でフロントエンドでメンテナンスしやすい形に合わせていきます。