JS模块化开发规范
JS模块化开发规范,以下介绍三种
commonJS规范(Nodejs模块系统遵循此规范,适用于服务端)
1、 规范定义
CommonJS规范规定,一个文件就是一个模块,用module变量代表当前模块。 Node在其内部提供一个Module的构建函数。所有模块都是Module的实例
2、 module.exports属性定义模块
module.exports属性表示当前模块对外输出的接口,其他文件加载该模块,实际上就是读取module.exports变量。
//moduleA.js
module.exports.funcA= function(){
console.log('This is moduleA!');
}
3、模块引用
require函数的基本功能是,读入并执行一个JavaScript文件,然后返回该模块的exports对象。在moduleB模块中加载引入moduleA模块,便可以使用funA方法了,示例代码如下:
//moduleB.js
var a = require('./moduleA');
a.funcA();//打印'This is moduleA!'
AMD规范(RequireJs JS模块加载器遵循此规范,适用于浏览器)
1、定义模块:define方法 define(id?, [deps,]?, factory);
l 第一个参数,id(名字),是个字符串。它指的是定义中模块的名字,这个参数是可选的。如果没有提供该参数,模块的名字应该默认为模块加载器请求的指定脚本的名字。如果提供了该参数,模块名必须是“顶级”的和绝对的(不允许相对名字)。
l 第二个参数,dependencies(依赖),是个定义中模块所依赖模块的数组。依赖模块必须根据模块的工厂方法优先级执行,并且执行的结果应该按照依赖数组中的位置顺序以参数的形式传入(定义中模块的)工厂方法中。
l 第三个参数,factory(工厂方法),为模块初始化要执行的函数或对象。如果为函数,它应该只被执行一次。如果是对象,此对象应该为模块的输出值。
2、require方法:加载模块require([module], callback);
第一个参数[module],是一个数组,里面的成员就是要加载的模块;第二个参数callback,则是加载成功之后的回调函数。如果将前面的代码改写成AMD形式,就是下面这样:
require(['a'], function (a) {
a.FuncA();
});
//js/index.js(requirejs的使用)
<script data-main="js/ctr/index" src="js/lib/require.js" type="text/javascript"></script>
require.config({
//baseUrl——用于加载模块的根路径。
//paths——用于映射不存在根路径下面的模块路径。
//shims——配置在脚本/模块外面并没有使用RequireJS的函数依赖并且初始化函数。
//deps——加载依赖关系数组
baseUrl : "js",
paths: {
'jquery': '../lib/jquery'
},
shim: {//加载非AMD规范的模块
"underscore" : {
exports : "_";
},
"jquery.form" : {
deps : ["jquery"],//deps数组,表明该模块的依赖性
exports: 'jqueryForm'
}
}
});
require(['jquery'], function($) {
$(document).on('click', '#clickBtn', function() {
$('#showMsg').html('看看jquery加载进来了没有');
});
});
CMD规范(seaJS 模块加载器)
1、规范定义
CMD是国内大牛玉伯在开发SeaJS的时候提出来的,属于CommonJS的一种规范,根据浏览器的异步环境做了自己的实现。它和 AMD 很相似,尽量保持简单,并与 CommonJS 和 Node.js 的 Modules 规范保持了很大的兼容性。
2、define方法:定义模块 define( id?, [deps,]?, factory ); 前两个参数项可选
define('hello', ['jquery'], function(require, exports, module) {
// 模块代码
});
3、require方法:加载模块
1.require 是同步往下执行,require.async 则是异步回调执行。require.async 一般用来加载可延迟异步加载的模块。
2.除了给 exports 对象增加成员,还可以使用 return 直接向外提供接口
3.module.exports 的赋值需要同步执行,不能放在回调函数里。
4.exports 是 module.exports 的一个引用
define(function(require, exports, module) {
// 错误用法,对 module.exports 的赋值需要同步执行,不能放在回调函数里。
setTimeout(function() {
module.exports = { a: "hello" };
}, 0);
// 异步加载模块,在加载完成时,执行回调
require.async(['./c', './d'], function(c, d) {
c.doSomething();
d.doSomething();
});
//向外暴露接口的方法3种
// 1.给 module.exports 赋值
module.exports = new SomeClass();
// 2.给 exports 对象增加成员
exports.doSomething = function() {};
// 3.通过 return 直接提供接口
return {
foo: 'bar',
doSomething: function() {}
};
});
//js/index.js(seajs的使用)
define(function(require, exports, module) {
// var $ = require("$");
module.exports= {
init: function() {
console.log('index.js is loaded!');
}
};
});
seajs.config({
base: "./js/lib/",// Sea.js 的基础路径
alias: {// 别名配置
'$':'jquery/1.12.3/jquery-1.12.3',
'jquery':'jquery/1.12.3/jquery-1.12.3',
},
paths: {// 路径配置
'basePath': './js/lib/'
},
vars: {// 变量配置
'jquery_version': 'jquery-1.12.3'
},
map: [// 映射配置
[ '.js', '-debug.js' ]
],
preload: ['$'], //预加载项'$'
debug: true,// 调试模式
charset: 'utf-8'// 文件编码
});
seajs.use(['$','./js/ctr/index.js'], function($,index) {
$(document).ready(function(){
index.init();
});
});