メドピア開発者ブログ

集合知により医療を再発明しようと邁進しているヘルステックカンパニーのエンジニアブログです。読者に有用な情報発信ができるよう心がけたいので応援のほどよろしくお願いします。

Railsフロントエンドボイラープレート「medpacker」の紹介

メドピアマッスル部のフロントエンドエンジニア村上(@pipopotamasu)です。

最近筋トレに時間を割かれ、家でコードが書く時間が減ってしまったのが悩みの種です。

今日は最近作ったメドピア用Railsフロントエンドのボイラープレート、「medpacker」を紹介しようと思います。

github.com

medpacker作成の背景

Railsには公式で大きく分けて2つのフロントエンドの環境があります、アセットパイプラインとwebpackerです。 これらはメドピアの既存プロダクトでも使ってきたのですが、プロダクトの規模が大きくなったり、時間が経つにつれて色々な辛みが見えるようになってきました。

アセットパイプライン

  • 最終的にJSã‚„CSSのファイルを1つのファイルに出力するため、プロジェクトが大きくなってくるとファイルサイズが大きくなってしまう(キャッシュが効いてないと読み込みが遅すぎる、開発時のビルドに時間がかかる)
  • ES6+を使いたい場合はwebpack等のBundlerを自前で設定する必要がある(またはbundlerã‚’wrapしているgemを使う必要がある)

webpacker

  • アセットパイプラインの欠点を解消(複数ファイル出力、webpackが設定済み)したのはよいが、webpackの設定がrailsにラップされすぎていてわかりづらい
  • 初期設定だとプロダクションビルドにsource mapがついていたりなど?な設定がある
  • webpack本体のバージョンアップについていけてない(webpackがv4なのに対して、webpackerはwebpack v3依存)

これらの辛みのため新規でRailsプロジェクトを作成する時、今まで通りアセットパイプラインやwebpackerで構築してしまっていいのかという疑問が生じてきました。 またフロントエンド開発をメインで行うのがサーバーサイドエンジニアや外部のフロントエンドエンジニアさんということもあり、プロジェクト間で採用技術や質を標準化するために、またフロントエンドの環境構築の時間短縮のためRailsフロントエンド用のボイラープレートを用意しそれを横展開するのがよいのではないか?

ということで、これらの辛みを克服するためにメドピア用Railsフロントエンド用のボイラープレート「medpacker」を作成しました。

medpackerのコンセプト

medpackerのコンセプトは大きく2つです。

素早く、簡単に導入できる

webpackerのような導入の簡単さを目指し、Railsのアプリケーションテンプレートを使用して設定できるようにしています。これによりrails newをしてから2~3分でフロントエンド環境を構築することができます。

だいたい開発や本番環境で必要なものが初期から設定されている

アプリケーションテンプレートで導入した直後から、webpack・babel・lint・postcss・minify等がすでにセットアップされているため、すぐに開発に着手できるようになっています。

Get started! 実際にmedpackerを導入してみる

それでは実際にmedpackerを導入してみましょう。

STEP1: medpackerをローカルにcloneする

$ git clone https://github.com/medpeer-inc/medpacker.git

STEP2: rails newした直後のrailsプロジェクトを用意する

$ rails new test-project

STEP3: アプリケーションテンプレートを用いて、先ほど作成したプロジェクトにmedpackerを適用する

$ cd test-project
$ bin/rails app:template LOCATION=path/to/medpacker/template.rb

この際いくつかCLIに質問されるので、用途に応じて答えてください。

remove 'app/assets'? y
remove 'test/'? y
need example page? y
Overwrite /Users/yamatomurakami/work/test-project/config/routes.rb? (enter "h" for help) [Ynaqdhm] a

STEP:4 railsを起動する

$ bin/rails s

サーバーを起動し、以下の画面が出たら導入完了です

( ※need example page?にyesで答えないとこのページは表示されません)。

f:id:ec0156hx39:20190122002939p:plain
medpacker_home

