自分用のgruntタスクメモ

ツール

前にgruntの使い方を書きましたが、それからいろいろ試してみて自分なりのタスクを作成しました。

まだあまり使い倒してないのでまだまだ変更するところがあると思いますが、これを元に変えていきます。

2種類用意しました

がっつり機能を使いたい時もあれば、ちょこっとだけ使えればいいかなっていうことが個人的にあったので2種類用意してみました。

  1. 制作フォルダで制作後、最終的にJSやCSSを圧縮し、確認・納品フォルダへ必要ファイルを全コピーする
  2. 制作フォルダにはscssファイルのみ置き、HTMLやJSは確認・納品フォルダにのみ置いておく

1.がっつりタイプ

こちらは先程も書いたように、「制作フォルダで制作後、最終的にJSやCSSを圧縮し、確認・納品フォルダへ必要ファイルを全コピーする」ということをやります。

使用gruntプラグイン

  • grunt-contrib-watch
  • grunt-contrib-connect
  • grunt-contrib-copy
  • grunt-contrib-clean
  • grunt-open
  • grunt-contrib-compass
  • grunt-contrib-uglify
  • grunt-contrib-cssmin
  • grunt-csscomb
  • grunt-autoprefixer
  • grunt-contrib-concat

フォルダ構成

フォルダの構成はこのような感じです。

フォルダ構成図

流れとしては、

  1. 制作フォルダ(resource)で制作と確認。実行するタスクは、watch(compass・csscomb・autoprefixer)とconnectです。
  2. 出来たらCSSとJSを圧縮しつつ確認・納品フォルダ(deploy)へ必要ファイルをコピー。

としています。ちゃんと機能が保持されて圧縮されているか再度確認する必要があります。

Gruntfile.jsの設定

module.exports = function(grunt) {

  var pkg = grunt.file.readJSON('package.json');

  grunt.initConfig({

    path:{
      resource:"resource",//製作用
      deploy:"deploy"//確認・納品用
    },
    // Watch
    watch: {
      options: {
        livereload: true
      },
      html: {
        files: "<%= path.resource %>/**/*.html",
        tasks: []
      },
      css: {
        files: "<%= path.resource %>/**/*.scss",
        tasks: ['compass','csscomb','autoprefixer']
      },
      js: {
        files: "<%= path.resource %>/**/*.js",
        tasks: 'concat:resJs'
      }
    },

    // Compass
    compass: {
      default: {
        options: {
          config: "config.rb"
        }
      }
    },

    //結合
    concat: {
      resJs: {
        src: ['<%= path.resource %>/common/js/lib/*.js','<%= path.resource %>/common/js/script/*.js'],
        dest: '<%= path.resource %>/common/js/script.js'
      },
      depJs: {
        src: ['<%= path.deploy %>/common/js/script.js','<%= path.resource %>/common/js/lib/license.js'],
        dest: '<%= path.deploy %>/common/js/script.js'
      },
      depCss: {
        src: ['<%= path.deploy %>/common/css/style.css','<%= path.deploy %>/common/css/sass/_license.scss'],
        dest: '<%= path.deploy %>/common/css/style.css'
      }
    },

    //CSSセレクタ調整
    csscomb:{
      default: {
        src: '<%= path.deploy %>/common/css/style.css',
        dest: '<%= path.deploy %>/common/css/style.css'
      }
    },

    //ベンダープレフィックス
    autoprefixer: {
      options: {
        browsers: [ "last 2 version","ie 8","ie 9" ]
      },
      default: {
        src: "<%= path.resource %>/css/style.css",
        dest: "<%= path.resource %>/css/style.css"
      }
    },

    // LiveReload
    connect:{
      livereload:{
        options:{
          port:9001,
          hostname: 'localhost',
          open: true,
          base:"<%= path.resource %>/"
        }
      }
    },

    //コマンド実行時にページをブラウザで開く
    open: {
      server: {
        path: 'http://localhost:<%= connect.livereload.options.port %>'
      }
    },

    //ファイルの複製
    copy: {
      deploy: {
        files:[{
          expand : true,
          cwd : "<%= path.resource %>",
          src : ["**"],
          dest : "<%= path.deploy %>"
        }]
      }
    },

    //ファイルの削除
    clean:{
      deleteRelease: "<%= path.deploy %>",
      deleteSass: "<%= path.deploy %>/common/css/sass",
      deleteJs: ["<%= path.deploy %>/common/js/lib/","<%= path.deploy %>/common/js/script/"],
      deleteSprites: "<%= path.deploy %>/common/img/sprites",
    },

    //CSS min
    cssmin: {
      minify: {
        expand: true,
        cwd: '<%= path.deploy %>/common/css/',
        src: ['*.css', '!*.min.css'],
        dest: '<%= path.deploy %>/common/css/',
        ext: '.css',
        options: {
          noAdvanced: true
        }
      }
    },

    //JS min
    uglify: {
      minify:{
        files:{
          "<%= path.deploy %>/common/js/script.js":["<%= path.deploy %>/common/js/script.js"]
        }
      }
    }

  });

  //使うプラグインの読み込み
  var taskName;
  for(taskName in pkg.devDependencies) {
    if(taskName.substring(0, 6) == 'grunt-') {
      grunt.loadNpmTasks(taskName);
    }
  }

  //デフォルト
  grunt.registerTask('default', [
    'connect',
    'watch'
  ]);

  //リリース用
  grunt.registerTask('deploy',[
    'clean:deleteRelease',
    'copy:deploy',
    'cssmin',
    'concat:depCss',
    'uglify',
    'concat:depJs',
    'clean:deleteSass',
    'clean:deleteJs',
    'clean:deleteSprites'
  ])

};

