CommonJS规范
-
CommonJS规范的提出是为了弥补当前JavaScript没有标准的缺陷(ES5)
-
CommonJS规范为JS指定一个美好愿景,希望JS能够在任何地方运行
-
CommonJS对模块化的定义十分简单:
- 模块引用
- 模块定义
- 模块标识
模块定义
- 在Node中,一个js文件就是一个模块。(创建一个js文件)
模块引用
- 在node中,通过require()函数来引入外部的模块,require()可以传递一个文件路径作为参数;node将会自动根据该路径引入外部模块。如果使用相对路径必须用 . 或 … 开头。
- 我们使用require() 引入模块后该函数会返回一个对象,这个对象就是引入的模块(见module02.js)
module01.js
console.log("我是module01");
var x = 10;
module02.js
var md = require("./module01");
console.log(md.x);
在输出结果可见,module02 引入并执行了 module01代码,可是并没有获取到module01的内容。
- 在Node中,每一个js文件的js代码都是独立运行在一个函数中。所以一个模块中的变量和函数在其他模块中无法访问。
向外部暴露属性或方法 exports
-
我们可以通过 exports 来向外部暴露变量和方法,只需要将要向外暴露的变量或方法设置为exports的属性即可。
module01.js
console.log("我是module01"); var x = 10; exports.x = "我是module01.js中的x";
同样运行 module02 就会得到module01中向外暴露的内容。
模块标识
我们使用 require() 引入外部模块时,使用的就是模块标识,通过模块标识来找到指定的模块。
模块分成两大类
-
核心模块
-
由 node 引擎提供的模块
-
核心模块的标识就是模块的名字
var fs = require("fs");
-
通过 npm 下载的也可以直接写名字
-
-
文件模块
- 由用户自己创建的模块
-
在Node中有一个全局对象 global ,它的作用和网页中的window类似
在全局中创建的变量都会作为global的属性保存
a = 10; //不用var
在全局中创建的函数都会作为global的方法保存
arguments.callee
这个属性保存的是当前执行的函数对象。
console.log(arguments.callee + "");
当node在执行模块中的代码时,会在代码的最顶部添加如下代码:
function (exports, require, module, __filename, __dirname) {
底部添加:
}
实际上模块中的代码都是包装在一个函数中执行的,并且在函数执行时,同时传递进了5个实参。
-
exports
该对象用来将变量或函数暴露在外部
-
require
函数,用来引入外部的模块
-
module
module 代表的是当前模块本身
exports 就是 module 的属性(module.exports == exports)
既可以使用 exports 导出,也可以使用 module.exports导出。
-
__filename
当前模块的完整路径
g:\learn\module03.js
-
__dirname
当前模块所在文件夹的完整路径
g:\learn
exports 和 module.exports
helloModule.js
exports.name = "孙悟空";
exports.age = 18;
exports.sayName = function() {
console.log("name");
}
用module.exports
module.exports = {
name : "猪八戒",
age : 28,
sayName : function() {
console.log("name2");
}
};
exports 传对象
exports = {
name : "猪八戒",
age : 28,
sayName : function() {
console.log("name2");
}
};
原理比如:
var obj = {};
obj.a = {};
var a = obj.a;
//a 和 obj.a指向同一个对象
a.name = "孙悟空";
a = new Object();
console.log(obj.a.name); //"孙悟空"
console.log(a.name)//"undefined"
所以
exports = {
name : “猪八戒”,
age : 28,
sayName : function() {
console.log(“name2”);
}
};
原本指向 module.exports 的 exports 断开了连接。
-
通过exports 只能使用 . 的方式来向外暴露内部变量
exports.xxx = xxx;
-
而module.exports 既可以通过 . 的形式,也可以直接赋值。
module.exports.xxx = xxx;
module.exports= {
xxx: xxx;
}
CommonJS的包
包(package)
- CommonJS的包规范允许我们将一组相关的模块组合到一起,形成一组完整的工具。
- CommonJS的包规范由 包结构 和 包描述文件 两部分组成。
包结构
用于组织包中的文件
- 包实际上就是一个压缩文件,解压以后还原为目录。符合规范的目录,应该包含如下软件:
- package.json 描述文件 (必须)
- bin 可执行二进制文件
- lib js代码
- doc 文档
- test 单元测试
包描述文件
描述包的相关信息,以供外部读取分析
-
包描述文件用于表达非代码相关的信息,它是一个JSON格式的文件——package.json,位于包的根目录下,是包的重要组成部分。
-
package.json 中的字段
name、description、 version、 keywords、 maintainers、 contributors、 bugs、 licenses、 repositories、 dependencies、 homepage、 os、 cpu、 engine、 builtin、 directories、 implements、 scripts、 author、 bin、 main、 devDependencies。