node知识点总结(六)

242 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第23天,点击查看活动详情

前言

大家好呀,我是L同学。在上篇文章node知识点总结(五)中,我们学习了node相关知识点,包括全局模块、nodemon模块、本地安装和全局安装区别、更改镜像源、模块化等相关知识点。今天,在这篇文章中,我们来学习node的其他知识点,包括nodejs中的模块分类、模块作用域、导入导出模块、CommonJS规范等相关知识点。

模块分类

Node.js 中根据模块来源的不同,将模块分为了 3 大类,分别是:

  • 内置模块(内置模块是由 Node.js 官方提供的,例如 fs、path、http等)。
  • 自定义模块(用户创建的每个 .js 文件,都是自定义模块)。
  • 第三方模块(由第三方开发出来的模块,并非官方提供的内置模块,也不是用户创建的自定义模块,使用前需要先下载)。

无论是什么模块,我们都要使用 require() 去加载,然后才能使用。加载自定义的模块,需要加 ./ ,而且可以省略后缀 .js

// 加载核心模块
const fs = require('fs');

// 加载第三方模块
const express = require('express');

// 加载自定义模块
const custom = require('./custom');

模块作用域

在Node.js中,用户创建的每个 .js 文件都是自定义模块。在自定义模块中定义的变量、方法等成员,只能在当前模块内被访问,这种模块级别的访问限制,叫做模块作用域。模块作用域的好处是避免了全局变量污染。由于模块具有一个模块级别的作用域,则另一个JS文件就无法使用当前模块定义的内容。

导入导出模块

为了能正常使用加载的模块中的成员,CommonJS给出了标准,即

  • 一个模块需要使用 module.exports 导出需要共享的内容。
  • 使用模块的JS文件需要使用 require() 导入模块。 模块导出的是什么,另一个使用模块的JS文件得到的就是什么。

require()具有缓存效果。使用 require() 加载模块后,会缓存起来,下次再调用 require()加载相同模块的时候,直接使用缓存,而不是从新加载,从而大大提高了性能。

CommonJS规范

CommonJS规范的出现是为了实现模块化。模块化规范的种类有AMD、CMD、CommonJS(Node.js遵循CommonJS)、ES6。

Node.js遵循了CommonJS模块化规范,CommonJS规定了模块的特性和各模块之间如何相互依赖。

CommonJS 规定:

  1. 每个模块内部,module 变量代表当前模块。
  2. module 变量是一个对象,它的 exports 属性(即 module.exports)是对外的接口。
  3. 加载某个模块,其实是加载该模块的 module.exports 属性。require() 方法用于加载模块。

require()加载模块的机制

加载自定义模块和其他模块的机制有相同之处,也有不同之处,所以这里分开来看。

加载自定义模块

  1. 首次加载成功,会缓存模块。
  2. 下次从缓存中加载,速度更快。
  3. 加载自定义模块必须加 ./ ,如果是其他路径,对应变化,否则会把它当做核心模块或者第三方模块。
  4. 加载自定义模块的时候,如果是 require('./abc')。 (1)优先加载相同名字的文件,加载一个叫做 abc 的文件。

(2)自动补 .js 后缀,然后加载 abc.js 文件。

(3)自动补 .json 后缀,然后加载 abc.json 文件。

(4)自动补 .node 后缀,然后加载 abc.node 文件。

(5)以上文件都没有,则报错 Cannot find module './abc'

加载核心模块和第三方模块

  1. 首次加载成功,会缓存模块。

  2. 下次从缓存中加载,速度更快。

  3. 加载模块一定不能./ ,否则会把它当做自定义模块。

  4. 加载模块的时候,如果是 require('haha')。 (1)优先加载核心模块。

(2)去查找并加载第三方模块,查找第三方模块的路径可以通过 module.paths 查看。

(3)加载第三方模块会从当前目录开始寻找node_modules文件夹,如果找到进入node_modules文件夹寻找对应的模块。如果没找到,进入上一级目录继续寻找node_modules,一直到根目录。如果一直没有找到,提示未找到模块。