WordPressテーマのsassコンパイルやminifyをGulpでやる

頑なにWordPressテーマのビルドをrubyの自動化ツールであるGuardを使ってやってきたのですが、フロントエンドに関しては、今どきはnodeを使ったほうがバージョンアップも盛んですし情報も充実しています。

というわけでnodeの今どきのビルドツールであるGulpを使ってビルドするようにしてみました。

テーマのディレクトリ構成

[theme]
 ├─assets          # 画像などの素材一式
 | ├── fonts       # フォント
 | ├── images      # 画像
 | ├── javascripts # JavaScript
 | └── stylesheets # sassファイル
 └─partials        # 部分的に使用するテンプレート

Gulpの設定

Gulpのインストール

npm install -g gulpでGulpコマンドが使えるようにしておきます。

必要なモジュールのインストール

テーマディレクトリにpackage.jsonという名前で、以下の内容が記述されているファイルを作成します。

{
  "name": "your-theme-name",
  "version": "1.0.0",
  "dependencies": {},
  "devDependencies": {
    "gulp": "~3.5.1",
    "gulp-autoprefixer": "0.0.6",
    "gulp-cache": "~0.1.1",
    "gulp-concat": "~2.1.7",
    "gulp-imagemin": "~0.1.4",
    "gulp-jshint": "~1.3.4",
    "gulp-load-plugins": "~0.2.0",
    "gulp-minify-css": "~0.3.0",
    "gulp-notify": "~0.4.0",
    "gulp-rename": "~0.2.2",
    "gulp-ruby-sass": "~0.3.0",
    "gulp-uglify": "~0.2.0",
    "gulp-compass": "~1.1.8"
  }
}

package.jsonがある状態でnpm installとコマンドを打つと、テーマディレクトリ直下にnode_modulesというディレクトリが生成され、必要なモジュールがインストールされます。

Gitでバージョン管理している場合は.gitignoreにnode_modules/を加えておくとよいでしょう。

gulpfile.jsの用意

CoffeeScriptで書くこともできるのですが、内容のわりには設定が面倒なので普通にJavaScriptで書いています。

// Load plugins
var gulp = require('gulp'),
    plugins = require('gulp-load-plugins')({ camelize: true }),
    lr = require('tiny-lr'),
    server = lr();

// Stylesheets
gulp.task('stylesheets', function() {
  return gulp.src('assets/stylesheets/*.sass')
    .pipe(plugins.compass({
      css: 'assets/tmp',
      sass: 'assets/stylesheets',
      image: 'assets/images'
    }))
    .pipe(plugins.autoprefixer('last 2 versions', 'ie 9', 'ios 6', 'android 4'))
    .pipe(plugins.minifyCss({ keepSpecialComments: 1 }))
    .pipe(gulp.dest('./'))
    .pipe(plugins.livereload(server))
    .pipe(plugins.notify({ message: 'Styles task complete' }));
});

// JavaScripts
gulp.task('javascripts', function() {
  return gulp.src('assets/javascripts/*.js')
    .pipe(plugins.concat('main.js'))
    .pipe(gulp.dest('./'))
    .pipe(plugins.rename({ suffix: '.min' }))
    .pipe(plugins.uglify())
    .pipe(plugins.livereload(server))
    .pipe(gulp.dest('./'))
    .pipe(plugins.notify({ message: 'Scripts task complete' }));
});

// Images
gulp.task('images', function() {
  return gulp.src('assets/images/**/*')
    .pipe(plugins.cache(plugins.imagemin({ optimizationLevel: 7, progressive: true, interlaced: true })))
    .pipe(plugins.livereload(server))
    .pipe(gulp.dest('assets/images'))
    .pipe(plugins.notify({ message: 'Images task complete' }));
});

// Watch
gulp.task('watch', function() {

  // Listen on port 35729
  server.listen(35729, function (err) {
    if (err) {
      return console.log(err)
    };
    // Watch .sass files
    gulp.watch('assets/stylesheets/**/*.sass', ['stylesheets']);
    // Watch .js files
    gulp.watch('assets/javascripts/**/*.js', ['javascripts']);
    // Watch image files
    gulp.watch('assets/images/**/*', ['images']);
  });

});

// Default task
gulp.task('default', ['stylesheets', 'javascripts', 'images', 'watch']);

このファイルをテーマディレクトリの直下にgulpfile.jsという名前で配置して、gulpとコマンドを打ち込むと、ファイルの変更を検知しながらリアルタイムでビルドを行ってくれます。

加えてhtmlのヘッダで結合&ミニファイされたcssファイルとjsファイルを読み込むようにするのを忘れずに。

CoffeeScriptを使いたい場合はgulp-coffeeを挟めばOKです。

注意すべきは、JavaScriptを多用するプロジェクトの場合はJavaScriptの結合順序を考えなきゃいけないので、上記のファイルのままだと使い物にならないかもしれないです。jQueryを使うならBowerでパッケージ管理もしたいところだし、まだまだ進化させるポイントはありますね。

Gulpは良い

何にせよ、Gulp、良いです。

Grunt.jsは使っていて、ただただ辛かった。JSONだけで上手く書かなければいけないというのは、過去のXML地獄を思い出させるつらさがありました。その点、Gulpはコードで表現ができるので、人のを見るのも自分のをメンテするのも非常に楽です。

あわせて読みたい

タスクランナーgulp.js最速入門