Skip to content

CommonJS 模块规范

  • 模块引用

    js
    const math = require('math')
  • 模块定义

    模块中通过上下文提供的 require() 方法引入外部模块,上下文还提供了 module 对象,代表 模块本身,还提供了 exports 对象,它是 module 的属性,是导出当前模块的方法或变量的 唯一出口。在 Node 中,一个文件就是一个模块。

    js
    exports.add = () => {}
    js
    const add = () => {}
    
    module.exports = add
  • 模块表示

    传递给 require() 方法的参数,必须是符合小驼峰命名法的字符串或以 .、.. 开头的相对 路径或一个绝对路径,可以省略文件名后缀。

CommonJS 构建的这套模块系统的引入和导出机制使用用户完全不需要考虑变量污染问题。

Node 模块化

Node 借鉴 CommonJS 的 Modules 规范实现了一套模块系统,按需引入,但无法实现 tree-shaking。Node 中每一个文件都是一个模块,module.exports 导出,require 导入。

Node 模块分为三类:

  • 内置模块和核心模块

    不需要安装,引入时不需要添加路径。在源码的编译过程中被编译进了二进制执行文件,Node 进程启动时,部分核心模块直接加载进内存中,这部分核心模块引入时,省略文件定位和编译 执行,并且在路径分析中优先判断,加载速度是最快的。

  • 自定义模块(文件模块)

    不需要安装,引入时需要添加路径。运行时动态加载,需要完整的路径分析、文件定位、编译 执行过程,速度比核心模块慢。

  • 第三方模块

    需要安装,引入时不需要添加路径。

目的

解决命名冲突,实现低耦合高内聚。

Node 中引入模块经历三个步骤

  • 路径分析

  • 文件定位

  • 编译执行

Node 对引入过的模块都会进行缓存,浏览器对于静态脚本只是缓存文件,Node 缓存的是编译 和执行之后的对象,相同模块的第二次加载一律缓存优先,但核心模块的缓存检查优于文件模块 的缓存检查