ゆたんぶろぐ

気が向いたら書いてます

更新したファイルに該当するタスクだけ走らせる Gruntfile

grunt-contrib-watch って便利なんですが、監視ファイルが多くなる=走る処理が多くなるとどうしても時間がかかってしまいます。それでなんだか効率が落ちてたりするわけなんですが、grunt-este-watch が幸せということを聞いて、ぼくも幸せになりたいと思いやってみました。

更新されたファイルに関係ないタスクが走るのが良くないわけで、ちゃんと個別にタスクを走らせたら良いわけですね。ということで、以下にサンプルを置いておきます。とりあえず便宜上なので、ファイル名に意味はありません。

やりたいこと

Sass

common.sass

css へのコンパイル -> reset.sass との concat -> minify

mobile.sass

css へのコンパイル -> minify

JavaScript

common-a.js / common-b.js

common-a.js と common-b.js を concat -> minify

mobile.js

minify

YAML

functions.yml / settings.yml

それぞれのファイル名での json

前提

監視対象のファイルは全て ./src/ に入ってるものとします。

利用するプラグイン

  • grunt-contrib-compass
  • grunt-contrib-concat
  • grunt-contrib-cssmin
  • grunt-contrib-uglify
  • grunt-este-watch
  • grunt-yaml

Gruntfile.coffee

module.exports = (grunt) ->
  pkg = grunt.file.readJSON 'package.json'
  grunt.initConfig
    compass:
      dev:
        options:
          config: 'config.rb'
          environment: 'development'
          force: true
      prod:
        options:
          config: 'config.rb'
          environment: 'production'
          force: true
    concat:
      css:
        files:
          'css/styles.css': ['css/reset.css', 'css/common.css']
      js:
        files:
          'js/functions.js': ['src/common-a.js', 'src/common-b.js']
    cssmin:
      common:
        files:
          'css/styles.min.css': ['css/styles.css']
      mobile:
        files:
          'css/mobile.min.css': ['css/mobile.css']
    uglify:
      common:
        files:
          'js/functions.min.js': ['js/functions.js']
      mobile:
        files:
          'js/mobile.min.js': ['src/mobile.js']
    yaml:
      functions:
        files:
          'js/functions.json': ['src/functions.yml']
      settings:
        files:
          'js/settings.json': ['src/settings.yml']
    esteWatch:
      options:
        dirs: ['src/']
      sass: (file) ->
        return if getTarget(file) is 'mobile' then ['compass:dev', 'cssmin:mobile'] else ['compass:dev', 'concat:css', 'cssmin:common']
      js: (file) ->
        return if getTarget(file) is 'mobile' then ['uglify:mobile'] else ['concat:js', 'uglify:common']
      yml: (file) ->
        return ['yaml:' + getTarget(file)]

  for t of pkg.devDependencies
    if t.substring(0, 6) is 'grunt-'
      grunt.loadNpmTasks t

  grunt.registerTask 'w', ['esteWatch']
  grunt.registerTask 'default', ['compass:dev', 'concat', 'cssmin', 'uglify']

getTarget = (file) ->
  return file.split('/')[1].split('.')[0]

これで grunt w で、css でも yaml でも該当タスクだけ走るので、劇的にスピードが変わりました。めでたしめでたし。