CommonJS规范
项目最初是由Mozilla 的工程师 Kevin Dangoor 在2009年1月创建的,当时名为ServerJS。2009年8月,这个项目改名为 CommonJS,以显示其API更广泛实用性。
项目是以浏览器环境之外构建 JavaScript 生态系统为目标而产生的,它希望JavaScript可以运行在任何地方而不仅仅是浏览器。比如在服务器和桌面环境中。
所以CommonJS API定义了很多(非浏览器)使用的API,力求提供一个类似Python,Ruby和Java标准库。
CommonJS模块使用
CommonJS规范是为了解决 JavaScript 的作用域问题而定义的模块形式,可以使每个模块它自身的命名空间中执行。
CommonJS模块规范主要分为引用、定义、标识模块三部分
module.exports = function( value ){
return value * 2;
}
/**
* 模块引用
*
* 使用require()方法来引入一个模块;
* 这里引入 模块:moduleA,并复制给变量multiplyBy2;
*
*/
var multiplyBy2 = require('./moduleA');
var result = multiplyBy2(4);
/**
* 模块标识
*
* 指传给require()的参数 可以是小驼峰命名的模块名或是路径
*
* require("模块名"):当前目录下的node_modules目录中的模块
* require("路径"):指定目录的指定模块
*
*/
/**
* 模块定义
*
* module对象:module对象指的模块自身
* export属性:module对象的属性,为外部提供接口
*
*/
module.exports = function( value ){
return value * 2;
}
Node.js最初的模块模式就是CommonJS(后面开始使用ECMAScript模块)。
CommonJS模块特点
-
CommonJS是同步加载模块,模块加载的顺序,按照其在代码中出现的顺序。
-
所有代码都运行在模块作用域,不会污染全局作用域。
-
模块可以多次加载,但是只会在第一次加载时运行一次,然后运行结果就被缓存了,以后再加载,就直接读取缓存结果。要想让模块再次运行,必须清除缓存。
浏览器对commonJS支持
我们在npm上下载的模块都是JavaScript编写的,但是由于浏览器不支持CommonJS格式所以用不了。
我们可以将模块转换成符合CommonJS规范的格式。
浏览器不兼容CommonJS的根本原因,在于缺少四个Node.js环境的变量。
module、exports、require、global
在Jquery中我们可以看到它对CommonJS的支持的实现:
Jquery:
( function( global, factory ) {
"use strict";
// 判断环境中是否有`module`和`exports`变量
if ( typeof module === "object" && typeof module.exports === "object" ) {
/**
* 如果window.document存在,`module.exports = jQuery;`
*
*/
module.exports = global.document ?
factory( global, true ) :
function( w ) {
if ( !w.document ) {
throw new Error( "jQuery requires a window with a document" );
}
return factory( w );
};
} else {
factory( global );
}
} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
//省略
}
可以看出这是一个立即执行函数
-
(function( global, factory ){...})(window,function(window, noGlobal){...})
-
如果环境中存在module和exports变量即
module.exports = jQuery;
加载jQUery;否则正常加载jQuery
AMD规范
AMD(异步模块定义)是为浏览器环境设计的,因为 CommonJS 模块系统是同步加载的,当前浏览器环境还没有准备好同步加载模块的条件。
AMD 定义了一套 JavaScript 模块依赖异步加载标准,来解决同步加载的问题。
AMD使用
AMD模块定义: 通过define函数定义在 闭包中
语法:
define(id?: String, dependencies?: String[], factory: Function|Object);
-
id:模块名(可选)
-
dependencies:指定需要加载的依赖列表(如果没有默认值为
["require", "exports", "module"]
) -
factory:模块的具体实现,它是一个函数或是对象。
AMD模块使用: 通过require函数来导入模块
require(['myModule'], function(myModule) {});
JavaScript库对AMD支持
在Jquery中我们可以看到它对AMD的支持的实现:
if ( typeof define === "function" && define.amd ) {
define( "jquery", [], function() {
return jQuery;
} );
}