grunt-contrib-requirejsを試してみた
ちょっと前から、JS力を上げようと足掻いてます
今回はその中でも以下の内容を模索してみました
1.package管理
2.ミニファイ&ファイル連結
3.ファイル監視して、自動で2をやる
1をやりたいのは、以下の様な理由から
- そのページに必要なJSだけを読み込みたかった
- 他にも依存関係をぱっと見で分かるようにしたかった
- global領域を汚染しないようにしたかった
2をやりたいのは、以下の様な理由から
- 役割毎にファイルを分けたいが、jsファイルを読み込むオーバーヘッドは極力少なくしたい
そして、RequireJSがそれを解決してくれそう
3をやりたいのは、以下の様な理由から
- 開発時にjsファイルを修正する度に、commandやらを打つのは面倒・・・
ClosureLibraryでも上記は満たせるのだけど、流石に仕事に使うにはマニアックな気もするので、
一般的?にはどうやるのか調べてみることに
そして、Grunt: The JavaScript Task Runnerがそれを解決してくれそう
gruntjsはtwitterのTLでちらほら見かけていたので、気になっていました
この2つを組み合わせればいけるか!?などと思っていたら、grunt-contrib-requirejs - npmがあることに気付きました
因みにこいつはGrunt0.4系でないと動かないみたいです
ちょっと前にgrunt.js試した時に、0.3系入れていたので、今回VersionUp
というわけで、上記を満たすために、挑戦してみました
挑戦した結果はGithubに置いてます
GitHub - sinmetal/webproject-template at develop
まず、grunt.jsを動かすためにはNode.jsが必要なので、適当に入れます
Macだと公式ページから一発でInstallできるけど、他のOSだとどうなのかな?
以下の手順も全てMacでやったことなので、他OSだと動くのかは分かりません
次にgruntを入れます
Getting started - Grunt: The JavaScript Task Runner
公式に書いてある通り、
でいれます
npm install -g grunt-cli
Macだとsudoが必要になると思います
grunt.jsの設定ファイルをプロジェクトの直下に置きます。
Gruntfile.js
webproject-template/Gruntfile.js at develop · sinmetal/webproject-template · GitHub
いくつかの設定を書いているので、ちょっとずつ説明していきます
module.exports = function(grunt) {
grunt.initConfig({
// 監視用の設定
watch: {
files: './src/**',
tasks: ['requirejs']
},// requirejs用の設定
requirejs: {
compile_top: {
options: {
name : 'main', // mainで読み込むjsのpath
baseUrl: "./src/js",
mainConfigFile: './src/js/main.js',
out: "./build/toppage.js"
}
},compile_page1: {
options: {
name : 'page1/main', // mainで読み込むjsのpath
baseUrl: "./src/js",
mainConfigFile: './src/js/page1/main.js',
out: "./build/page1.js"
}
}
},
});//matchdepでpackage.jsonから"grunt-*"で始まる設定を読み込む
require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);
//grunt.loadNpmTasks('grunt-contrib-watch');
//grunt.loadNpmTasks('grunt-contrib-requirejs');
}
まずは、先頭のwatch
これは、ファイル監視用の設定です
watch: {
files: './src/**',
tasks: ['requirejs']
}
grunt-watch
'./src/**'src以下のファイルに変更があった場合、'requirejs'を実行しろ!となります
僕がjsファイルをsrcの下に置いていて、requirejsのビルドのタスク名が'requirejs'なので、こうなります
これで、jsファイル修正時に、自動でビルドが走るように設定できました
次のrequirejs
これは、grunt-contrib-requirejs - npmのための設定です
// requirejs用の設定
requirejs: {
compile_top: {
options: {
name : 'main', // mainで読み込むjsのpath
baseUrl: "./src/js",
mainConfigFile: './src/js/main.js',
out: "./build/toppage.js"
}
},compile_page1: {
options: {
name : 'page1/main', // mainで読み込むjsのpath
baseUrl: "./src/js",
mainConfigFile: './src/js/page1/main.js',
out: "./build/page1.js"
}
}
},
});
'compile_top', 'compile_page1'の2つのページ用の設定を書いています
各ページのメインとなるjsのPathをnameで指定します
name:'page1/main'で、baseUrl:'./src/js'なので、'./src/js/page1/main.js'を見に行きます
mainConfigFileが同じファイルを指しているのは、依存関係をそのファイルに書いているからです
これについては、そのファイルが出た時に説明します
out: './build/page1.js'はミニファイ&ファイル連結されたファイルが出力されるPathです
これで設定は完了です
最後にnpm installで入れる設定の一覧
4行あるけど、実際に動いているのは1行だけ
//matchdepでpackage.jsonから"grunt-*"で始まる設定を読み込む
require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);
//grunt.loadNpmTasks('grunt-contrib-watch');
//grunt.loadNpmTasks('grunt-contrib-requirejs');
ここの部分は、matchdepを使ってGrunt.jsのプラグインを自動ロードするを参考にさせてもらいました
npm installの設定をGruntfile.jsとpackage.jsonの両方に書くのが面倒だから、
package.jsonを見に行くようにするってのが、metchdepです
入れ方なんかは、上記のリンク先を参照してください
これで、Gruntfile.jsの設定はおしまいです。
次は、package.jsonです
ここに書いてある"grunt-*"が利用しているgruntのpluginの一覧です
{
"name": "webproject-template",
"version": "0.1.0",
"devDependencies": {
"grunt": "~0.4.1",
"grunt-contrib-watch": "~0.3.1",
"grunt-contrib-requirejs": "~0.4.0",
"matchdep": "~0.1.1"
}
}
Projectの直下で
すると、node_modulesというディレクトリの下にインストールされます
npm install
これで準備は完了です
ここからは実際にどんな感じで作っていくかというのを書いていきます
まず、途中で少し出てきたけど、ディレクトリ構成は以下の様な感じ
build // buildされた結果のjs
+-page1.js
-toppage.js
page1
+-index.html
src
+-js
+-lib // OSSのLibraryとか
+-jquery.js // jQuery公式からDLしてきた
-require.js // requirejs公式からDLしてきた
-module // 自分で作ったutilとか置く場所
+-fuga.js
-hoge.js
-page1 // page1固有
+-main.js
-main.js // toppageのmain.js
Gruntfile.js
index.hml
package.json
まずは、moduleの中にあるhoge.jsです
defineで依存しているjsのpathを書きます
define([
'lib/jquery'
], function($) {
var Hoge = function() {};
Hoge.prototype.awesomeThod = function() {
console.log('Hellow RequireJS!');
};Hoge.prototype.outputLog = function(text) {
console.log(text);
};return Hoge;
});
ここではjQueryを指定しています
・・・使ってはいませんけど
後は、定義したいメソッドやらを作っていけば、OKです
次に、moduleを呼び出しているmain.jsです
//main.js
require.config({
baseUrl: 'js',
paths: {
'jquery': 'lib/jquery.js'
}
});require([
'module/hoge',
'module/fuga'
], function(Hoge, Fuga) {
// Hogeにはhoge.jsで定義されたコンストラクタが渡る
var hoge = new Hoge();
hoge.awesomeThod();
});
require.configが上の方に書いたmainConfigFileに指定した設定です
設定できる項目についてはhttp://d.hatena.ne.jp/maneater_rhythm/20130219/1361282887で詳しく書いてくれてます
require〜〜の部分が、処理の内容を書くところです
'module/hoge'でmodule/hoge.jsを読み込んでます
こいつの読み込みが終わると、Hogeに入れてくれます
後は使うだけ!
最後にindex.htmlです
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Web Project Template for Sinmetal</title> </head> <body> <p>Used Libraries</p> <ul> <li><a href="http://jquery.com/">jQuery</a></li> <li><a href="http://requirejs.org/">RequireJS</a></li> </ul> <p>Other Page</p> <ul> <li><a href="page1/index.html">page1</a></li> </ul> <script src="src/js/lib/require.js"></script> <script src='build/toppage.js'></script> </body> </html>
require.jsと、buildされたtoppage.jsを読み込んでいます
html側は特出することはないので、これだけです
後は、commandについても紹介しておきます
上記のプロジェクトをビルドするには
でできます
grunt requirejs
これは、Gruntfile.jsに書いてある設定の名前が、requirejsだからです
デフォルトを指定しておけば、引数無しで行けるとだと思うのだけど、デフォルト設定してないので・・・
後、ファイル監視
こいつもGruntfile.jsに書いてある設定の名前が、watchだから
grunt watch
これを起動しておけば、jsに修正が入った時に、自動でrequirejsを実行してくれます
以上でgrunt-contrib-requirejsを試してみた!は終わりです
そして、ここまで読んだ聡明な方なら、気付いてしまったと思うのですが・・・テストの設定が無い
まだ、JSのテストをいまいちどうやれば良いのか分かってないので、設定できてないorz