前言
JavaScript 是一个强大面向对象语言,它有很多快速高效的解释器。然而, JavaScript
标准定义的 API 是为了构建基于浏览器的应用程序。并没有制定一个用于更广泛的应用程序
的标准库。
CommonJS 规范的提出,主要是为了弥补当前 JavaScript 没有标准的缺陷。它的终
极目标就是:提供一个类似 Python,Ruby 和 Java 语言的标准库.
CommonJS 就是模块化的标准,nodejs 就是 CommonJS( ( 模块化 ) 的实现。
CommonJS模块化会应用于nodejs、vue、react等等框架语言。
概念
模块是Node.js 应用程序的基本组成部分,文件和模块是一一对应的。换言之,一个 Node.js 文件就是一个模块,这个文件可能是JavaScript 代码、JSON 或者编译过的C/C++ 扩展。
Nodejs 自定义 模块的规定:
1.我们可以把公共的功能 抽离成为一个单独的 js 文件 作为一个模块,默认情况下面这
个模块里面的方法或者属性,外面是没法访问的。如果要让外部可以访问模块里面的方法或
者属性,就必须在模块里面通过 exports 或者 module.exports 暴露属性或者方法。
(如果要对外暴露属性或方法,就用 exports 就行,要暴露对象(类似class,包含了很多属性和方法),就用 module.exports)
2. 在需要使用这些模块的文件中,通过 require 的方式引入这个模块。这个时候就可以
使用模块里面暴露的属性和方法。
模块
Node.js 中存在 4 类模块(原生模块和3种文件模块)。原生模块优先级更高。
从原生模块加载
原生模块的优先级仅次于文件模块缓存的优先级。require 方法在解析文件名之后,优先检查模块是否在原生模块列表中。以http模块为例,尽管在目录下存在一个 http/http.js/http.node/http.json 文件,require(“http”) 都不会从这些文件中加载,而是从原生模块中加载。
原生模块也有一个缓存区,同样也是优先从缓存区加载。如果缓存区没有被加载过,则调用原生模块的加载方式进行加载和执行。
从文件加载
当文件模块缓存中不存在,而且不是原生模块的时候,Node.js 会解析 require 方法传入的参数,并从文件系统中加载实际的文件,加载过程中的包装和编译细节在前一节中已经介绍过,这里我们将详细描述查找文件模块的过程,其中,也有一些细节值得知晓。
require方法接受以下几种参数的传递:
- http、fs、path等,原生模块。
- ./mod或…/mod,相对路径的文件模块。
- /pathtomodule/mod,绝对路径的文件模块。
- mod,非原生模块的文件模块。
应用
如果要对外暴露属性或方法,就用 exports 就行,要暴露对象(类似class,包含了很多属性和方法),就用 module.exports。
用hello.js ,main.js 两个文件,main.js 调用hello的模块,展示两种输出模块的方法:
//hello.js
exports.say = function() {
console.log("hello,world");
}
exports.againSay = function (){
console.log("again hello!");
}
// main.js
var h = require('./hello');
h.say();
h.againSay();
运行结果:
用module.exports 的方法:
//hello.js
function hello(){
var name;
this.set = function(s){
name =s;
}
this.get = function(){
console.log("name:",name)
return name;
}
}
module.exports = hello;
// main.js
var Hello = require('./hello');
hello = new Hello();
hello.set('hello,world!!!');
hello.get();
运行结果: