今更だけどやるgrunt入門編・インストールから基本的な使い方

Javascript

JavaScriptやCSSの結合や圧縮などいろいろな事を自動で処理してくれるGruntですが、もう話題になってずいぶん立ちますが今更ながら入れてみましたのでその方法です。

前にGruntの話題で盛り上がった時に試してみたのですがどうしても動かず原因もわからずで止まっていたのですが、情報も増えてきたので再チャレンジでした。

結果的に原因もわかったのでGruntの入れ方と基本的な使い方を書いておこうと思います。

node.jsのインストール

Gruntを使うためにはnode.jsが必要になりますので、以下のサイトからnode.jsをダウンロードします。

ダウンロードしたものを実行します。

これでnode.jsがインストールできたはずです。

コマンドを起動

次にコマンドを起動します。「管理者として実行」をクリックします。

まずはnode.jsが入ったか確認してみましょう。以下のコードを実行してみましょう。

node -v

ちゃんとインストール出来ていると以下のようにバージョンが表示されます。

v0.10.25

私はこの記事を書いている時点での最新バージョン0.10.25が表示されています。

grunt-cliをインストール

次にgruntの核となるgrunt-cliをインストールします。以下のコマンドを実行します。

npm install -g grunt-cli

そうすうとコマンドの画面にガーッつといろいろ表示され、インストールが完了します。

package.jsonを作成する

次にpackage.jsonというのを作成します。パッケージのバージョン管理をしてくれるファイルのようです。

ここからは作業を行うディレクトリで実行していくので、まずはコマンドでそのディレクトリまで移動しましょう。コマンドで

cd [ディレクトリまでのパス]

を実行します。そうすると作業ディレクトリに移動できるので、そこで以下のコマンドを実行します。

npm init

そうするとコマンド画面の中で項目をいろいろ聞かれます。特に指定しなくても大丈夫なので、Enterでどんどん進みます。そうするとpackage.jsonがフォルダに作成されます。

中を見てみると以下のように記述されています。nameの部分は私が作成したテストのディレクトリが「_grunttest」だったためです。

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

このように中に記述されていると思います。

フォルダにgruntをインストール

ここでgruntをインストールします。コマンドで以下を実行します。

npm install grunt -save-dev

そうすると先ほど作成したpackage.jsonに太字の箇所の記述が増えてると思います。

{
  "name": "_grunttest",
  "version": "0.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
  "devDependencies": {
    "grunt": "~0.4.2"
  }
}

gruntのバージョン0.4.2が入りました。

Windows7で便利なコマンドを実行しておく

Windows7だとgruntを実行する場合、「grunt」だけではダメで「grunt.cmd」としないと実行されません。前にやった時はここで詰まっていたようです。情報を調べるとみんなMacなのかあまりこの情報を見かけませんでした。

なのでここから先便利なように以下のコマンドを実行しておきます。

DOSKEY grunt=grunt.cmd $*

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

さて、次に使いたいgruntのプラグインをインストールします。本当は使う機能だけインストールしたほうがデータ量的にいいかと思いますが、とりあえず試す用なので一気にインストールしてみます。

npm install grunt-contrib -save-dev

個別にインストールする場合は以下のように記述します。赤字の箇所です。

npm install grunt-contrib-cssmin -save-dev

プラグインをインストールすると、package.jsonが以下のように変わっていると思います。

{
  "name": "_grunttest",
  "version": "0.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "grunt": "~0.4.2",
    "grunt-contrib-concat": "~0.3.0",
    "grunt-contrib-copy": "~0.4.1",
    "grunt-contrib-sass": "~0.5.1",
    "grunt-contrib-csslint": "~0.1.2",
    "grunt-contrib-requirejs": "~0.4.1",
    "grunt-contrib-compass": "~0.6.0",
    "grunt-contrib-clean": "~0.5.0",
    "grunt-contrib-htmlmin": "~0.1.3",
    "grunt-contrib-jst": "~0.5.1",
    "grunt-contrib-coffee": "~0.7.0",
    "grunt-contrib-cssmin": "~0.6.2",
    "grunt-contrib-watch": "~0.5.3",
    "grunt-contrib-uglify": "~0.2.7",
    "grunt-contrib-handlebars": "~0.5.12",
    "grunt-contrib-jshint": "~0.6.5",
    "grunt-contrib-stylus": "~0.8.0",
    "grunt-contrib-connect": "~0.5.0",
    "grunt-contrib-jade": "~0.8.0",
    "grunt-contrib-qunit": "~0.3.0",
    "grunt-contrib-compress": "~0.5.3",
    "grunt-contrib-jasmine": "~0.5.2",
    "grunt-contrib-less": "~0.7.0",
    "grunt-contrib-nodeunit": "~0.2.2",
    "grunt-contrib-imagemin": "~0.3.0",
    "grunt-contrib-yuidoc": "~0.5.0",
    "grunt-contrib": "~0.8.0"
  }
}

全部入れたのですごい量になってます。

Gruntfile.jsを作って動いているか確認する

ここで実際に動くかどうかを試してみたいと思います。今回はまず同じディレクトリにtest.htmlを用意しました。htmlの中身は適当です。次にGruntfile.jsという名前のファイルを同じディレクトリに新規作成で用意します。中身は以下のように記述します。

test.htmlを監視してねという記述です。

module.exports = function(grunt) {

  grunt.initConfig({

    watch: {
      dev: {
        files: ["test.html"]
      }
    }

  });

  //使うプラグインの読み込み
  grunt.loadNpmTasks('grunt-contrib-watch');

};

