JavaScriptやCSSの開発工程を自動化するGruntとは何か?

フロントエンドのWEB開発はここ数年で、とても高度になった代わりに、かなり工程が増えました。

昔は単純でした。

  1. CSSを書く。
  2. CSSをアップロードする。

最近は、こうです。

  1. LESSやSassを書く。
  2. CSSにプリコンパイルする
  3. プリコンパイルしたCSSをminifyする。
  4. minifyしたCSSをgzip圧縮する。
  5. gzip圧縮されたCSSをアップロードする。

CSSだけでなくJavaScriptも同様に、実際にコーディングしたものに対して多段階の処理をして公開します。理由があって複雑になっているのですが、かなり面倒です。

Gruntを使って全部を自動化する。

こういう機械的な工程は、Gruntを使って簡単に自動化することができます。

スクリーンショット 2014-04-06 18.48.48

Grunt: The JavaScript Task Runner

今までは「wro4jでリソースをminifyし、Jettyでレスポンスをgzip化して通信する。」に書いたように、Mavenにフロントエンドの処理もさせていました。しかし、MavenはJavaのためのツールで、Javaはフロントエンド開発には使われないので、いまいち親和性がよくありませんでした。

Gruntとは何か?なぜGruntか?

Gruntは、先ほど書いたようなWEB開発の作業工程を自動化するツールです。公式サイトには、「Gruntはタスクランナーです」と記載があります。

Gruntは、必要なパッケージを組み合わせて使います。Gruntは、フロントエンド開発に関わるほぼ全て工程をカバーしています。だから、どんな言語や環境で開発をしていても、その全てを自動化することができます。

そういうわけで、実際にコードを書く以外の作業は全てGruntで自動化して、自分はコードを書くことに集中することができます。

Gruntをインストール

さっそくインストールしてみます!npmからインストールすることができます。

npm install -g grunt-cli

root権限が必要な場合はsudoして実行してください。

$ grunt --version
grunt-cli v0.1.13

これでインストールが完了です!

JavaScriptをminifyして容量を削減する

今回は、例として、JavaScriptのminifyの工程をGruntで自動化してみます。minifyとは、プログラムの構造を変えずにソースコードを圧縮して、ファイルの容量を削減する作業です。

プロジェクトの構成は、index.htmlとmain.jsだけです。このmain.jsをminifyします。

$ ls
index.html	main.js

index.htmlは特に内容はないですが、jQueryとmain.min.jsを読むようにしておきます。main.jsをminifyして、main.min.jsという名前で保存できればゴールです。

<!doctype html>
<html lang="ja">
    <body>
        <div id="main">
        </div>
        <script type="text/javascript" src="http://code.jquery.com/jquery-2.1.0.min.js"></script>
        <script type="text/javascript" src="./main.min.js"></script>
    </body>
</html>

main.jsは、文字列を表示するだけの単純なものです。

$(fucntion()) {
	$('#main').text('Hello World');
});

Gruntで作業を自動化するための設定をしていきます。

package.jsonの作成

Gruntの設定ファイルで重要なのは、package.jsonとGruntfile.js です。

ファイル名 使う人 内容
package.json npm どういうパッケージを使用するか?
Gruntfile.js Grunt パッケージを使ってどういう処理をするか?

package.jsonはnpmのための設定で、Gruntfile.jsがGruntのための設定です。Gruntが使用するパッケージはnpmからインストールするため、先にnpmの設定が必要になります。

まずは、package.jsonを作成するために、作業ディレクトリでnpm initを実行します。

npm init

色々と聞かれますが、テキトーに打ち込んでいくと、package.jsonというファイルが生成されます。

$ ls
index.html	main.js		package.json

内容を見てみると、パッケージに関する情報はまだ含まれていないようです。

{
  "name": "gruntexample",
  "version": "0.0.0",
  "description": "ERROR: No README.md file found!",
  "main": "main.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": "",
  "author": "",
  "license": "BSD"
}

package.jsonは、Gruntの設定ではなく、npmの設定です。まずは、Gruntが使えるように、ここに設定を追加します。

npmコマンドに、–save-devオプションを付けて、gruntをインストールします。

npm install grunt --save-dev

すると、node_modulesというディレクトリが作成され、中にgruntのパッケージがインストールされます。

$ ls
index.html	main.js		node_modules	package.json
$ ls node_modules/
grunt

