Vue on Laravelというモノリスを解体してNuxtへ移行しました!

こんにちは、株式会社SCOUTERの開発部の小平(@ryotakodaira )です。

以前Twitterにてこのようなツイートをして、Nuxt移行の記事を書くと宣言してしまっていたので、書く書く詐欺で終わらないように今回の開発の背景などを含めて記事にしてみました。

弊社では、SARDINEという法人向けの業務管理ツールを提供していますが、そのアプリケーションはLaravelがベースにあり、その中でVueを使う構成で運用されていました。

今回、そのようなLaravelに依存しているVueアプリケーションからフロントエンドのみを切り出す形でLaravel API+Nuxtアプリケーションに置き換えを行いました。

この記事では、なぜNuxtに移行したのかや、その時に少し躓いた点について記していこうと思います。

なぜフロントを切り出す選択をしたのか

今回リニューアルをしたアプリケーションはリリースから1年6ヶ月程が経過しており、当然のことながら同期間立て続けにシステムの追加開発/運用を続けてきました。

当初は立ち上げから間もないサービスということもあり、スピード重視での開発体制であったため、アプリケーション構成も最小構成のLaravel(bladeテンプレート)の中でVueを使う構成で開発を進めていました。

機能追加を繰り返しコードベースの量が増えたり開発に関わるメンバーが増えたことによって以下のような問題が顕在化してきました。

ページ読み込みにかかる時間が長いことによるユーザビリティの低下

  • 前述の通り、Laravel(bladeテンプレート)の中でVueを使う構成で作られていた
  • そのためクライアント側のルーティングをLaravel(PHP)が握っている構成でアプリケーション自体が構築されておりvue-routerなども使用していなかったため、ページ遷移のたびに「JS/CSSファイルのダウンロード→Vueインスタンスの初期化」が行われてしまっていた

採用要件を高めてしまっている

  • バックエンド、フロントのコードが完全に分離出来ていないため、LaravelとVueの両方に理解がないと1つの機能開発を行うことが出来ない状態になっていた
  • 仮に両方出来たとしてもバックエンド、フロントのそれぞれの責務範囲がはっきりしていなかったためキャッチアップにも時間がかかってしまう

開発効率の低下

  • はるか昔に導入した化石のようなパッケージ群の影響範囲が分からず毎回影響範囲を調査する必要があった
  • ESLintやPretterを入れていなかったためコードスタイルが無法地帯
  • モノリシックな構成になっているためバックエンド、フロントの両方を気にかけて開発を行わないとならない
  • コードが増えるにつれてjavascriptのビルドの時間が長くなり開発中の待ち時間が増加(laravel-mix)

ということでそれらを一気に解決するために、フロントを切り出す開発に踏み切りました。

移行時に気をつけたこと

VuexStoreの設計

  • NuxtのSPAモードで開発するので、今までとは違ってページ遷移するたびにStoreが初期化されない(元々はページ遷移でどうせ初期化されるからちゃんとやってなかったw)
    • ページ遷移してもStoreは引き継がれるため遷移先の挙動に影響を及ぼさないように調整
  • コンポーネント内にdataプロパティーとして状態を持っている場合、ページ遷移でコンポーネントが破棄されると当然dataプロパティーも破棄されるので同じページに戻ってきた時に再度リクエストが走り、無駄が生じてしまう可能性がある
    • Vuexをフル活用しグローバルに状態を持つように変更して該当ページに再流入してきた時はAPIにリクエストを送らずにVuexからデータを降ろしてくるように処理を修正する

移行時に躓いたこと

驚くべきことにNuxtへの移行に大きな問題には遭遇しませんでしたが、
唯一少し躓いたところがありましたので、その部分の説明をします。

this.$router.pushの仕様

this.$router.push('hoge', {
query: {
params: ['foo', 'bar']
}
})

Nuxtで上記のようにルーティングのプッシュを行うと、デフォルトでは http://example.com?params=foo&params=barのようなURLになります。

ただ、このクエリーパラメータのフォーマット形式だと弊社のサービスにとっては問題が有りました。

Nuxtのページコンポーネントで受け取った queryのオブジェクトが意図した形では無いという問題でした。

// http://example.com?params=foo&params=bar

query = {
params: ['foo', 'bar']
}

// http://example.com?params=foo

query = {
params: 'foo'
}

👆配列で欲しいが文字列になってしまう

要件としてはparamsが一つだったとしてもパースした結果は配列として受け取りたいので、nuxt.config.jsに以下のような記述を追加してvue-routerを拡張して解決しました。

query-stringというnpmパッケージを通すことによってクエリパラメーターのフォーマットを指定できるのでその方法を採用しました。

ちなみにquery-stringを通すとURLは http://example.com?params[]=foo&params[]=bar
のようになります。

module.exports = {
router: {
parseQuery(query) {
return require('query-string').parse(query, {
arrayFormat: 'bracket',
})
},
stringifyQuery(params) {
if (Object.keys(params).length === 0) {
return ''
}
const query = require('query-string').stringify(params, {
arrayFormat: 'bracket',
})
return `?${query}`
},
},
}

