クックパッド開発者ブログスマートフォン用の表示で見るクックパッド開発者ブログ2017-03-27Webpackerを使ったRailsでのJavaScript開発こんにちは。マーケティングプロダクト開発部の長田です。この記事では、私が現在進めているプロジェクトで、Webpackerを使ったJavaScriptのモジュール管理を導入したので、それについて紹介したいと思います。organizationで開発されているgemです。これまで、Rails上でJavaScriptのパッケージをどのように管理するか、また、モジュール依存をどのように解決するかについて、多くの選択肢があり、それらをどう組み合わせて使うのかについて悩まされてきました。このブログでも過去に何度か記事が投稿されており、その中でも複数の選択肢が上げられています。Rails私のプロジェクトでは、ユーザーが入力するフォームが多く、「リッチなフォームで使いやすい入稿システムを作りたい」という要件があったので、JavaScriptのパッケージをいくつか組み合わせて作ろうと思っていて、Yarn、Webpackを使って実現しようとしたのですが、考えることが多いなという印象でした。*1このような問題に対してWebpackerを使うと、ある程度Railsの開発プロセスにのったJavaScriptの開発ができるのではないかと思い、これを機に導入を試みました。載っているので、そこを参考にしつつ進めることで導入できました。以下では、導入するにあたって検討したことについて、主に次の2点について紹介します。導入にあたって、悩んだのはディレクトリ構成をどうするかでした。ポイントは以下の2点です。app/assets/javascriptsの扱いエントリーポイントとしてビルドするファイルapp/assets/javascriptsの扱いWebpackerでモジュールを管理できるようになったとはいえ、RailsはSprocketsを捨てる訳ではないらしいので、viewごとのアセットは今まで通り、app/assets/javascripts以下に置いても良さそうなのですが、個人的には、モジュールの管理がプロジェクト内で分散するのは避けたかったため、全てのファイルをapp/javascripts以下に置くことにしました。私のプロジェクトはスタートしたばかりで、ファイルが少なかったので、app/assetsにあるものを難なく移行するとこができました。生成されるWebpackの設定では、app/javascripts/packs直下に配置したファイルがそれぞれエントリーポイントとしてビルドされるような設定になっています。私のプロジェクトではapp/assets/javascriptsに置いていたファイルはSprocketsで1つのファイルにまとめていたので、それと同じようにするには、app/javascripts/packs以下にapplication.jsだけを配置して、そこから、他のモジュールを読み込むようにする必要がありました。以下の点から複数のエントリーポイントを作るようにしました。modelごとにエントリーポイントを作り、必要なviewからjavascript_pack_tagで読み込むようにしました。これにはメリット・デメリットはありますが、メリットとして大きいと思うのは、JavaScriptの挙動の影響範囲を特定しやすくなるという部分です。1つのファイルにまとまっている場合、コードベースが大きくなると、ロジックがどこで定義されているのか、また、ロジックがどこに影響するのかの見通しが悪くなってしまいがちです。ViewごとにJavaScriptを書いていて、それが1つのファイルにまとまっていた時、ファイルをまたいでDOMのidやclassが被ってしまうと予期せぬ挙動を与えてしまうこともありえると思います。複数のエントリーポイントを作り、必要なviewごとに読み込む方針は上のような問題に対しては有効だと思いました。modelを配置して、それぞれエントリーポイントとしてビルドする方針にしました。*3フロントエンドのテストフロントエンドのテストを書く手段として、E2Eテストで、ブラウザの振る舞いをテストするJavaScriptのモジュール単位でテストをする2つの選択肢があると思うのですが、私のプロジェクトでは、前者を採用することにしました。理由は、フロントエンドにロジックを持っているとはいえ、そこまで複雑なロジックではないサーバーサイドのテストと同じフレームワークで書けるので、導入コストがほとんどないという点から、E2EテストでJavaScriptで書いたロジックのテストをすることにしました。そこで問題になったのは、モジュールのビルドをどのタイミングで行うかです。wayなプロジェクトだと、Sprocketsをつかってモジュール管理をすると思うのですが、Sprocketsはアセットのリクエスト時にビルドをしてくれるので、phantomjsなどのヘッドレスブラウザを使ってテストをすることで、アセットのビルドを気にすることなくE2Eテストが書けました。Webpackerを使う場合は、テスト実行前にモジュールをビルドする必要があり、その設定とタイミングで悩みました。私のプロジェクトでは、test環境のビルド設定をdevelopment環境に合わせ、テストフレームワークのフック等とは別で、あらかじめアセットをビルドする方針にしました。*4ビルドの設定をdevelopment環境と合わせることで、開発中でもプロジェクトのビルド設定(RAILS_ENV的なもの)を変更することなくテストを実行できます。ビルドのステップをテストとは別にすることで、開発中には不要なビルドが走らず、こまめにテストを実行することができます。生成されるWebpackの設定は、test環境のものは生成されないので、config/webpack/test.jsを追加しました。実行することでdevelopment環境と同じようにビルドすることができるので、CIで以下のようなスクリプトを書いても、開発中と同じようにテストをすることができます。testまとめこの記事では、RailsアプリケーションでWebpackerを使ったJavaScriptの開発について書きました。Yarn、Webpackを使ったモダンなJavaScriptの開発環境が、rakeタスクなどが用意されている状態で、シュッと整うのは非常にいいと感じました。一方で、packs以下に配置するファイルの方針を考えたり、デフォルトのWebpackの設定だとディレクトリ構成に制約があったり、test用の環境はそれぞれでセットアップしなければいけなかったりするのと、今回の記事では触れませんでしたが、現時点ではCSSのビルドに対応できていない等、課題はまだまだありそうだなという感触です。最後になりましたが、この記事がRailsでのJavaScriptの開発について、少しでもお役に立てれば幸いです。*1:ビルド成果物をアセットパイプラインにのせるのかどうか、テストやデプロイ、digest等をどうするかを考えなければいけないので、多いなと思いました。instanceにあたります。*3:ただし、しばらくWebpackerを使っていくうちに、不都合が出てきたときを想定して、Sprocketsに切りもどせるようにコードを書くよう意識しています。*4:私のプロジェクトではRSpecを使っており、ここでいうフックとは、before(:suite)等のことを指します。16:17Webpackerを使ったRailsでのJavaScript開発Tweet関連記事2019-10-21クックパッドアプリ(Android)の開発効率化のためにやったこと/やっていることモバイル基盤部のこやまカニ大好き(id:nein37)です。こんにちは、投稿開発部エンジニアの芳賀です。既存...2016-03-16クックパッドにおける最近のMicroservices事例こんにちは。使ったセキュリティログ検索基盤の構築サービス特性にあった検索システムの設計戦略クックパッド採用説明会「クックパッドはサービスの作り手を採用したいんです。/*}*/スターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。