模块

在 Node 中引入模块, 需要经历如下 3 个步骤。

  1. 路径分析
  2. 文件定位
  3. 编译执行

在 Node 中, 模块分为两类:

一类是 Node 提供的模块, 称为 核心模块; 另一类是用户编写的模块, 称为 文件模块

出自 朴灵. 深入浅出Node.js (图灵原创) (Kindle 位置 517-520). 人民邮电出版社. Kindle 版本.

模块查找

在使用 require 引入模块的时候,需要注意路径的写法。

在node路径解析中,包含以下几种:

  • 系统模块

系统模块使用 require('moduleName')

  • 自定义模块

系统模块使用 require('./moduleName')

注意自定义模块是针对于项目目录而言,加上 ./ 表示当前文件同级目录。

引入模块的时候,后缀 .js 可省略。

  • 模块查找
  1. 如果有 ./
  • 则从当前目录查找
  1. 如果没有 ./
  • 则先查找系统模块
  • 再遍历当前项目下 node_modules

CommonJS规范

CommonJS这个规范下,每个.js文件都是一个模块,它们内部各自使用的变量名和函数名都互不冲突,例如,hello.jsmain.js都申明了全局变量var s = 'xxx',但互不影响。

一个模块想要对外暴露变量(函数也是变量),可以用module.exports = variable;,一个模块要引用其他模块暴露的变量,用var ref = require('module_name');就拿到了引用模块的变量。

要在模块中对外输出变量,用:

module.exports = variable;

输出的变量可以是任意对象、函数、数组等等。

要引入其他模块输出的对象,用:

var foo = require('other_module');

引入的对象具体是什么,取决于引入模块输出的对象。

module.exports 和 exports

在Node环境中,有两种方法可以在一个模块中输出变量:

方法一:对module.exports赋值:

// hello.js
function hello() {
    console.log('Hello, world!');
}
function greet(name) {
    console.log('Hello, ' + name + '!');
}
module.exports = {
    hello: hello,
    greet: greet
};

方法二:直接使用exports:

// hello.js
function hello() {
    console.log('Hello, world!');
}
function greet(name) {
    console.log('Hello, ' + name + '!');
}
function hello() {
    console.log('Hello, world!');
}
exports.hello = hello;
exports.greet = greet;

默认情况下,Node准备的exports变量和module.exports变量实际上是同一个变量,并且初始化为空对象{},于是,我们可以写:

exports.foo = function () { return 'foo'; };
exports.bar = function () { return 'bar'; };

也可以写:

module.exports.foo = function () { return 'foo'; };
module.exports.bar = function () { return 'bar'; };

换句话说,Node默认给你准备了一个空对象{},就可以直接往里面加东西。

但是,如果我们要输出的是一个函数或数组,那么,只能给module.exports赋值:

module.exports = function () { return 'foo'; };

exports赋值是无效的,因为赋值后,module.exports仍然是空对象{}

MIT Licensed | Copyright © 2018-present 滇ICP备16006294号

Design by Quanzaiyu | Power by VuePress