通行的Javascript模块化规范共有两种:CommonJS 和 AMD
Node.js 的模块系统,就是参照 CommonJS 规范实现,同步加载模块,提供的方法 require 和 exports
Require.js 参照 AMD 规范实现,异步加载模块,提供的方法 require 和 define
Require.js 定义模块
Require.js 定义模块时,一个文件定义一个模块,使用 define 方法定义模块
define 有三个参数:name, deps, callback
name 定义模块名,最好不要用;deps 模块依赖;callback 执行的函数
//test.js
define(['underscore', 'jquery', 'backbone'], function(_, $, Backbone) {
return Backbone.View.extend({
tagName: 'div',
attributes: {'class': 'view-test'},
template: _.template( $('#t-view-test').html() ),
initialize: function() { this.render() },
render: function() {
this.$el.html( this.template(this.model.toJSON()) );
return this;
}
})
})
Require.js 执行模块
调用 require 方法执行函数,参数:deps, callback, errback
deps 模块依赖;callback 执行的函数;errback 依赖模块加载失败的回调函数
//main.js
require(['app', 'backbone'], function(AppRouter) {
var app = new AppRouter();
Backbone.history.start();
})
Require.js 配置
baseUrl 设置公共目录
paths 如果路径或文件名很长,就可以在这里定义一个名字代替路径或文件名
shim 加载没有使用 define 定义的模块时,需要在这里说明。定义在 exports 中的名称会成为全局变量名。
//main.js
require.config({
baseUrl: 'js',
paths: {
'jquery': 'lib/jquery.min',
'underscore': 'lib/underscore.min',
'backbone': 'lib/backbone.min'
},
shim: {
'jquery': { exports: ['jQuery', '$'] },
'underscore': { exports: '_' },
'backbone': {
deps: ['underscore', 'jquery'],
exports: 'Backbone'
}
}
})
页面中使用 Require.js
如果页面中使用的所有脚本都是模块化编写的,那页面中只需要一个 script 标签加载 require.js
其他模块 require.js 会按照依赖关系都加载过来
data-main 属性说明需要执行的主模块
baseUrl 的默认值就是主模块的路径
<script type="text/javascript" src="js/require.min.js" data-main="js/main"></script>
Require.js 插件
Require.js 只能加载 Javascript 模块,加载其他类型的文件则需要使用相应的插件。
依赖模块模块名中,感叹号前面的是插件名,感叹号后面的文件就是使用插件加载。
将插件脚本文件和 require.js 放在一起,使用的时候就不用指定路径名。
define(['text!note.txt', 'image!icon.jpg'], function(note, icon) {
console.log(note),
document.body.appendChild(icon)
})
r.js 压缩模块
Require.js 提供一个脚本 r.js ,可以将所有使用到的模块压缩成一个脚本文件,r.js 可以使用 node.js 来执行。
在压缩模块前,需要写一个配置文件,说明主模块名,压缩后的文件名,哪些模块不要压缩
没有使用 define 定义的模块都不要压缩,包括 jquery,backbone 等库及其插件
//build.js
({
baseUrl: '.',
paths: {
'jquery': 'empty:',
'underscore': 'empty:',
'backbone': 'empty:',
},
name: 'main',
out: 'main.min.js'
})
压缩命令:
node r.js -o build.js