Require.jsを試してみた

Require.jsはActionScriptのimportのようにjsファイル同士の依存関係を崩さないよう非同期で読み込みつつ、多重読み込みなども防止してくれるライブラリ。
Require.jsを使えば細かくjsファイルを分割してもBackboneやjQuery等のライブラリを依存関係を保ちつつ読み込んでみる。

最小限のコードで挙動を確認してみる。(以降すべてCoffeeScript
これを実行するとMyModelのmessageに定義された「Hello, World!」が出力される。
Backboneに必要なUnderscoreとjQueryはBackboneより先に読み込まれている。

require([
	"libs/jquery-1.10.1.min"
	"libs/underscore.min"
	"libs/backbone.min"
],
($, _, Backbone) ->
	MyModel = Backbone.Model.extend({
		message: "Hello, World!"
	})

	MyView = Backbone.View.extend({
		initialize: (options) ->
			console.log @model.message
	})

	view = new MyView({
		model: new MyModel()
	})
	@
)

今度はRequire.jsの機能のdefineを使ってモジュールを作ってみる。
こちらも同じく「Hello, World!」が出力される。

define("myModule",
[
	"libs/jquery-1.10.1.min"
	"libs/underscore.min"
	"libs/backbone.min"
],
($, _, Backbone) ->
	MyModel = Backbone.Model.extend({
		message: "Hello, World!"
	})

	MyView = Backbone.View.extend({
		initialize: (options) ->
			console.log @model.message
	})

	return {
		modelClass: MyModel
		viewClass: MyView
	}
)

require([
	"myModule"
],
(module) ->
	model = new module.modelClass()
	view = new module.viewClass({
		"model": model
	})
	@
)

require.configのshimでライブラリの依存関係をあらかじめ設定してみる。
実行結果は同様。

require.config(
	shim:
		"libs/backbone.min":
			deps: [
				"libs/jquery-1.10.1.min"
				"libs/underscore.min"
			]
			exports:
				"Backbone"
)

define("myModule",
[
	"libs/backbone.min"
],
(Backbone) ->
	MyModel = Backbone.Model.extend({
		message: "Hello, World!"
	})

	MyView = Backbone.View.extend({
		initialize: (options) ->
			console.log @model.message
	})

	return {
		modelClass: MyModel
		viewClass: MyView
	}
)

require([
	"myModule"
],
(module) ->
	model = new module.modelClass()
	view = new module.viewClass({
		"model": model
	})
	@
)

今度はrequire.configのpathsを使ってライブラリのパスをあらかじめ定義しておく。
こちらも実行結果は同様。

require.config(
	paths:
		"jquery": "libs/jquery-1.10.1.min"
		"underscore": "libs/underscore.min"
		"backbone": "libs/backbone.min"
)

define("myModule",
[
	"jquery"
	"underscore"
	"backbone"
],
() ->
	MyModel = Backbone.Model.extend({
		message: "Hello, World!"
	})

	MyView = Backbone.View.extend({
		initialize: (options) ->
			console.log @model.message
	})

	return {
		modelClass: MyModel
		viewClass: MyView
	}
)

require([
	"myModule"
],
(module) ->
	model = new module.modelClass()
	view = new module.viewClass({
		"model": model
	})
	@
)

今度はshimにもpathsで定義したパスを使ってみる。

require.config(
	paths:
		"jquery": "libs/jquery-1.10.1.min"
		"underscore": "libs/underscore.min"
		"backbone": "libs/backbone.min"

	shim:
		"backbone":
			deps: [
				"jquery"
				"underscore"
			]
			exports:
				"Backbone"
)

define("myModule",
[
	"backbone"
],
() ->
	MyModel = Backbone.Model.extend({
		message: "Hello, World!"
	})

	MyView = Backbone.View.extend({
		initialize: (options) ->
			console.log @model.message
	})

	return {
		modelClass: MyModel
		viewClass: MyView
	}
)

require([
	"myModule"
],
(module) ->
	model = new module.modelClass()
	view = new module.viewClass({
		"model": model
	})
	@
)

require.configでの設定は一度きりなのでこれを無視すると、メインのコードはだいぶスッキリした。

参考:
RequireJS moduleについて – 文殊堂
java-ja.js #2 RequireJS実践編 – 文殊堂
[JS] JavaScriptをモジュール分割して開発できるRequireJSに入門 – YoheiM .NET