EatSmartシステム部ブログ

ウェブサイトの開発や運営に関する情報です。

もぐナビのフロントエンド事情

イートスマートではもぐナビという食品クチコミサイトを運営しています。 私が入社する以前から続くこのサービスは、フロントエンドにjQueryと一部prototype.jsを利用しています。 jQueryでDOMを直接操作するため、いわゆるイマドキなWEBサービスに比べるとレガシー感があります。 そんなもぐナビですが、今期リリースを予定する新機能の開発に伴い、ReactとTypeScriptの導入を行いました。

jQueryの利用に関して

個人的な考えですが、現状でもjQueryの利用は"アリ"だと思います。 サービスの要件やメンバーの習熟度を考えると、jQueryの採用が妥当な場面はまだまだあるように思います。 今回ReactとTypeScriptを導入しますが、主要なページではjQueryを利用し続けますし、最新バージョンへの更新も行う予定です。

jQueryは、簡単なDOMの操作やイベントに紐づく処理の実装はとても簡単に出来ます。また、豊富なプラグインを利用出来るのも魅力です。 ですが、Reactを今回導入するきっかけとなった新機能を実装するとなると、だいぶ辛さがありました。

Reactを導入する理由

状態に応じてフォームや遷移を管理するには、jQueryでも可能です。実際に、会員登録やクチコミ投稿ページでは、状態に応じた処理を行っています。 今回の要件を満たすプロトタイプを実装する途中まで、jQueryも頑張れそうでしたが、ReactやVueのような仕組みが欲しくなりました。

実は社内ツールではReact/Vueいずれも導入しています。複雑な実装をしたわけでは無いですが、jQueryに対するメリットを実感することが出来ました。 この中ではなぜReactを選んだかというと、React Nativeでネイティブアプリを開発するための下地を作りたかったからです。 もぐナビでは現在ネイティブアプリの提供を停止しています。いろいろな事情がありますが理由のひとつに、プラットフォームごとにネイティブアプリを開発・運用することの負担が大きかったことがあります。 Reactを経験してReact Nativeによるネイティブアプリの開発の敷居を下げることも、Reactを導入する理由のひとつです。

Reactの導入にあわせてTypeScriptの導入も行いました。量は多くありませんが、新規のものからReactとは関係が無いのものTypeScriptでの実装を行っています。 対応するエディタを利用すると、Javaのようにコードアシストやエラー・警告で問題箇所の指摘が行われるので、以前に比べ実装の負担は減っています。 下記の記事を参考に"がんばらずに"導入したことも良かったです。

employment.en-japan.com

スクランナーの導入

今回からwebpackとgulpを導入しました。

webpackはReactとTypeScriptのビルドに利用しています。 以下のように、共通して利用されるモジュールを別途出力し、ファイルサイズを小さくする工夫をしています。 jsやcssの縮小などwebpackでも可能なようですが、それらはgulpのタスクにしています。

optimization: {
    runtimeChunk: 'single',
    splitChunks: {
        name: 'webpack-chunks',
        chunks: 'initial',
        minChunks: 2
    }
}

gulpでは上記のようにwebpackで行わないjsやcssの縮小や結合等最適化に利用しています。 当初はこれらの処理は既存のyuicompressorで行おうとしていましたが、webpackでビルドしたjsや一部cssの処理に問題があったので、webpack導入と合わせてgulpの導入を行いました。 yuicompressorはJenkinsのジョブから実行するAntのタスクに組み込むことができましたが、gulpはJenkinsのジョブからgulp/webpackを導入したDockerコンテナで実行するようにしています。

開発時はgulpのwatchを利用して、ファイルが変更されたタイミングで自動的にビルドが行われるようにしています。 開発が進むにつれビルドに時間がかかるようになり、反映までの待ちが出来るようになってしまいました。このため、依存関係に無いタスクをparallelで処理するようにしています。 以下のように、jsとcssは依存しないのでparallelで、webpackとjsを結合する"js-concat"タスクはseriesで実行しています。

gulp.parallel(
    gulp.series(
        'webpack',
        'js-concat'
    ),
    'css-concat'
)

おわりに

もぐナビのフロントエンドのこれからを書きました。 React/TypeScriptに関してまだまだ知見が少なく、jQueryでは簡単に実装できそうなものに手こずることもありますが、新たなチャレンジに試行錯誤しながら楽しく取り組むことが出来ています。 未だにjQuery/Vanilla JSの割合が大きいですが、少しづつReact/TypeScriptを増やしていきたいと思います。

イートスマートでは、一緒に自社サービスの開発・運用をするメンバーを募集しています。 www.eatsmart.co.jp