模块化
模块化概念
- 模块化是指解决一个复杂问题时,自顶向下逐层把系统划分为若干模块的过程,模块是可组合、分解和更换的单元。
- 模块化可提高代码的复用性和可维护性,实现按需加载。
- 模块化规范是对代码进行模块化拆分和组合时需要遵守的规则,如使用何种语法格式引用模块和向外暴露成员。
Node.js 中模块的分类
- 内置模块
- 自定义模块
- 第三方模块
Node.js 中的模块作用域
- 和函数作用域类似,在自定义模块中定义的变量、方法等成员,只能在当前模块内被访问,这种模块级别的访问限制,叫做模块作用域
- 防止全局变量污染
模块作用域的成员
- 自定义模块中都有一个
module
对象,存储了和当前模块有关的信息 - 在自定义模块中,可以使用
module.exports
对象,将模块内的成员共享出去,供外界使用。导入自定义模块时,得到的就是module.exports
指向的对象。 - 默认情况下,
exports
和module.exports
指向同一个对象。最终共享的结果,以module.exports
指向的对象为准。
CommonJS 模块化规范
- 每个模块内部,
module
变量代表当前模块 module
变量是一个对象,module.exports
是对外的接口- 加载某个模块即加载该模块的
module.exports
属性
模块加载机制
模块第一次加载后会被缓存,即多次调用 require()
不会导致模块的代码被执行多次,提高模块加载效率。
内置模块加载
内置模块加载优先级最高。
自定义模块加载
加载自定义模块时,路径要以 ./
或 ../
开头,否则会作为内置模块或第三方模块加载。
导入自定义模块时,若省略文件扩展名,则 Node.js 会按顺序尝试加载文件:
- 按确切的文件名加载
- 补全
.js
扩展名加载 - 补全
.json
扩展名加载 - 补全
.node
扩展名加载 - 报错
第三方模块加载
若导入第三方模块, Node.js 会从当前模块的父目录开始,尝试从
/node_modules
文件夹中加载第三方模块。如果没有找到对应的第三方模块,则移动到再上一层父目录中,进行加载,直到文件系统的根目录。 例如,假设在
C:\Users\bruce\project\foo.js
文件里调用了require('tools')
,则 Node.js 会按以下顺序查找:C:\Users\bruce\project\node_modules\tools
C:\Users\bruce\node_modules\tools
C:\Users\node_modules\tools
C:\node_modules\tools
目录作为模块加载
当把目录作为模块标识符进行加载的时候,有三种加载方式:
- 在被加载的目录下查找
package.json
的文件,并寻找main
属性,作为require()
加载的入口 - 如果没有
package.json
文件,或者main
入口不存在或无法解析,则 Node.js 将会试图加载目录下的index.js
文件。 - 若失败则报错