Node中模块查找机制

在Node.js中,目前支持es6模块和commonjs模块,在这个万物皆可为模块的世界里,模块的查找机制是一个相对复杂但有序的过程。这通常被称为“模块解析”或“模块查找”。

模块分类

nodejs中的模块主要分为两大类,一类是nodejs提供的模块,称为核心模块,另一类是用户编写的模块,称为文件模块。

文件模块

文件模块根据引用的方式不同,又分为自定义模块和以路径形式引入的模块,自定义模块通常是以包的形式存在,例如我们从npm上下载下来的包,就是自定义模块。以路径形式引入的模块,通常是用户自己编写封装的模块,引入时,用户需要制定模块的真实路径,二者的区别是引入方式不同

模块查找机制的主要步骤和规则

  • 路径解析
    • 当使用require()函数加载模块时,Node.js首先会解析模块标识符(即传递给require()的参数)。
    • 如果模块标识符以./(相对路径)或/(绝对路径)开头,Node.js将直接在该路径下查找模块。
    • 如果模块标识符没有路径信息(即没有以.//node_modules/开头),Node.js将按照一系列规则在node_modules目录中查找。
  • 自定义模块查找
    • 对于自定义模块(即非内置模块),如果模块标识符包含路径信息(如./module/path/to/module),Node.js将直接在该路径下查找。
    • 如果省略了文件扩展名(如require('./module')),Node.js将按照以下顺序尝试加载文件:
      • 尝试加载与模块标识符同名的文件,依次尝试.js.json.node扩展名。
      • 如果找到的是文件夹,Node.js将尝试加载该文件夹下的index.jsindex.jsonindex.node文件。
  • node_modules目录查找
    • 如果模块标识符没有路径信息,Node.js将在当前文件的node_modules目录中查找。
    • 如果在当前目录的node_modules中未找到,Node.js将向上级目录的node_modules中查找,以此类推,直到根目录。
    • (老版本)在每个node_modules目录中,Node.js将首先查找与模块标识符同名的文件夹,然后查找该文件夹下的package.json文件中的main属性指定的文件。如果未找到package.json文件或者它的main属性没指定文件,Node.js将尝试加载该文件夹下的index.js文件。
    • (新版本)默认 先查找同名文件。如果没找到,则尝试查找 .js和.json文件 。如果还是没有,会查找 同名文件夹(当成了一个包),找到后,会先找 package.json文件。如果没有,则会继续查找 index.js文件。如果依旧不存在,则会报错。
  • 内置模块查找
    • 如果Node.js在node_modules目录中未找到对应的模块,它将检查该模块是否为Node.js的内置模块(如fshttp等)。
    • 内置模块是Node.js官方提供的,直接由Node.js的源代码实现,因此不需要通过node_modules目录查找。
  • 缓存机制
    • Node.js在第一次加载模块后,会将模块缓存起来。这意味着如果再次加载同一个模块,Node.js将直接从缓存中加载,而不是重新查找和加载文件。
    • 缓存机制提高了模块的加载速度,并确保了模块的一致性。

总结一下文件模块的 查找规范

// 新版node查找流程
│
└───┤ 同名文件
 │	
 │──┤ 同名.js / 同名.json
 │
 │──┤ 同名文件夹
    │
    │───┤ pageage.json
    │
    └───┤ index.js
   

注意

安装的模块里又引用了其他的模块,这个模块会按照规则先在自己的node_modules里查找它自己引用的模块,找不到再向上查找所以你即使在最外层的模块里加载了最新的这个包,那么它也不会生效。

当多个同级模块都引入了同一个模块,但它们的版本不一样。模块之间是互相独立的,他们都会在它自身的node_module里先找,如果都找到了,那他们所用的模块确实是不同版本的。如果没找到就会向上查找。

安装模块后为什么可以直接执行命令

例如安装ESLint后,能够直接执行`eslint --fix`命令的原因可以归纳为以下几点:

全局安装
   当使用`npm install eslint -g`命令全局安装ESLint时,npm会将ESLint包及其所有依赖下载并放置在全局的`node_modules`目录中。这个位置根据操作系统和npm的配置有所不同。

bin属性的处理
   npm在全局安装过程中会查看ESLint包的`package.json`文件。如果该文件包含`bin`属性,npm会根据`bin`属性指定的文件路径,在全局的`bin`目录中创建指向这些文件的链接(或在Windows上是可执行的包装器)。这些链接或包装器允许用户直接在命令行中运行ESLint。

PATH环境变量
   PATH环境变量是操作系统用来定位可执行程序的关键变量。当在命令行终端输入一个命令(如`eslint`)时,系统会检查PATH环境变量中列出的目录,以查找名为`eslint`的可执行文件。由于全局安装ESLint时,其可执行文件的路径已被添加到PATH中,因此用户可以在任何位置直接运行`eslint`命令。

npm scripts 使用指南 - 阮一峰的网络日志 (ruanyifeng.com)

前端概念关系图

参考文章

node.js - nodeJS模块查找策略 - 个人文章 - SegmentFault 思否

从package-lock看npm版本锁定相关知识_版本锁定标识-优快云博客

npm link与bin的一些使用 - 掘金 (juejin.cn)

npm scripts 使用指南 - 阮一峰的网络日志 (ruanyifeng.com)

npx 使用教程 - 阮一峰的网络日志 (ruanyifeng.com) 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值