はじめに
Webフロントエンド開発を中心に行っている寺島です。
これから何回か分けて、Oisix の EC サイト に対して行っているWeb フロントエンドの刷新プロジェクトについて紹介していきます。
本記事では、プロジェクトの目的やプロジェクト開始時の状態を示したうえで、採用しているアプローチや進め方について紹介します。
本記事以外の残りの記事では以下について紹介する予定です。
- 刷新プロジェクトにおけるフロントエンドのアーキテクチャ
- 採用している技術やその利用方法
- 刷新プロジェクトを進めた結果と現状・今後の展望
Web フロントエンド刷新プロジェクトの目的・背景
Oisix は 2021 年末時点で創業から 21 年が経過しています。
その一方で、 EC サイトである oisix.com は一度も再構築などがされておらず、創業当時のコードベースから継ぎ足されながら開発が今も行われています。
当然ながら今に至るまでに、事業自体、開発のスタイル、トレンド技術など様々な事柄に変化が起きており、それがコードへ反映されています。 結果、継ぎ足され続けたソースコードが原因となって、お客様により魅力的なサービスをお届けすることが遅くなってしまうことがあります。
そういった問題を解決するために、ソフトウェアやインフラをモダンなものに置き換えて、 お客様により早くよりよい価値を提供していけるようにすることを目的に刷新プロジェクトが始まりました。
Web フロントエンドにおいては、技術的に JSP (JavaServer Pages) と jQuery を中心とした JavaScript ライブラリで UI が構成されています。 したがって、これらをモダンな技術ベースに置き換えていくというのが第一の目標となります。
また、刷新のスコープですが、ECサイトは PC とスマートフォンのページが別々に作成されています。 そこで、まずは利用者の割合が多いスマートフォンのページのみをターゲットとしています。
プロジェクト開始時の状況
私が入社したのは 2019年の 7 月で、当時のリーダのもとでプロジェクトを進める開発者として参画しました。入社以前からプロジェクトは動いており、資料をたどると 2018年の後半ごろからプロジェクトはスタートしてるようでした。
一方で、現状のプロジェクトの基礎ができたのは 2019年の10月ごろです。そのため、2019年の10月ごろをプロジェクトの開始時として、それ以前のプロジェクトを ”前身プロジェクト” と表現します。
この章では、プロジェクトの開始時やそれ以前の状況を以下の観点で紹介します。
- ソフトウェアの状態
- 組織の状態
- 前身プロジェクトの状態
また、以降に示すのはプロジェクト開始当時に見たソフトウェア開発に限った観点の話です。 20年近くの間、これらのソフトウェアやソフトウェアを作ってきた人たちが事業を継続し成長させてきたという事実は見逃せません。
したがって、現在に至るまでこのソフトウェアを作るのに携わってきた人や当時の判断を否定する意図はありませんしその意味もありません。
ただ、今の視点でソフトウェアやそれを取り巻く状況を直視しない限りプロジェクトを完遂することはできません。
ソフトウエアの状態
なんで動くかわからない
ECサイト自体は Java で構築されており基本的に自前のフレームワークがベースになっています。 フロントエンド部分は JSP で記述されており、バックエンドとフロントエンドはリポジトリ的に独立しています。また、リリースも独立して行われています。 フロントエンドで利用されるデータやロジックは MVC モデルのコントローラに相当する部分から公開されたオブジェクトを JSP で直接利用するか、JSP のカスタムタグを経由して利用することが基本です。
それが基本となる一方で、JSP の中に普通に Java コードでロジックが記述されていることも多々あります (基本とは...)。
加えて、JSP のカスタムタグなどの挙動も直感的ではなく、事前に特定のメソッドがコールされていることや状態を前提としているものがあり、 『理由はわからないけど、こう書かないと期待通り動かない』というものも存在します。 これは既存のソフトウェアをリファクタリングするうえで大きな心理的障壁にもなります。
コピペ駆動制作・増殖するバグ
EC サイトはサービスの性質上、毎週新しいコンテンツをリリースするのですが、自前のフレームワークや JSP 内に記述されているロジックなどに各機能が依存することがネックとなり一般的な CMS でのコンテンツ管理が困難です。 そのため、基本的にコンテンツは新しい JSP として記述されそれが蓄積されていくという状態です。
週次という比較的タイトなスケジュールで制作を行うことと、新しい JSP としてコンテンツを記述するという性質上、制作の現場は基本的にコピペ中心となっています。 結果として同じような内容のファイルが大量に存在するという状態になっています。
また、コピペをして必要な部分を変えるという発想になるためか、インラインスタイルシートやインラインスクリプトが大量に存在しました。 これらのスタイルやスクリプトは特定のライブラリや、別スクリプトに定義してあるグローバル関数などの前提条件を期待しますが、それらの整理も行われていなかったので、必要そうなものを適当に読み込んだり、そもそもコピペ元から全く触らないという姿勢になっていきます。
結果、コピー元のページでは使っていたけど新しいページでは使わないスクリプトがエラーになっていてそれに気が付かないままになっていたり、 CSSを変更したら全然意図していないところで表示が壊れるなどが発生する状況でした。 しかもこの問題を抱えたままコピペで増えていきます。
膨大なファイルたち
ファイルは現在 Git で管理されていますが、かつてはバージョン管理ツールの利用が一般的ではなかったです。 制作運用の中では、対象のサーバに都度必要なファイルを FTP でアップロードをすることでコンテンツのリリースを行っていたと聞いています。
その当時から、役割を終えたファイルの整理がほとんど行われていなかったという経緯があったようで、不要と思われる大量のコンテンツやファイルがサーバ上に存在している状態でした。 あるタイミングで管理の必要性を認識し、サーバからファイルを丸ごと取得して Git での管理を始めたらしいのですが、本プロジェクト開始当初は、JSP・CSS・JS が中心のファイル群が 10万ファイル以上存在していました (画像は含んでおらずそれを含むともっとあります...)。
この膨大なファイル数と、コピペを中心とした制作の結果、サイト全体的な対応が必要となる変更が発生した時には、使われているかどうかわからないファイル群なども変更対象に上がってきてしまい非常に非効率な作業を強いられる状態にありました。 また、刷新プロジェクトを進めるにあたっても、対象のスコープを定めることが難しく、このプロジェクトはいつ終わりますか?という当然の質問にも全く答えられないという状態です。
このように、コピペによってつくられた大量のファイルと重複した記述、インラインで記述された無秩序なスタイルととスクリプトというように、よく聞くヤバそうなやつを煮詰めて固めたような状態がプロジェクト開始時のソフトウェアの状態でした。
フロントエンド開発・制作を行う組織
弊社にはシステム本部というシステム開発などの役割を有した部署があり、私もそこに所属しています。 ただ、制作を含めたソフトウェアの開発を行う組織として集約されているかというとそうではありません。
ECサイトのコンテンツ制作や表示・インタラクションの開発は事業的な観点が強く関わります。 そこで、より素早く改良を行いお客様に提供するという目的で、企画などを行っている人たちと同じ、EC事業本部という組織に制作を行うコーダや開発を行うフロントエンドエンジニアが所属しているという体制をとっています。
システム本部の役割としては、EC サイトであればEC事業本部からの依頼などをトリガーにバックエンド部分の開発・改良を行います。 加えて、弊社では業務アプリケーションなども内製しているため、それらの開発を行うというような役割を持っています。
そのため、サービスに新たな機能を追加するなどバックエンドを含めた開発を行う場合は、EC事業本部から起案し、システム本部へ開発依頼を行い、優先度を加味したうえで順次処理していくという形をとっています。
EC サイトについて見ると、バックエンドとフロントエンドでコードリポジトリやリリースが独立しており、組織的にも分かれ、それぞれで意思決定を行いスピーディーに開発を進めることができるという意味で適切な形をとっているように見えます。 実際、スピーディーにお客様のニーズに応えてサービスを提供することができ、現在に至るまでサービスを維持・成長できたと思います。
一方で、フロントエンドのソフトウェアは前述のとおりの状況になってしまいました。
システム本部と EC 事業本部それぞれの組織もサービスを良いものとし、お客様により良い価値を提供したいという目的や思いは同じです。 しかし、それを実現するにあたって強く興味を持っている部分や責任は異なってます。
例えば、EC 事業本部は主に売り上げ等に関しての責任を持ち、より良い体験やサービスをお客様に早く提供することを重視します。 一方で、システム本部はシステムの安定稼働に関して責任をもち、ソフトウェアに対して保守性や拡張を重視します。
これらはいずれも重要でバランスをとることが必要です。 しかし、それぞれが独立したまま、それぞれの目標を達成しようと行動する結果、 例えば、フロントエンドの開発や制作において保守性などを軽視するという状況が発生したり、 新しいサービスの開発をEC 事業本部からシステム本部へ依頼した時にスピード感・コスト感が合わないといったことが起こりえます。
このような背景があり、例えば、フロントエンドの領域のみで目的を解決しようとして JSP 内に本来バックエンドで記述するべき Java ロジックが散乱するなどが発生したのだと思います。
これは、組織のサイロ化や個別最適化の例として広く知られているケースではあると思います。 お客様やサービスのために、それぞれの責任を果たそうとした結果、このような状態になったのではないかとプロジェクトの開始当時に感じました。
前身プロジェクトの失敗
私が入社する前からスタートし、入社後しばらくまで行われていた前身プロジェクトですが、 ある程度まで開発を進めていたものの、その成果ほとんどすべてを破棄し方針の再検討から仕切りなおすという提案をし、承認していただきました。
これに至った経緯などを以降で紹介します。
前身プロジェクトの方針
前身プロジェクトの方針は、特定のページをターゲットととし、そのページを Vue.js ベースのアプリケーション (MPA) として再構成するというものでした。 これは、既存のフロントエンドが無秩序であるという状態を考えれば、それらを白紙にして実装を行う方が安全なので、開発者の観点で考えれば自然な方針だったと思います。
前身プロジェクトの課題
再構成される要素には、すべてのページで利用される UI パーツ が存在しました。 サイト全体で用いられるグローバルヘッダーなどはその典型的な例です。 そのような UI パーツの中にはユーザに対して今週のおすすめ商品などを示すような、週次で更新されるコンテンツも多く含まれていました。
コンテンツは前述のとおり JSP にハードコードされているものなので、その時構築した Vue.js ベースのものとは独立して情報が存在する状態でした。 したがって、サイトや特定ページを停止させずに成立させるには、週次の制作運用に刷新後のアプリケーションを追従させる必要があります。 しかし、それを実現させる運用のアイディア (リソース・運用フロー) がないという状態で開発が進められていました。
このままではサイトの運用を維持したまま、継続して刷新を行うことが困難になることが予想されたので、後述する新方針の検討を行い当初の方針での開発中止を提案しました。
サイロ化と個別最適化について前述しましたが、この件も同様に特定の視点や目的にだけ基づいて方法や方針を決定してしまったことに起因した結果であろうと考えました。
プロジェクトの再スタート
ある程度進めていたプロジェクトの方針転換や、ここまで進めてきた実装を破棄するという判断は簡単にできるものではなかったと思いますが、提案に至った理由などを説明することで承認いただけました。 おそらく創業当時から存在するであろう、組織の機敏さや風通しのよさなどのおかげでプロジェクトを再スタートすることができたと感じています。
これらの経緯・状況を踏まえ、同様な失敗をしないように方針や開発の進め方を再定義しつつ今のプロジェクトがスタートしました。
刷新の方針・進め方
ここまでに紹介したような状況や失敗を踏まえて 開発・リリースは小さな単位で反復的に行う という点を重視しようと思いました。 具体的には以降に示す方針や進め方でプロジェクトをスタートしました。
技術的な方針
重視したい点を踏まえて、開発・リリースの単位はページではなく、 UI パーツとすべきと考えました。 変更の粒度を小さくすることで、リリース影響を小さくすることができ、必要な時に切り戻しも比較的簡単になります。 また、現状のアプリケーションについて知っていることが少ないことを踏まえると、開発ごとの調査範囲などを小さく区切りやすくなることもメリットになります。
一方で、現状のアプリケーションは前述のとおり無秩序なCSSとJSであふれており、UIパーツをデプロイしたとしても、意図しないDOMエレメントの変更・スタイルの上書きなどの影響を受け破壊される可能性が容易に想像できます。
本プロジェクトでは、この問題を解決するために Web Components を利用しています。 Web Components は基本的にWeb Components 外のスタイルの影響を受けず、意図ない限り jQuery などでDOMエレメントの変更がされません。 このような特徴は本プロジェクトの課題を解くためには最適なものであったため、前身プロジェクトで採用していた Vue.js で Web Components を実装し、JSPのマークアップ内で利用するという方針を基本としました。
この方針をとることで、基本は既存の JSP 内のロジックを活かしながら、徐々にその責任を Web Components に移動することができます。
また、UIパーツには以下が必要です。
- スタイルルール (どんな表示をするか)
- ユーザとのインタラクション (どんな振る舞いをするか)
- 表示データ (何を表示するか)
Web Components を使うだけで解決できるものもあれば工夫が必要なものもありました。 これらの具体的な解決方法などについては、次回以降の記事で紹介したいと思います。
開発の進め方
開発は2週間のタイムボックスで、開発・リリースすることを繰り返すスタイルで進めています。 タスクの管理には当初 GItHub Project を利用しており、現在は GItHub Project (Beta) を利用しています。 具体的な活用方法などについては別の機会があれば紹介できればと思います。
また、開発における各工程における作業手順や作成する文書、それらの典型的なパターンなどはプロジェクトの開始前にすべて文書化しそれに沿って開発を進めるようにしました。
というのも、前身プロジェクトの終わり際前後のタイミングでリーダを含めた担当者の退職や異動によって、このプロジェクトにアサインされている社員は私一人になってしまいました。 結果、私一人で諸々の方針や技術選定を行い、開発を協力会社の方々数名と進めていく必要がありました。
そんな中の特に走り始めにおいて、円滑に開発を進めていくには、作業をできるだけ形式化し迷うことをできるだけ減らすことが最も重要だと考えました。 そのような取り組みの結果、刷新対象に関する個別の難しさはありましたが、ある程度安定した開発を継続できました。 また、基本作業を形式化・文書化するということは文化としてチームに根付き、課題を発見したりするごとに文書を更新していくということを積極的に行うチームになっています。
開発の形式化は、新規メンバーの参加時にも有効でした。採用活動を進め開発メンバーが増えたときも、開発対象特有のわかりにくさや戸惑いはあるのですが、その割には比較的スムーズに開発に入っていける状態を作れていると感じています。
一方で、形式化した作業に従っているだけでは、現状の問題点を改善するというような意識が働かずチームが硬直化してしまう可能性があります。 これを回避するために、開発の安定化に伴ってチームへの権限移譲を順次進めることを行ってきました。 現在はチームが主体的に自分たちのやり方を変えることができるようになってきています。
この辺りのチームができていくまでの話も機会があれば共有したいと思っています。
おわりに
Oisix の EC サイトに対して実施している Web フロントエンドの刷新プロジェクトの背景や目的、方針について紹介しました。 次回の記事では、ソフトウェアのアーキテクチャについて紹介したいと思います。
現在も刷新プロジェクトは進行中で、一緒に刷新プロジェクトを進めたいメンバーを募集中です。
気になる方は是非以下もご覧ください。