通行的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