Hatena::ブログ(Diary)

SinDiary Twitter

2013-03-31

grunt-contrib-requirejsを試してみた

ちょっと前から、JS力を上げようと足掻いてます

今回はその中でも以下の内容を模索してみました


1.package管理

2.ミニファイ&ファイル連結

3.ファイル監視して、自動で2をやる


1をやりたいのは、以下の様な理由から

  • そのページに必要なJSだけを読み込みたかった
  • 他にも依存関係をぱっと見で分かるようにしたかった
  • global領域を汚染しないようにしたかった

2をやりたいのは、以下の様な理由から

  • 役割毎にファイルを分けたいが、jsファイルを読み込むオーバーヘッドは極力少なくしたい

そして、RequireJSがそれを解決してくれそう


3をやりたいのは、以下の様な理由から

  • 開発時にjsファイルを修正する度に、commandやらを打つのは面倒・・・

ClosureLibraryでも上記は満たせるのだけど、流石に仕事に使うにはマニアックな気もするので、

一般的?にはどうやるのか調べてみることに

そして、no titleがそれを解決してくれそう


gruntjsはtwitterのTLでちらほら見かけていたので、気になっていました

この2つを組み合わせればいけるか!?などと思っていたら、no titleがあることに気付きました

因みにこいつはGrunt0.4系でないと動かないみたいです

ちょっと前にgrunt.js試した時に、0.3系入れていたので、今回VersionUp


というわけで、上記を満たすために、挑戦してみました

挑戦した結果はGithubに置いてます

GitHub - sinmetal/webproject-template at develop


まず、grunt.jsを動かすためにはNode.jsが必要なので、適当に入れます

Macだと公式ページから一発でInstallできるけど、他のOSだとどうなのかな?

以下の手順も全てMacでやったことなので、他OSだと動くのかは分かりません


次にgruntを入れます

no title

公式に書いてある通り、

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で読み込むjspath
          baseUrl: "./src/js",
          mainConfigFile: './src/js/main.js',
          out: "./build/toppage.js"
        }
      },

      compile_page1: {
        options: {
          name : 'page1/main',  // mainで読み込むjspath
          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

    // requirejs用の設定
    requirejs: {
      compile_top: {
        options: {
          name : 'main',  // mainで読み込むjspath
          baseUrl: "./src/js",
          mainConfigFile: './src/js/main.js',
          out: "./build/toppage.js"
        }
      },

      compile_page1: {
        options: {
          name : 'page1/main',  // mainで読み込むjspath
          baseUrl: "./src/js",
          mainConfigFile: './src/js/page1/main.js',
          out: "./build/page1.js"
        }
      }
    },
  });

これは、no titleのための設定です

'compile_top', 'compile_page1'の2つのページ用の設定を書いています

各ページのメインとなるjsPathをnameで指定します

name:'page1/main'で、baseUrl:'./src/js'なので、'./src/js/page1/main.js'を見に行きます

mainConfigFileが同じファイルを指しているのは、依存関係をそのファイルに書いているからです

これについては、そのファイルが出た時に説明します

out: './build/page1.js'はミニファイ&ファイル連結されたファイルが出力されるPathです

これで設定は完了です


最後にnpm installで入れる設定の一覧

//matchdepでpackage.jsonから"grunt-*"で始まる設定を読み込む
require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);
//grunt.loadNpmTasks('grunt-contrib-watch');
//grunt.loadNpmTasks('grunt-contrib-requirejs');

4行あるけど、実際に動いているのは1行だけ

ここの部分は、matchdepを使ってGrunt.jsのプラグインを自動ロードするを参考にさせてもらいました

npm installの設定をGruntfile.jsとpackage.jsonの両方に書くのが面倒だから、

package.jsonを見に行くようにするってのが、metchdepです

入れ方なんかは、上記のリンク先を参照してください


これで、Gruntfile.jsの設定はおしまいです。

次は、package.jsonです

{
  "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"
  }
}

ここに書いてある"grunt-*"が利用しているgruntのpluginの一覧です

Projectの直下で

npm install

すると、node_modulesというディレクトリの下にインストールされます


これで準備は完了です

ここからは実際にどんな感じで作っていくかというのを書いていきます

まず、途中で少し出てきたけど、ディレクトリ構成は以下の様な感じ

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([
	'lib/jquery'
], function($) {
	var Hoge = function() {};
	Hoge.prototype.awesomeThod = function() {
		console.log('Hellow RequireJS!');
	};

	Hoge.prototype.outputLog = function(text) {
		console.log(text);
	};

	return Hoge;
});

defineで依存しているjspathを書きます

ここでは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に指定した設定です

設定できる項目についてははてなダイアリーで詳しく書いてくれてます

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だからです

デフォルトを指定しておけば、引数無しで行けるとだと思うのだけど、デフォルト設定してないので・・・

後、ファイル監視

grunt watch

こいつもGruntfile.jsに書いてある設定の名前が、watchだから

これを起動しておけば、jsに修正が入った時に、自動でrequirejsを実行してくれます


以上でgrunt-contrib-requirejsを試してみた!は終わりです

そして、ここまで読んだ聡明な方なら、気付いてしまったと思うのですが・・・テストの設定が無い

まだ、JSのテストをいまいちどうやれば良いのか分かってないので、設定できてないorz

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/sinmetal/20130331/1364742840
リンク元