config.rbの設定

if RUBY_VERSION =~ /1.9/
  Encoding.default_external = Encoding::UTF_8
end

# パス設定
http_path = "/"
css_dir = "resource/common/css"
sass_dir = "resource/common/css/sass"
images_dir = "resource/common/img"
javascripts_dir = "resource/common/js"

# .sass-cacheを出力するか
cache = false

# クエストにクエリ文字列付けてキャッシュ防ぐ
asset_cache_buster :none

# Sassファイルをブラウザで確認
sass_options = { :debug_info => false }

# cssの主力形式
output_style = :expanded

# trueで相対パス、falseで絶対パス
relative_assets = true

# CSSファイルにSassファイルの何行目に記述されたものかを出力する
line_comments = false

# スプライト画像生成時に生成されたファイル名に自動的に付けられるハッシュ文字列を削除する
on_sprite_saved do |filename|
  if File.file?(filename)
    FileUtils.mv filename, filename.gsub(%r{-s[0-9a-f]{10}(\.\w+)}, '\1')
  end
end

# スプライト画像生成時に生成されたファイル名に自動的に付けられるハッシュ文字列を削除し、
# キャッシュバスターとして利用する
# device-pixel-ratioの分数内に挿入される半角スペースを削除
on_stylesheet_saved do |filename|
  if File.file?(filename)
    css = File.read(filename)
    File.open(filename, 'w+') do |f|
      f << css.gsub(%r{-s([0-9a-f]{10})(\.\w+)}, '\2?\1').gsub(%r{(device-aspect-ratio:\s*)(\d+)\s*(/)\s*(\d+)}, '\1\2\3\4')
    end
  end
end

2.ちょこっとタイプ

上記のものだと結構処理が多くて、別にそこまでやる必要はないかなというもののためにもう一つ作りました。

こちらはscssのファイルだけ製作用フォルダに置いておき、出力は確認・納品フォルダへ行います。これだけだとgruntを使うまでも ない気がしますが、ライブリロードとautoprefixerを使いたかったのと、何かgruntの機能で足したくなった時にいいかなと思ったからです。

使用gruntプラグイン

  • grunt-contrib-watch
  • grunt-contrib-connect
  • grunt-open
  • grunt-contrib-compass
  • grunt-autoprefixer