medpackerの中身について

作成に至った背景、コンセプトなどはすでに説明した通りです。ここではmedpackerの中身についてみていきます。

webpack

medpackerの核ともいうべきbundlerです。 もちろんフロントエンドのアセットをビルドするために入れてます。 Rails側でビルドしたアセットをHTMLに読み込むためのヘルパーを用意してあり、それを使うことで読み込むことができます。 productionモードでビルドするとCSS, JSがminifyされるようになっています。

webpack-dev-server

webpackでの開発をサポートするツールです。ざっくり以下のような機能があります。

  • JSを変更した時差分のビルドをしてくれる(webpackのwatchと同じ)

  • リロードせずに更新したファイルがブラウザに適用される(Hot module replacement, HMR)

  • 上記のHMRができない場合は自動的にブラウザをリロードし、更新分のアセットを取得する

CSS(SCSS), PostCSS

導入時点で、SCSSとPostCSSの設定がされています。

(※メドピアでは全てのRailsプロジェクトでSCSSを使用しているので、決め打ちで入れてあります)

またPostCSSで初期導入されているプラグインは以下2つです。

  • autoprefixer・・・自動的にベンダープレフィックスをつけてくれるライブラリ
  • postcss-flexbugs-fixes・・・ブラウザが潜在的に持っているflexboxのバグを踏まないように、自動整形してくれるライブラリ

babel

JSを色々なブラウザで読み込めるように(例えば最新の記法が古いブラウザでも読み込めるように)変形/代替してくれるライブラリになります。 導入時点で設定済みなので、IE11とか気にせずにJSを書いても問題ありません。

基本的にメドピアの推奨環境に合わせてありますが、この辺をいじれば対応ブラウザを変えることができます。

lintç³»

SCSSのlint(stylelint)とJSのlint(eslint)の2つが設定済みです。導入側のプロジェクトのCIに組み込んでおいてください。

Vue.js

medpackerに入れるか迷ったのですが、導入時にVue.jsが初期設定してあります。 個人的にJSライブラリを入れるのは本当に必要になった時に初めて入れればいいと思っているのですが、プロジェクト間での採用技術を統一するために入れてあります(以前とあるプロダクトで外部のエンジニアさんにお手伝いしていただいてた時、社内のほとんどのプロジェクトでVue.jsを使っているにも関わらず、しれっとReactが入っていたことがあったので...)。

工夫したところ

ライブラリアップデート

月1回のペースで、自動的にgemとnpmのアップデートPRがCIで作られるようになっています。 作成後は私がPR内容の確認・マージをしています(この辺は手動です)。 「medpackerを適用しようとしたがバージョンが古い...」というメンテされずに放置されるという事態は避けるようにしています。

アプリケーションテンプレートの使用

より楽にプロジェクトにmedpackerを適用するためにRailsのアプリケーションテンプレートを使用しました。 最初はこの便利機能の存在を知らずに、こちらの方法をメインの適用方法にと考えていました。今考えるととてつもなく使いづらいですね。。。

終わりに

現在メドピアでは3つのプロダクトでmedpackerを使用しています。 使っているうちに出てくる改善点や追加機能などは日々更新していく予定です。

もしこのブログを見た人で「うちではこんなの使ってるよー」とか知見がある人はこっそり教えていただけたらありがたいです。medpackerに取り入れるかもしれません。

またこのmedpackerを作る上でpixivさん、スタディストさんのブログを参考にさせていただきました。本当にありがとうございました。

今日から簡単!Webpacker 完全脱出ガイド - pixiv inside

フロントエンド原理主義者が目論んだ脱webpacker – スタディスト開発ブログ – Medium


(☝︎ ՞ਊ ՞)☝︎是非読者になってください


メドピアでは一緒に働く仲間を募集しています。 ご応募をお待ちしております!

■募集ポジションはこちら

https://medpeer.co.jp/recruit/entry/

■開発環境はこちら

https://medpeer.co.jp/recruit/workplace/development.html