まとめ

VueをNuxtへの移行は今回が初めてでしたが、移行中は大きな問題は特に発生せずNuxtはまさにかゆいところに手が届くという言葉がふさわしいなと実感しました。

弊社と同じような課題を抱えている開発チームにはぜひ取り組んでみて欲しいと思います!

今回のNuxtへの移行にはエンジニアメンバー4人で3週間かかりましたが、顕在化していた問題は無事解決されたため、リターンとしては十分で合ったと思います。

ただ、Nuxtへ移行する前のLaravel(bladeテンプレート)の中でVueを使う構成のアプリケーションが他にも存在しているためタイミングを見てそちらもNuxtに移行していきます。

次は2回目なのでもっと早く終わると信じて。

さいごに

SCOUTER社の開発チームの取り組みを紹介させていただきました!
サービスが成長していくにあたって、これからもメンバーを増やしていきたいと思っています。

興味のある方は下記から応募下さい!


フロントエンドエンジニア
最新技術で成長業界の波に乗りたいVue.jsフロントエンドエンジニア募集!
ROXXは「人を想い、社会に問う」をビジョンに、2013年に設立。この先何十年も使い続けられるような社会的意義のあるサービスを目指し、現在はHRTechサービスを展開しています。 ■月額制リファレンスチェックサービス『back check』( https://backcheck.jp )  書類選考や面接だけでは分からない採用候補者の経歴や実績に関する情報を、候補者の上司や同僚といった一緒に働いた経験のある第三者から取得することができる、リファレンスチェックサービスです。業界水準の1/10ほどの低コストで実施ができ、大手企業からスタートアップベンチャーまで、幅広い企業様にご利用いただくことができます。 ■ 採用企業と人材紹介会社を繋ぐ、求人プラットフォーム『agent bank』  サービス上に掲載されている1,500社以上の求人情報を、自社で抱える求職者へ自由に紹介することができる求人プラットフォームです。人材紹介会社は、自社で無駄な営業コストを抱えず、目の前の転職者支援に注力することができます。今後は、AIを活用した書類の自動作成、求職者に適した求人提案の自動化などのエージェント業務の大幅な効率化を進めていきます。中小規模の人材紹介会社を集約し、数年後には日本最大の人材紹介会社になることを目指します。
株式会社ROXX
サーバーサイドエンジニア
Laravelでマーケット成長の波に乗りたいエンジニアを募集!
ROXXは「人を想い、社会に問う」をビジョンに、2013年に設立。この先何十年も使い続けられるような社会的意義のあるサービスを目指し、現在はHRTechサービスを展開しています。 ■月額制リファレンスチェックサービス『back check』( https://backcheck.jp )  書類選考や面接だけでは分からない採用候補者の経歴や実績に関する情報を、候補者の上司や同僚といった一緒に働いた経験のある第三者から取得することができる、リファレンスチェックサービスです。業界水準の1/10ほどの低コストで実施ができ、大手企業からスタートアップベンチャーまで、幅広い企業様にご利用いただくことができます。 ■ 採用企業と人材紹介会社を繋ぐ、求人プラットフォーム『agent bank』  サービス上に掲載されている1,500社以上の求人情報を、自社で抱える求職者へ自由に紹介することができる求人プラットフォームです。人材紹介会社は、自社で無駄な営業コストを抱えず、目の前の転職者支援に注力することができます。今後は、AIを活用した書類の自動作成、求職者に適した求人提案の自動化などのエージェント業務の大幅な効率化を進めていきます。中小規模の人材紹介会社を集約し、数年後には日本最大の人材紹介会社になることを目指します。
株式会社ROXX
UI/UX designer
ユーザーの行動設計を変えていく!話題のSaaSデザイナー募集!
ROXXは「人を想い、社会に問う」をビジョンに、2013年に設立。この先何十年も使い続けられるような社会的意義のあるサービスを目指し、現在はHRTechサービスを展開しています。 ■月額制リファレンスチェックサービス『back check』( https://backcheck.jp )  書類選考や面接だけでは分からない採用候補者の経歴や実績に関する情報を、候補者の上司や同僚といった一緒に働いた経験のある第三者から取得することができる、リファレンスチェックサービスです。業界水準の1/10ほどの低コストで実施ができ、大手企業からスタートアップベンチャーまで、幅広い企業様にご利用いただくことができます。 ■ 採用企業と人材紹介会社を繋ぐ、求人プラットフォーム『agent bank』  サービス上に掲載されている1,500社以上の求人情報を、自社で抱える求職者へ自由に紹介することができる求人プラットフォームです。人材紹介会社は、自社で無駄な営業コストを抱えず、目の前の転職者支援に注力することができます。今後は、AIを活用した書類の自動作成、求職者に適した求人提案の自動化などのエージェント業務の大幅な効率化を進めていきます。中小規模の人材紹介会社を集約し、数年後には日本最大の人材紹介会社になることを目指します。
株式会社ROXX
株式会社ROXX's job postings
1 Likes
1 Likes

Weekly ranking

Show other rankings
If this story triggered your interest, go ahead and visit them to learn more