これで、このディレクトリでgruntが使えるようになりました。

先ほどのpackage.jsonにも、gruntへの依存情報が追加されています。

{
  "name": "gruntexample",
  "version": "0.0.0",
  "description": "ERROR: No README.md file found!",
  "main": "main.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": "",
  "author": "",
  "license": "BSD",
  "devDependencies": {
    "grunt": "~0.4.4"
  }
}

こうやって、package.jsonには、必要なパッケージの情報を記載するわけです。

grunt-contrib-uglifyパッケージのインストール

gruntだけでは、実際の処理ができないので、「JavaScriptをminifyする」という今回の目的のためのgrunt-contrib-uglifyパッケージをインストールします。

今度は先ほどと違う方法でパッケージをインストールします。先に、package.jsonを書き換えて、そこからパッケージをインストールしてみます。

まずpackage.jsonに、grunt-contrib-uglifyを追加します。

{
  // ...(略)...
  "devDependencies": {
    "grunt": "~0.4.4",
    "grunt-contrib-uglify": "~0.4.0"
  }
}

そして、npm installを実行すると、不足しているgrunt-contrib-uglifyをインストールしてくれます。

npm install

確認してみます。

$ ls node_modules/
grunt			grunt-contrib-uglify

このように、package.jsonを変えてnpm installすると、node_modulesディレクトリ内のパッケージが同期されます。

Gruntfile.jsの作成

必要なパッケージがインストールできたので、本丸のGruntの設定へ移ります。Gruntの設定は、Gruntfile.jsへ記述します。

grunt-contrib-uglifyパッケージを使って、main.jsをminifyして、main.min.jsにするという設定です。

module.exports = function(grunt) {
	grunt.initConfig({
		uglify : {
			main : {
				files : {
					'main.min.js' : ['main.js']
				}
			}
		}
	});
	grunt.loadNpmTasks('grunt-contrib-uglify');
	grunt.registerTask('default', ['uglify']);
};

loadNpmTasks関数で必要なパッケージをロードし、initConfigに処理の設定を記述し、registerTaskに処理の流れを記述します。

$ ls
Gruntfile.js	index.html	main.js		node_modules	package.json

これで、package.jsonとGruntfile.jsが揃いました!

Gruntで処理をする

設定が終わったら、あとはGruntを実行するだけです。gruntコマンドで、設定した処理が実行されます。

$ grunt
Running "uglify:main" (uglify) task
File main.min.js created: 68 B → 62 B
 
Done, without errors.

問題なく処理が成功したら、main.min.jsが生成されるはずです。

$ ls
Gruntfile.js	index.html	main.js		main.min.js	node_modules	package.json

main.min.jsの中身を見ると、JavaScriptの処理に不要な改行やスペースが除去され、容量が削減されていることが分かります!

$(document).ready(function(){$("#main").text("Hello World")});

これで、さきほどのHTMLにHello Worldが表示できました。

スクリーンショット 2014-04-06 19.44.50

Gruntをチーム開発で使う

チーム開発でGruntを使うと、更に威力を発揮します。これからは、開発メンバー全員に「CSSを書いたらminifyしてgzipして・・・」と工程を説明しなくても、「CSSを書いたらgruntして!」で済みます。

ソースコードのバージョン管理にGitを使っている場合、npmでインストールされたパッケージをGitの管理下に入れたくないです。その場合は、node_modulesディレクトリを丸ごと.gitignoreに追加して、Gitの管理外にします。ついでに自動生成されたファイルも.gitignoreに追加しておくと良いかもしれません。

echo 'node_modules' >> .gitignore
echo '*.min.js' >> .gitignore

初回だけ開発メンバーにnpmでパッケージをインストールしてもらいます。それ以降はgruntコマンド一発で、どんどん作業が進められます。

# 初回のみGruntに必要なパッケージをインストールする。
npm install
# あとはビルドしたいタイミングでGruntを実行するだけ
grunt

パッケージを組み合わせると、ファイルを保存したタイミングで自動的に処理を実行したりもできます。これは便利です!

参考にしたページ

次のページを参考にしました。

Web制作で面倒な作業を自動化するビルドツール、Grunt v0.4 入門 | Web Design KOJIKA17
grunt.js – Grunt入門 – Qiita
Gruntの復習 (2)Gruntfile.jsを書く – 鴨のいいカモです

About katty0324

Scroll To Top