LoginSignup
85
82

More than 5 years have passed since last update.

gulpを使ってsassの@importを解決しつつ差分ビルドをする

Last updated at Posted at 2015-08-22

小さいアプリケーションなら、styleは変更がある度に毎回フルビルドしてしまっても1sもかからないかもしれない。
しかし大きくなって、5s以上かかると非常に苦痛だ。

というわけで差分ビルドしたい。

Sassの差分ビルドで問題になること

差分ビルド自体は簡単で、gulp-cachedとかを使えば、前回と差分があるものだけをビルドできる。

なんだけど、その場合に問題になるのがsassの依存関係(@import)の解決だ。

単純に差分のあったファイルをビルドするだけだと、@import元を辿れない。
そうすると@import元のファイルが変更についてこない。

いや、でもnode-sassのwatchオプションって@import元辿ってるよな、あれってどうなってるんだ??
と思って実装を見てみたら、sass-graphというnpmを使って辿っていた。

お、これ使えば差分ビルド時に依存関係の解決もできるんじゃね??

ということでgulp taskに組み込んでみた。

gulpfile.coffee

gulp        = require 'gulp'
forEach     = require 'gulp-foreach'
sass        = require 'gulp-sass'
cache       = require 'gulp-cached'
grapher     = require 'sass-graph'
gulpIf      = require 'gulp-if'

gulp.watching = false

gulp.task 'build:sass', ->
  baseDir = "front/stylesheets/"
  graph = grapher.parseDir(baseDir)
  gulp.src "#{baseDir}/**/*.scss"
    .pipe cache('sass')
    .pipe gulpIf(@watching, forEach (currentStream, file) ->
      files = [file.path]
      addParent = (childPath)->
        # ここで@import元をたどる
        graph.visitAncestors childPath, (parent) ->
          files.push(parent) unless _.includes(files, parent)
          addParent(parent)
      addParent(file.path)
      gulp.src files, {base: baseDir}
    )
    .pipe sass().on('error', sass.logError)
    .pipe gulp.dest("public/stylesheets")


gulp.task 'watch', ->
  @watching = true
  gulp.watch "front/stylesheets/**/*.scss", ['build:sass']

これのおかげで、10sかかかるビルドが0.1sで済むようになった。嬉しいね。

85
82
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
85
82