javascript模块规范:CommonJS,AMD,CMD
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了javascript模块规范:CommonJS,AMD,CMD相关的知识,希望对你有一定的参考价值。
CommonJS/Nodejs实现
- Node.js上下文提供的变量
- require:函数,用于引用依赖模块,依赖模块被引用为对象,即可食用提供的方法和变量,require()接受一个模块标识参数。
- module:对象,代表当前模块本身
- exports:对象,module的属性,作为模块的唯一出口,用来导出当前模块提供的方法和变量,将方法或变量挂载为exports对象的属性即可导出,也可以直接将方法或变量赋给module.exports导出
“`javascript
//挂载方式导出方法和变量
exports.fun1=function(){
…
}
var a = “”;
exports.a=a;
//直接赋值导出,不能直接给exports赋值!!!
function fun2(){
}
module.exports=fun2;
- _filename:当前模块的文件名
- _dirname:当前模块所在目录名
-模块标识格式
1符合小驼峰命名的字符串||以.、..开头的相对路径||绝对路径
2可以没有文件名后缀
-模块类型
-.js
-.node
-.json
-包结构
-package.json;json格式文件,包描述文件
- bin:目录,存放可执行二进制文件
- lib:目录,存放Javascript代码
- doc:目录,存放文档
- test:目录:存放测试用例
### AMD/require.js实现
[AMD文档](https://github.com/amdjs/amdjs-api/wiki/AMD "AMD文档")
-模块定义,使用require.js提供的全局函数define定义模块,define()接受三个参数
```javascript
define(id?,dependences?,factory);
- id,可选,
- dependences,可选,字符串数组(可以只有一个元素),当前模块依赖的所有模块
- factory,必须,函数,提供了独立的作用域,用于定义模块提供的方法和变量,当前模块存在依赖模块时,依赖模块作为factory的参数传入
define(function(){
var exports ={};//需要定义模块入口变量
exports.fun1=function(){
...
}
return exports;//需要将模块入口作为返回值
});
define([‘myLib‘],function(myLib){
function foo(){
myLib.doSomething();
}
return{
foo : foo
};
});
- 模块加载,在非模块代码中加载模块,使用require.js提供的全局函数require将模块加载为回调函数的参数,require接受两个参数
- modules,字符串数组,要加载的模块标识,必要时需对模块标识设置加载路径
“`javascript
//设置加载路径,相对于当前模块所在目录
require.config({
paths: {
“jquery”: “lib/jquery.min”,
“underscore”: “lib/underscore.min”,
“backbone”: “lib/backbone.min”
}
});
//设置模块加载根目录
require.config({
baseUrl: “js/lib”,
paths: {
“jquery”: “jquery.min”,
“underscore”: “underscore.min”,
“backbone”: “backbone.min”
}
});
- modules,字符串数组,要加载的模块标识,必要时需对模块标识设置加载路径
- callback,回调函数,加载模块后执行,参数即为加载的模块对象
### CMD/seajs实现
[CMD文档](https://github.com/cmdjs/specification/blob/master/draft/module.md "CMD文档")
-模块定义,使用sea.js提供的全局函数define定义模块,define()接受一个参数factory,factory有三种情况
-函数:模块构造函数,默认有三个参数,require,exports,module,以形参的形式将上下文提供的变量引入当前模块的作用域供调用,还可以自己定义其他参数
```javascript
//变量和方法的挂载同commonJS,不能直接为exports赋值,因为exports是momule.exports的引用,改变exports的值不改变对象内容
define(function(require, exports, module) {
...
});
- 对象:
“`javascript
define({foo:”bar”});
-字符串:可以用来定义字符串模板
```javascript
define(‘I am a template. My name is {{name}}.‘);
- 模块加载
- require(),同步加载,接受模块标识作为唯一参数,将模块加载为对象
- require.async(),异步加载,接受模块标识和回调函数,模块加载成功后执行回调函数
前后端模块
javascript没有编译的过程,模块加载都是在代码执行过程中进行的,javascript模块都是独立的文件,,模块加载意味着需要读取文件
后端模块(nodejs)的加载默认采用同步加载,由于加载的文件都是在本地,而且nodejs提供了模块缓存机制,因此同步加载对性能影响不大
前端模块的加载需要进行网络请求,速度远不如加载本地文件,而且如果采用同步加载,且模块加载在UI初始化之前进行,则会对用户体验造成较大影响
从 CommonJS 到 Sea.js
以上是关于javascript模块规范:CommonJS,AMD,CMD的主要内容,如果未能解决你的问题,请参考以下文章