Rails wayなプロジェクトでの調査録
Webpacker
RailsでWebアプリケーションを作る際、Webpackerという名前をよく聞く。
最近はWebpackerをやめ、Webpackを使うように戻す動きが多いらしい。
とりあえず名前だけは覚えておくと良い◎
Railsのgem
事前に設定されたWebpackにビューヘルパーを加えたものを提供することで、生成されたアセット(JavaScriptや[S]CSSファイルなど)を簡単に対応付けられるようにする。
rails newをする際に、--webpack
オプションをつけるとある程度セットアップがなされた状態でプロジェクトが作成されるためRailsエンジニアからすると利用しやすい。
$ rails new sample_app --webpack
作成されたプロジェクトを見ると、app/javascriptというディレクトリがあり、app/javascript/packs
がエントリファイルになるよう設定されている。
ビルド後するとpublic/packs/manifest.json
が生成される。
{
"application.js": "/packs/index-xxxxx.js",
}
このmanifest.jsonによってapp/javascript/packsに入っているエントリファイルと、public/packsに生成されたハッシュ値付きのバンドルファイルを紐づける。
ビルド後生成されるHTMLファイルを見るとハッシュのふられたファイルを読み込むようになっている。
<script src="/packs/index-xxxxx.js"></script>
【結論】
Webpackerはハッシュ付きのバンドルファイルをビルドし、マニフェストファイルによってバンドルファイルとHTMLを紐付ける
Sprockets
Simpaker
クックパッド社が作成したRailsのgem
Simpacker は基本的なところは Webpacker と同じです。manifest.json という、ハッシュ値が付与されたファイル名ともとのファイル名のマッピング情報を持つファイルをもとに、JS や CSS を読み込むタグを生成するヘルパーを提供します。Webpacker と違うのは、Simpacker は webpack 側の設定を一切管理せず、出力する manifest.json のパスしか知らないというところです。開発者は好きな webpack のバージョンを使い、直接 webpack.config.js を書いて、Simpacker で設定されたパスに manifest.json を出力すればいいだけです。
Simpakerはapp/javascript/packs
配下に画面ごとのJSファイルを置くのがルールなのでSentiryファイルの設定が下記のようになる。
const root = path.join(__dirname, '..')
const bundles = path.join(root, 'app', 'javascript', 'packs')
const targets = glob.sync(path.join(bundles, '**/*.{js,ts}'))
const entry = targets.reduce((entry, target) => {
const bundle = path.relative(root, target)
const filename = path.relative(bundles, target)
const ext = path.extname(filename)
return Object.assign({}, entry, {
[filename.replace(ext, '')]: './' + bundle,
})
}, {})
module.exports = {
entry: entry,
}
entryにはオブジェクトで下記の形式にして値を渡す。
entry: {
home: './home.js',
about: './about.js',
contact: './contact.js'
}
};
参考
画像ファイルの適切な置き場所
Railsでは下記2箇所に画像ファイルを配置することができる。
- public配下
- app/assets/images配下
違いと適切な配置判断軸は下記記事参照
アセットパイプライン
Rails では app/assets ディレクトリ以下はアセットパイプラインの対象となり、自動でスペースや改行を詰める、コメントを削除するなどの最小化が行われる。
また、ファイル名にフィンガープリントを挿入し、アセットファイルがブラウザでキャッシュされるようになる。
同じ名前で違う画像に差し替えても、画像ファイルの中身からフィンガープリントを自動で更新して、画像ファイル名に挿入するので、ブラウザでキャッシュされた古い画像が表示される心配がない。
変更が想定されない画像に関してはpublic配下に配置し、変更の可能性がある画像に関してはassets配下に配置する。