画像を追加・変更した際に随時gruntのimageminタスクを実行する

公開

grunt-regardに[deprecated]が付けられるなどしたので、以前構築したオリジナルビルド環境をアップデートしました。アップデートついでに、画像を追加・変更した際に随時imageminタスク(grunt-contrib-imagemin)を実行することができないか検討しました。というのも、今までは構築が一段落した際にimageminタスクを実行していたのですが、タスク実行後に画像が追加になることが発生し(運用フェーズに入ればそれが普通になる)、タスク実行の度に最適化後のファイルまで走査されるのが無駄に感じたためです。

ファイルパスの渡し方で結構はまりましたが、GistにアップしているGruntfile.coffeeのようになりました。要点は以下の通りです。ファイル変更時にファイル名を取得する方法は、grunt-contrib-watchのCompiling Files As Neededを参考にしました。なお、CoffeeScriptで書いています。

module.exports = (grunt) ->
 grunt.initConfig 
 watch:
 options:
 nospawn: true
 livereload: true

 imagemin:
 files: [
 'htdocs/**/*.png'
 'htdocs/**/*.jpg'
 ]
 tasks: ['imagemin:ondemand']
 options:
 event: [
 'added'
 'changed'
 ]
 livereload: false

 imagemin:
 dist:
 optimizationLevel: 3
 files: [
 expand: true
 src: 'htdocs/**/*.{png,jpg,jpeg}'
 ]
 ondemand:
 optimizationLevel: 3
 files: []

 # Load grunt tasks.
 require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks)

 # Register tasks.
 grunt.registerTask 'default', [
 'compass:dev'
 'connect'
 'open'
 'watch'
 ]

 # Event
 changedFiles = Object.create null
 onChangeImage = grunt.util._.debounce(->
 paths = Object.keys changedFiles
 filesArray = []
 paths.forEach (path) ->
 filesArray.push
 src: path
 dest: path
 return
 grunt.config ['imagemin', 'ondemand', 'files'], filesArray
 changedFiles = Object.create null
 return
 , 200)
 grunt.event.on 'watch', (action, filepath) ->
 changedFiles[filepath] = action;
 if (/\.(png|jpg)$/.test(filepath))
 onChangeImage()
 return
 
 return;