2014/07/25(Fri) サービス開発
根津 陽

今更聞けない人の為のGrunt再入門

どうも、School Withのフロントをあれこれ作っている根津です。
弊社鈴木の『今更聞けない人の為の◯◯◯』シリーズが好評になってきたので、それにのっかって、フロントエンド側の開発についても同様にシリーズ化していこうと思います。

インフラ周りのバックエンドはもちろんですが、最近ではフロントエンドの開発に関して、いろいろなものが登場しては一般化してきました。
ボイラープレート、コンパイラー、テスト、タスクランナー、フレームワークなど…

「いったい何をどう使えばいいの?」ってなりますね。

というわけで、弊社で利用しているフロント周りの技術を紹介していこうと思います。
今回は“Grunt”についてです。

grunt_catch

Gruntって何?

Gruntとはフロントエンドのさまざまな処理を自動化するツールです。
こういった自動化ツールはタスクランナー、ビルドツールなどと呼ばれます。
Gruntは、フロントエンド、すなわちHTML、CSS、Javascriptが主な対象となります。

javaなどの他の言語では、Ant、Maven等のビルドツールが昔からありましたが、フロントエンド周りで一般的に利用されるようになってきたのはここ数年のことだと思います。
当時はまだGruntに関するリファレンスも少なく、導入も大変だったのですが、今ではGruntの導入事例もたくさんありますので、ハードルも下がったと思います。

どういったことを自動化できるの?

WebサイトやWebサービスを構築する際に発生する一般的なタスクはだいたい自動化できます。

例をあげますと

  • ・ソースコードの圧縮
  • ・スプライト画像の作成
  • ・画像の最適化
  • ・sassの管理
  • etc…

この他にもあげたらキリがないくらいあります。
「この作業面倒だな。自動化できないかな」なんて感じるタスクはだいたいGruntで対応できちゃう気がします。

前置きはこのくらいにして、さっそく導入していきましょう。

gruntの実行環境をつくろう!

GruntはNode.jsがベースになっていいます。
そのため、まずはNode.jsをインストールする必要があります。
下記Node.js公式Webサイトより、「INSTALL」ボタンを押してインストールしましょう。
nodejs.org

npmでgrunt-cliを導入する

node.jsはnpmというパッケージ管理ツールを利用しています。
grunt関連のプラグインをインストールするときはnpmコマンドを使っていきます。
まずはgruntをコマンドライン上で利用するためのパッケージ”grunt-cli”をインストールします。

npm install -g grunt-cli

インストールが完了すると下記のような表示がでると思います。

grunt-cli@0.1.13 /usr/local/lib/node_modules/grunt-cli
├── resolve@0.3.1
├── nopt@1.0.10 (abbrev@1.0.5)
└── findup-sync@0.1.3 (lodash@2.4.1, glob@3.2.11)

npmで「-g」をつけると、node.js全体にインストールされます。この形式はグローバルインストールと呼ばれています。「-g」をつけない場合はカレントディレクトリにインストールされます。
基本的に”grunt-cli”以外は「-g」をつけず、対象の作業ディレクトリごとに、必要なプラグインを都度インストールする形式でいいと思います。

ひとまず、これで”grunt-cli”の導入が完了し、gruntの利用していくための下準備ができました。このあとは作業ディレクトリに移動してプラグインの導入&設定を行っていきます。

Gruntをインストールしてみよう!

今回は仮で「/grunt-test」というディレクトリを対象にしていきます。
対象ディレクトリに移動しましょう。

cd /grunt-test

ディレクトリの移動が完了したら、gruntを実行していきます。
まずは下記コマンドを実行します。

npm init

このコマンドを実行すると、”package.json”というファイルが生成されます。生成のために下記の内容を入力するように要求されますが、何も入力せずにenter(return)を押していけばデフォルトの値で生成されます。
ここで入力した内容は後ほど編集できるので、デフォルト値でファイルを生成しましょう。

name: (grunt-test)
version: (0.0.0)
description:
entry point: (index.js)
test command:
git repository:
keywords:
author:
license: (ISC)

“package.json”というファイルが生成されたら、gruntをインストールします。

npm install grunt --save-dev

インストールが終わると、node_modulesというディレクトリが生成されています。プラグインをインストールしていくと、このnode_modulesの中に格納されていきます。

Gruntfile.jsの作成

gruntがインストールされたら、Gruntfile.jsというファイルを作成していきます。
Gruntfile.jsとは、Gruntで実際にどのようなタスクを実行していくかを記述した設定ファイルです。
書き方はルールがありますので、まずはひな形を作成します。

