Web雑記帳 atsu666


Grunt.jsを触ってみた

April 07 Mon 2014 | 学習

自分は業務でほとんどhtmlやcssは書かないのですが、役にたつか分かりませんが、触ってみたいと思います。 今年はちょっとフロントを勉強しようかと思っているので、まずは環境(まずは形から入るタイプなので。。)を有名な自動化ビルドツール、Grunt.jsから触ってみようと思います。

目標

  • インストール
  • CSSファイルをminify,
  • ファイルを監視してタスク自動実行

まずは最低限という所で以上を目標にやってみます。

インストール

Node.jsのインストール

Grunt.jsを動かす為にはNode.jsが必要なので、まずはNode.jsをインストールします。 ただ、以前homebrewでNodeをインストールした事があったのでバージョンアップだけしときます。

$ brew upgrade node
$ node -v  // バージョン確認
v0.10.26

また、Homebrewでインストールすると、npm(Nodeのパッケージマネージャー)まで 自動でインストールしてくれます。

grunt-cliのインストール

次にgruntのコマンドラインツールgrunt-cliをインストールします。-g オプションをつけてグローバルインストールします。

$ sudo npm install -g grunt-cli

ただここで自分の場合は問題発生。シェルに自分はzshを使っているのですが、npmと打つと補完機能が egrep: empty (sub)expression というエラーを出します。 ぐぐったらnpmの補完をするコマンドがあったのでそれを実行。npmの補完を有効にする

$ npm completion >> ~/.zshrc
$ source .zshrc

これでエラーがなくなり補完がきくようになりました。

Gruntを使ってみる

では実際に対象のプロジェクトに移動しGrountをインストールして動かしてみたいと思います。 まずはpackage.jsonを作ります。 package.jsonは、パッケージの情報や、プロジェクト情報が乗っているファイルで、 パッケージ郡のインストールが簡単になるようです。環境毎に設定するのは面倒くさいですからね。

package.jsonを作る方法はnpm initコマンドで対話的に作成できます。

$ cd プロジェクトディレクトリ
$ npm init

ここでは、entry pointにはGruntfile.jsを指定。CoffieScriptも使えるのでGruntfile.cofeeでもいい。

{
  "name": "test",
  "version": "1.0.0",
  "description": "",
  "main": "Gruntfile.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "atsu666",
  "license": "ISC"
}

Gruntのインストール

次にGruntのインストールを行います。 npm install grunt とコマンドを打つとGruntがインストール出来るのですが、 オプションで --save-devをつける事より先ほど作成したpackage.jsonにGruntのインストール情報が追記されますので指定します。

コマンドを実行するといろいろと落としてきてくれます。 プロジェクトをみると、node_modulesというディレクトリが出来ていると思います。

$ npm install grunt --save-dev
grunt@0.4.4 node_modules/grunt
├── which@1.0.5
├── dateformat@1.0.2-1.2.3
├── eventemitter2@0.4.13
├── getobject@0.1.0
├── rimraf@2.2.6
├── colors@0.6.2
├── grunt-legacy-util@0.1.2
├── hooker@0.2.3
├── async@0.1.22
├── exit@0.1.2
├── nopt@1.0.10 (abbrev@1.0.4)
├── lodash@0.9.2
├── coffee-script@1.3.3
├── underscore.string@2.2.1
├── glob@3.1.21 (inherits@1.0.0, graceful-fs@1.2.3)
├── minimatch@0.2.14 (sigmund@1.0.0, lru-cache@2.5.0)
├── iconv-lite@0.2.11
├── findup-sync@0.1.3 (glob@3.2.9, lodash@2.4.1)
└── js-yaml@2.0.5 (esprima@1.0.4, argparse@0.1.15)
{
  "name": "test",
  "version": "1.0.0",
  "description": "",
  "main": "Gruntfile.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "atsu666",
  "license": "ISC",
  "devDependencies": { // ← Gruntのインストール情報が追記された
    "grunt": "^0.4.4"
  }
}

プラグインのインストール

Gruntのプラグインを入れていきます。grunt-contribをいれれば、基本的なプラグインが入るのですが、 今回は練習の為に一つずつ入れてみたいと思います。