そして、以下のコマンドを実行します。

grunt watch

そうするとコマンドの画面にwatchが動いてるよという表示が出ます。

動いてるのが確認できたら作ったtest.htmlの中身を適当に変更して保存します。コマンド画面を見るとtest.htmlが変わったよ!と教えてくれています。

これで基本的な動作の確認が出来ました。

JavaScriptを結合しよう

次にgruntでよく使いそうなJavaScriptの結合を試してみたいと思います。まずは以下のようにjsファイルを2つ用意します。ディレクトリは先程のディレクトリにjsというフォルダを作成してその下に置いています。

そしてjs01.jsには以下の様な記述をしました。

$(function(){

    var boxW = $('.box').width();
    var boxH = $('.box').height();

});

js02.jsには以下の記述。

$(function(){

    var boxIW = $('.box').innerWidth();
    var boxIH = $('.box').innerHeight();

});

そして、Gruntfile.jsを変更します。赤字の箇所です。

module.exports = function(grunt) {

  grunt.initConfig({

    concat : {
      dist : {
        src : [
          'js/js01.js',
          'js/js02.js'
        ],
          dest : 'js/main.js'
        }
    },

    watch: {
      dev: {
        files: ["js/*.js"],
        tasks: ['concat']
      }
    }

  });

  //使うプラグインの読み込み
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-concat');

};

ファイルの結合にはgrunt-contrib-concatというプラグインを使うのでその記述が増えています。

  • concatのsrcに結合するファイルを記述
  • concatのdestに結合後のファイル名を記述
  • watchには監視して欲しいファイルと実行したいタスクを書きます。

これで先ほどと同じにコマンドでgrunt watchを実行します。そうすると設定したmain.jsが作成されています。

作成されたmain.jsの中を見てみると以下のようになっています。

$(function(){

    var boxW = $('.box').width();
    var boxH = $('.box').height();

});
$(function(){

    var boxIW = $('.box').innerWidth();
    var boxIH = $('.box').innerHeight();

});

js01.jsとjs02.jsの中身が一緒になってることがわかります。

jsを圧縮する

次にJavaScriptを圧縮してくれるgrunt-contrib-uglifyを使ってみます。

Gruntfile.jsを以下のように書き換えます。

module.exports = function(grunt) {

  grunt.initConfig({

    uglify: {
      dist: {
        src: "js/main.js",
         dest: "js/main-min.js"
      }
    },

    concat : {
      dist : {
        src : [
          'js/js01.js',
          'js/js02.js'
        ],
          dest : 'js/main.js'
      }
    },

    watch: {
      dev: {
        files: ["js/*.js"],
        tasks: ['concat','uglify']
      }
    }

  });

  //使うプラグインの読み込み
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-concat');
  grunt.loadNpmTasks('grunt-contrib-uglify');

};

先ほどconcatを追加したようにuglifyを追加しています。

これでまたgrunt watchをコマンドで実行すると、main-min.jsが出来上がります。

main-min.jsの中身を見ると以下のようになっています。

$(function(){$(".box").width(),$(".box").height()}),$(function(){$(".box").innerWidth(),$(".box").innerHeight()});

Gruntfile.jsを少しスマートに

ここまで使ってきて思うかもしれませんが、プラグインが増える度に記述が増えていきます。 なのでプラグインの読み込み部分をもっと簡素になるように変更します。

module.exports = function(grunt) {

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

  grunt.initConfig({

    uglify: {
      dist: {
        src: "js/main.js",
        dest: "js/main-min.js"
      }
    },

    concat : {
      dist : {
        src : [
          'js/js01.js',
          'js/js02.js'
        ],
        dest : 'js/main.js'
      }
    },

    watch: {
      dev: {
        files: ["js/*.js"],
        tasks: ['concat']
      }
    }

  });

  var taskName;
  for(taskName in pkg.devDependencies) {
    if(taskName.substring(0, 6) == 'grunt-') {
      grunt.loadNpmTasks(taskName);
    }
  }

};

package.jsonで読み込んでいるプラグインを記述するように変更しました。これでプラグインの読み込み箇所を毎回追加せずにすみます。

実行するタスクをまとめる

またコマンドで毎回grunt watch等の入力するのが手間なので以下の追記をします。

module.exports = function(grunt) {

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

  grunt.initConfig({

    uglify: {
      dist: {
        src: "js/main.js",
        dest: "js/main-min.js"
      }
    },

    concat : {
      dist : {
        src : [
          'js/js01.js',
          'js/js02.js'
        ],
        dest : 'js/main.js'
      }
    },

    watch: {
      dev: {
        files: ["js/*.js"],
        tasks: ['concat','uglify']
      }
    }
  });

  var taskName;
  for(taskName in pkg.devDependencies) {
    if(taskName.substring(0, 6) == 'grunt-') {
      grunt.loadNpmTasks(taskName);
    }
  }

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

};

これをするとコマンド画面にgruntと記述し実行するだけで、registerTaskに書いたタスクが順番に実行されます。

次回起動する時

作業を再開するときはWindow7の場合は先ほど紹介した

DOSKEY grunt=grunt.cmd $*

を実行しないと「grunt」では動いてくれないみたいなので注意です。一回一回面倒な場合は

grunt.cmd

で実行しましょう。

これで基本的な使い方が出来ました。他にも様々な使い方やプラグインがあると思いますのでいろいろ試しつつ使っていけたらいいなと思います。

参考サイト

以下のサイトに大変お世話になりました。ありがとうございます。