• 核心工作原理
    • 模块解析过程(Module Resolve)
    • 模块对象(Module Object)
    • 模块包装(Module Wrapper)
    • 缓存(Cache)
    • 循环引用(Cycle)

核心工作原理

模块解析过程(Module Resolve)

test.js

  1. x是node核心模块(如http,zlib等)则返回,否则继续
  2. 根据Module对象的paths属性一直递归找node_modules文件夹下是否存在该模块,直到根目录,否则抛出Error(‘MODULE_NOT_FOUND’)
  3. x是路径(如/path/to/file)
    • 尝试LOAD_AS_FILE(如.js,.json,.node),没有则继续
    • 尝试LOAD_AS_DIR(如文件夹下package.json),没有则抛出Error(‘MODULE_NOT_FOUND’)

LOAD_AS_FILE:

  1. .js
  2. .json
  3. .node文件(编译好的二进制node插件)

LOAD_AS_DIR:

  1. X/package.json中的main字段作为模块入口文件
  2. index.js
  3. index.json
  4. index.node

模块对象

  • id 模块id。通常为模块文件绝对路径,主模块通常为.
  • exports 模块导出对象。这里的exports指的是module.exports
  • parent 父模块。即被依赖模块
  • filename 模块文件名。通常与id相同
  • loaded 模块加载状态。是否已执行完成
  • children 子模块。即依赖模块
  • paths 模块查找路径数组。

模块包装(Module Wrapper)

主要由以下两点考虑

  • 使模块内定义的顶层变量限制在方法(也就是wrapper或者说模块内部)级作用域中,防止污染global环境

注:建议启用’use strict’模式,防止定义全局变量

  • 传入module, require有利于实现node模块化机制

缓存(Cache)

在一个node上下文环境中,两次require同一个文件,通常情况下返回完全相同的两个对象引用。除非用高阶函数返回工厂函数。

循环引用(Cycle)

由于node包相互依赖,则较大可能会形成循环引用,node利用其缓存机制避免无限循环。比如

index.js

a.js

b.js

如上。当b.js引用a.js时,为避免无限循环,a.js未完成的副本(我认为是require(‘./b.js’)之前的所有代码,但是在官方文档中未得到特别确切的表述)导出的对象被b.js引用


发表评论

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据