module.exports = function(grunt) {
	//Config : プロジェクトの設定
	grunt.initConfig({
		//initConfigの中にいろいろと設定を書いていきます
	};
	//プラグインの読み込み
	grunt.loadNpmTasks('Plugin-Name');
	//タスクの登録
	grunt.registerTask('default', ['Task-Name']);
};

上記がひな形ファイルになります。
「プラグインの読み込み」と「タスクの登録」については、実際にプラグインを導入した際に記述していくものになります。

このあとは、プラグインをインストールしてタスク実行するだけです。

Gruntを実行してみよう!

さて、実行環境を整えて、Gruntのインストールも無事完了しました。
試しにGruntでタスクを実行してみましょう。

今回実行するのは、以下のタスクです。
・jsファイルの結合
・結合したjsファイルの圧縮

仮でfuga.js、hoge.jsというファイルを用意します。
この2つのファイルを結合して、script.jsというファイルを生成してみましょう。

//hoge.js
(function(){
	var hoge = 'foo';
	console.log(hoge);
})();

//fuga.js
(function(){
	var fuga = 'foo';
	console.log(fuga);
})();

ディレクトリ構成は以下のような形にしています。

grunt-test
―js/
――dev/
―――hoge.js
―――fuga.js
――prd/
―――script.js
―node_modules/
―package.json

1. プラグインをインストールする

まずはプラグインをインストールしていきましょう。

利用するプラグインは
contrib-concat
contrib-uglify
の2つです。

プラグインそれぞれのドキュメントは下記です。
contrib-concat ドキュメント
contrib-uglify ドキュメント
プラグインの探し方については後述します。

プラグインは「npm install XXXXXXX」というコマンドでインストールできます。

npm install grunt-contrib-concat --save-dev
npm install grunt-contrib-uglify --save-dev

コマンドの実行が完了したら、「node_modules」のフォルダを見てみましょう。
「grunt-contrib-concat」と「grunt-contrib-uglify」というフォルダが生成されていると思います。ちなみに、「–save-dev」というオプションをつけることで、package.jsonにも自動的に反映してくれます。
package.jsonに反映させることで、新規でGrunt環境を構築する際にpackage.jsonに書かれているプラグインを自動でインストールしてくれます。一緒に作業するエンジニアと同じ環境をつくるとき非常に便利です。

2. Gruntfile.jsを編集する

インストールが完了したら、Gruntfile.jsに実行内容を記述していきます。

module.exports = function(grunt) {
	//1.プラグインの実行内容の設定
	grunt.initConfig({
		//contrib-concatの設定
		concat: {
			dist: {
				src: ['js/dev/hoge.js','js/dev/fuga.js'],
				dest: 'js/prd/script.js'
			}
		},
		//contrib-uglifyの設定
		uglify: {
			build: {
				src: 'js/prd/script.js',
				dest: 'js/prd/script.min.js'
			}
		}
	});

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

	//3.タスクの登録
	grunt.registerTask('default', [ 'concat', 'uglify' ]);
};

順番に説明します。

1.プラグインの実行内容の設定について
initConfig内に、concatとuglifyの設定が書いてありますが、記述方法はプラグインによって異なります。記述方法の調べ方については”プラグインの探し方”と合わせて後述します。

2.プラグインの読み込み
利用するプラグインの読み込みさせるための記述です。
grunt.loadNpmTasks(‘XXXXXXXX’);という記述で読み込みます。

3.タスクの登録
実行時するときのコマンド名と、その実行内容を登録します。
今回の場合「default」というコマンド名に、’concat’と’uglify’の実行を登録しました。

さっそく実行してみましょう。

grunt default
#実行結果
Running "concat:dist" (concat) task
File js/prd/script.js created.

Running "uglify:build" (uglify) task
File js/prd/script.min.js created: 115B → 83B

Done, without errors.

prdフォルダに”script.js”と”script.min.js”というファイルが生成されるはずです。
それぞれのファイルの中身は以下のようになっているかと思います。

//script.js
(function(){
	var hoge = 'foo';
	console.log(hoge);
})();
(function(){
	var fuga = 'bar';
	console.log(fuga);
})();

//script.min.js
!function(){var a="foo";console.log(a)}(),function(){var a="bar";console.log(a)}();

script.jsには、hoge.jsとfuga.jsのソースが書かれています。そして、script.min.jsには、結合された内容が圧縮されて1行になっており、変数名も短縮されています。

すごく簡単ではありますが、実行テストしてみました。
基本的な流れは
プラグインをインストール → Gruntfile.jsに内容を記述 → 実行
というものになります。
続いて、プラグインの探し方やその使用方法の調べ方を説明します。

プラグインの探し方と使用方法の調べ方

基本的にプラグインはgruntの公式Webサイトに掲載されています。
メニューの「Plugins」のページから検索できます。
gruntjs.org

2014年7月19日時点で3,188のプラグインが登録されています。
ダウンロード数も書いてあり、多いものほど当然みんなに使われているプラグインで参考事例も多いです。

さきほど利用したcontrib-uglifyのドキュメントを見てみましょう。
検索フォームから「contrib-uglify」と入れて、ソートされたページに遷移すればOKです。

ドキュメントはこんな感じ

このページのRead Me項目に基本的な使い方が書いてあります。
英語で書いてあることが多いですが、慣れれば問題ないかと思います。

3000個の中から目的のプラグインをどうやって探すの?
ってか英語苦手なんだけど!

そういったときはGoogle先生に相談しましょう。
例えば、「スプライト画像を生成する」タスクをGruntで処理したいときは
「Grunt 画像 スプライト」などのキーワードで検索すれば、他の方の参考事例が出てきます。
そこで見つけたプラグイン名と使用方法をGruntの公式ドキュメントと見比べて使っていけばだいたい事足りると思います。

まとめ

よほど複雑な処理のタスクでなければ、Gruntで簡単に自動化できます。

最近ではGruntのほかに、gulpというタスクランナーも登場しました。
Gruntは設定ファイルのgruntfile.jsの記述が煩雑な一方で、gulpはかなり簡素に記述できるというメリットがあり、最近注目を集めてきています。ただ、gulpは最近なのでまだ事例は少ないのがネックですかね。
いずれにせよ、これからの時代、面倒なタスクは自動化して処理することがポイントです。

ではでは。

この記事を書いた人
根津 陽 ディレクター

ディレクター兼エンジニア。早稲田大学政治経済学部卒業後、2年間大手web制作会社で、大手通信会社のサイトリニューアル、大手飲料メーカーのキャンペーンなどのフロントの設計、構築を担当する。代表の太田と出会い、School Withのスタートメンバーとしてジョイン。現在はサービスのディレクション、フロント周りのあれこれを担当。趣味はランニングで、フルマラソン4時間切りが目標。好きなラーメンは横浜家系。

School Withとは

School With (スクールウィズ) は海外留学・語学留学の口コミ情報サイトです。

東京ボスストーリー