フォルダ構成

フォルダ構成図

制作フォルダ(resource)にはscssファイルとそこで使うスプライト画像用のフォルダのみです。出力は確認・納品フォルダ(deploy)にされるため、 特にファイルの移動はしなくて大丈夫です。

Gruntfile.jsの設定

module.exports = function(grunt) {

  var pkg = grunt.file.readJSON('package.json');

  grunt.initConfig({

    path:{
      resource:"resource",
      deploy:"deploy"
    },
    // Watch
    watch: {
      options: {
        livereload: true
      },
      html: {
        files: ["<%= path.deploy %>/**/*.html"],
        tasks: ['compass','autoprefixer']
      },
      css: {
        files: ["<%= path.resource %>/sass/*"],
        tasks: ['compass','autoprefixer']
      }
    },

    // Compass
    compass: {
      dist: {
        options: {
          config: "config.rb"
        }
      }
    },

    // LiveReload
    connect:{
      livereload:{
        options:{
          port:9001,
          hostname: 'localhost',
          open: true,
          base:"<%= path.deploy %>/"
        }
      }
    },

    //コマンド実行時にページをブラウザで開く
    open: {
      server: {
        path: 'http://localhost:<%= connect.livereload.options.port %>'
      }
    },

    //ベンダープレフィックス
    autoprefixer: {
      options: {
        browsers: [ "last 2 version","ie 8","ie 9" ]
      },
      default: {
        src: "<%= path.deploy %>/common/css/style.css",
        dest: "<%= path.deploy %>/common/css/style.css"
      }
    }

  });

  //使うプラグインの読み込み
  var taskName;
  for(taskName in pkg.devDependencies) {
    if(taskName.substring(0, 6) == 'grunt-') {
      grunt.loadNpmTasks(taskName);
    }
  }

  //デフォルト
  grunt.registerTask('default', [
    'connect',
    'watch'
  ]);

};

config.rbの設定

if RUBY_VERSION =~ /1.9/
  Encoding.default_external = Encoding::UTF_8
end

# パス設定
http_path = "/"
css_dir = "deploy/common/css"
sass_dir = "resource/sass"
images_dir = "resource/"
generated_images_dir = "deploy/common/img"
javascripts_dir = "deploy/common/js"

# .sass-cacheを出力するか
cache = false

# クエストにクエリ文字列付けてキャッシュ防ぐ
asset_cache_buster :none

# Sassファイルをブラウザで確認
sass_options = { :debug_info => false }

# cssの主力形式
output_style = :expanded

# trueで相対パス、falseで絶対パス
relative_assets = true

# CSSファイルにSassファイルの何行目に記述されたものかを出力する
line_comments = false

# スプライト画像生成時に生成されたファイル名に自動的に付けられるハッシュ文字列を削除する
on_sprite_saved do |filename|
  if File.file?(filename)
    FileUtils.mv filename, filename.gsub(%r{-s[0-9a-f]{10}(\.\w+)}, '\1')
  end
end

# スプライト画像生成時に生成されたファイル名に自動的に付けられるハッシュ文字列を削除し、
# キャッシュバスターとして利用する
# device-pixel-ratioの分数内に挿入される半角スペースを削除
on_stylesheet_saved do |filename|
  if File.file?(filename)
    css = File.read(filename)
    File.open(filename, 'w+') do |f|
      f << css.gsub(%r{-s([0-9a-f]{10})(\.\w+)}, '\2?\1').gsub(%r{(device-aspect-ratio:\s*)(\d+)\s*(/)\s*(\d+)}, '\1\2\3\4')
    end
  end
end

スプライト画像を確認・納品フォルダに生成したかったので、「generated_images_dir」を使ってるのがちょっと違う点でしょうか。

タスクはどのような案件で制作環境かでだいぶ変わりそうな気がしますが、ひとつ参考になれば幸いです。

参考ページ

このタスクを作成する際に以下のサイトを参考にしました。