Help us understand the problem. What is going on with this article?

拡張子が.cssなファイルでもgulpを使ってSprocketsに無理やりasset pathを解決させる

More than 3 years have passed since last update.

背景

gulpでフロントエンドのビルドプロセスを組んでいるならSprocketsを通さなければ良い。
と言いたくても、なかなかそうすぐには完全移行はできず、ビルドしたものはapp/assets/配下に出力して最終的にはSprocketsさんにどうにかしてもらっている日々を過ごしています。

そんな中でscssのビルドをgulpに移行したのですが、Sprocketsでは.cssファイルではimage-urlasset-urlなどのhelperメソッドが使えず、imageのasset_pathが解決できません。

とはいえ、せっかくフロント側でlibsass使ってビルドしたものを.scss拡張子に戻して、再びSprocketsのScss Processorにかけるなんてリソースの無駄すぎて嫌だ。(libsassに比べると、ruby-sass遅過ぎる。)

じゃあ無理やり.css.erbに変換するか。erbなら余計な処理もなくて軽いでしょ、というのがこの記事でやることです。

参考

Rails4のpath解決については以下の記事を見ていただけると分かると思います。

http://qiita.com/wadako111/items/03bc00d914e62243a511

この記事で紹介されてる解決法1を実施するために、scssではなくerbに無理やりgulpで変換します。

コード

gulpfile.coffee
gulp        = require 'gulp'
sass        = require 'gulp-sass'
replace     = require 'gulp-replace'
rename      = require 'gulp-rename'

gulp.path =
   app: 'front'
   dist: 'app/assets'

gulp.task 'build:sass', ->
  styleAssetPattern = /(?:image-url|asset-url)\(['"](.+)['"]\)/g
  replaceStyleAssetPath = (_full, key) -> "url(<%= asset_path '#{key}' %>)"

  gulp.src "#{@path.app}/stylesheets/**/*.scss"
    .pipe sass({includePaths: [ '.tmp/stylesheets' ]})
    .pipe replace(styleAssetPattern, replaceStyleAssetPath)
    .pipe rename({ extname: '.css.erb' })
    .pipe gulp.dest("#{@path.dist}/stylesheets")

解説

gulp-replaceで、正規表現を使って本来のscssファイルで使っていた(image-url|asset-url)の引数を抜き出して、erbで使えるasset_pathに変換しています。
その上でgulp-renameで拡張子を.css.erbに変換します。

結果

before

front/stylesheets/test.scss
.test-image-url {
  background-image: image-url('image.png');
}


.test-asset-url {
  background-image: asset-url('asset.png');
}

after

app/assets/stylesheets/test.css.erb
.test-image-url {
  background-image: url(<%= asset_path 'image.png' %>); }

.test-asset-url {
  background-image: url(<%= asset_path 'asset.png' %>); }

実際早いの

.erbに一度するのは確かに無駄ですが、ある程度大きいコードベースならば、それを余裕でペイするぐらいにはlibsassは爆速です。(詳細なデータは取ってません、すみません。)
Sprocketsからの脱却を目指している身としては、また目標に一歩近づいて精神衛生的にも良いです。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away