今回導入するプラグイン
  • grunt-contrib-watch(ファイルを監視し更新があった時、処理を実行する)
  • grunt-contrib-cssmin(cssファイルをminifyする)

npmでプラグインを入れていきます。こちらも --save-devオプションをつけてpackage.json に情報を追記します。

$ npm install grunt-contrib-watch grunt-contrib-cssmin --save-dev

処理が完了すると、package.jsonにプラグインの情報が追記され、node_modulesディレクトリにプラグインのディレクトリが出来ていると思います。

{
  "name": "test",
  "version": "1.0.0",
  "description": "",
  "main": "Gruntfile.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "atsu666",
  "license": "ISC",
  "devDependencies": {
    "grunt": "^0.4.4",
    "grunt-contrib-cssmin": "^0.9.0", // 追記された
    "grunt-contrib-watch": "^0.6.1" // 追記された
  }
}

せっかくなので、node_modulesディレクトリを削除してもう一度同じ環境を用意してみようと思います。 package.jsonがあるので、以下のコマンド一発で同じ環境が用意できると思います。

$ npm install // package.jsonの情報を元にGruntやプラグインをインストール

Gruntfile.jsの作成

Gruntを実行する環境はできましたが、これだけでは、動きません。 実際に動作をさせたいタスクを書いていきます。

タスクを記述するのはGruntfile.jsになります。

基本的なフォーマット

以下が全てのGruntfileに共通するフォーマットになります。この中にタスクを書いていきます。

module.exports = function(grunt) {
};

設定オブジェクトを初期化

grunt.initConfigオブジェクトで設定の初期化を行います。プラグインの設定などをここでする事になります。

grunt.initConfig({
  cssmin: { // grunt-contrib-cssminの設定
    compress: {
      files: {
        './test.min.css': ['themes/xxx/css/*.css']
      }
    }
  },
  watch: { // grunt-contrib-watchの設定
    files: ['themes/xxx/css/*.css'],
    tasks: ['cssmin']
  }
});
grunt-contrib-cssminの設定
cssディレクトリ以下のcssファイルをminify&結合してtest.min.cssというファイルを生成
grunt-contrib-watchの設定
cssディレクトリ以下のcssファイルを監視し、更新があった場合にタスク cssmin を実行

プラグインのロード

タスクを書く事が出来ましたが、まだ動きません。次に使用するプラグインをロードします。 ロードするにはgrunt.loadNpmTasks()を使用します。

grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.loadNpmTasks('grunt-contrib-watch');

この段階でGruntタスクが動くようになりました。 以下のコマンドを打つと実際に動きます。

$ grunt cssmin watch

ただ、タスクが増えてくるとコマンドを打つのが面倒くさくなります。 そこで、grunt.registerTaskを使いデフォルトのタスクを登録します

grunt.registerTask('default', ['cssmin', 'watch']);

$ grunt // タスクを指定しなくても登録されているタスクが実行される

ここまでで、Gruntを無事動かす事が出来たと思います。

もう少し触ってみる

せっかくなので、もう少しだけGruntfileを触ってみます。 まずファイルの指定方法ですが、Glob形式でいろいろとマッチングできます。

themes/**/css/*css
// themesディレクトリ以下のサブディレクトリにあるcssディレクトリ直下のcssファイル
// サブディレクトリは何回層でもいいので使えそうですね。

images/*.{gif,jpeg,jpg,png}
// {}を使ってOR条件でファイルの拡張子を指定しています。

Gruntのテンプレートエンジン GruntにはデフォルトでUnderscore.jsライクなテンプレートエンジンがあるそうです。なのでこれを利用してpackage.jsonの情報を使ってみたいと思います。

grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'), // package.jsonの読み込み
    cssmin: {
      compress: {
        files: {
          './<%= pkg.name %>.min.css': ['themes/**/*.css'] // <%= %>で変数を展開できる(パッケージ名をファイル名に指定)
        }
      }
    },
    watch: {
      files: ['themes/**/css/*.css'],
      tasks: ['cssmin']
    }
  });

という事でGruntをインストールから一応動くところまでやってみました。 次は実践的な内容を書きたいです。


tag : js 学習 grunt 自動化