Railsのasset pipelineを捨ててgulpを使う
gulpを導入した時に、Railsのasset pipelineを捨てた話。ハッシュ付きのファイル名が書いてあるmanifestファイルが何とかなればいい。それで大体何とかなった。今後もgulpを使い続けるか分からないし、もしかしたらnpm scriptsにまとめるかもしれないし、Railsからフロントエンド関連の作業を取り除いておきたかった。
移行した人の話
移行してみた
まずはasset pipelineをオフにする。それからgeneratorでアセットが生成されないようにする。
config.assets.enabled = false
config.generators do |g|
g.assets false
end
それから、public
ディレクトリの下にrev-manifest.json
を出力する。gulp-rev-all
でこのmanifestファイルを出力するので、npm install
しておく。
"gulp-rev-all": "^0.9.7",
rev-manifest.json
を出力するタスク。
import gulp from 'gulp';
import gulpLoadPlugins from 'gulp-load-plugins';
import rev from 'gulp-rev-all'
const $ = gulpLoadPlugins();
const dist = 'public/';
gulp.task('rev', ['styles:minify', 'scripts:minify'], () => {
return gulp.src([
dist + 'assets/styles/**/*.min.css',
dist + 'assets/scripts/**/*.min.js'
], {base: dist})
.pipe(rev.revision())
.pipe(gulp.dest(dist))
.pipe($.gzip())
.pipe(gulp.dest(dist))
.pipe(rev.manifestFile())
.pipe(gulp.dest(dist));
});
Railsからmanifestファイルを読み込むためのクラスを作る。参照サイトからパスを改変した。
require 'json'
class AssetManifest
def self.manifest
path = 'public/rev-manifest.json'
if File.exists?(path)
@manifest ||= fix_manifest(JSON.parse(File.read(path)))
end
end
def self.fix_manifest(manifest)
fixed = manifest.map{|orig_path, hashed_path|
orig_path = '/' + orig_path if orig_path != ?/
hashed_path = '/' + hashed_path if hashed_path != ?/
[orig_path, hashed_path]
}
Hash[fixed]
end
def self.stylesheet_path(url)
if AssetManifest.manifest
url += '.css' unless url.end_with?('.css')
AssetManifest.manifest[url] || url
else
url
end
end
def self.javascript_path(url)
if AssetManifest.manifest
url += '.js' unless url.end_with?('.js')
AssetManifest.manifest[url] || url
else
url
end
end
def self.asset_path(url)
if AssetManifest.manifest
AssetManifest.manifest[url] || url
else
url
end
end
end
ヘルパーの取得先もmanifestファイル経由に変更した。
module ApplicationHelper
def stylesheet_link_tag(url, options={})
url = AssetManifest.stylesheet_path(url)
super(url, options)
end
def crossorigin_javascript_include_tag(url, options={})
url = AssetManifest.javascript_path(url)
super(url, options)
end
def javascript_include_tag(url, options={})
url = AssetManifest.javascript_path(url)
super(url, options)
end
def image_tag(url, options={})
url = AssetManifest.asset_path(url)
super(url, options)
end
def image_path(url, options={})
url = AssetManifest.asset_path(url)
super(url, options)
end
def image_url(url, options={})
url = AssetManifest.asset_path(url)
super((ActionController::Base.asset_host || "") + url, options)
end
end
cssの読み込み方法はこんな感じになる。
<% if Rails.env.production? %>
<%= stylesheet_link_tag '/assets/styles/app.min.css', media: 'all' %>
<% else %>
<%= stylesheet_link_tag '/assets/styles/app.css', media: 'all' %>
<% end %>
ここまでの作業でRailsからフロントエンド関連の作業をgulpに移行できた。もちろんgulpじゃなくても、好きなツールで静的ファイルをビルドするといいと思う。