Node中模块查找机制

说说 Node 文件查找的优先级以及 Require 方法的文件查找策略? Node.js的模块查找规则和优先级确保了模块可以按照一定的路径顺序被找到并加载。核心模块和已加载的模块会被缓存,避免了重复加载,提高了应用程序的性能。在编写Node.js应用程序时,我们可以根据这些规则来组织和导入模块,实现代码的模块化和复用。 阅读详情

在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.js、index.json或index.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的内置模块(如fs、http等)。
    • 内置模块是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) 

深入解析Node.js模块加载机制:从node_modules路径查找到依赖版本锁定 本文深入解析Node.js模块加载机制,详细阐述了从node_modules路径查找到依赖版本锁定的全过程。通过剖析模块解析算法、扁平化依赖结构带来的版本冲突与“幽灵依赖”问题,并强调package-lock.json等锁文件对保证依赖一致性的关键作用,帮助开发者从根本上理解和解决常见的模块加载与依赖管理难题。 阅读详情

相关推荐

Node.js模块查找原理与源代码示例

Node.js是一个基于Chrome V8引擎的JavaScript运行时环境,它采用模块化的方式组织代码。在Node.js中,模块是独立的功能单元,可以通过require语句加载和使用。那么,当我们使用require加载模块时,Node.js是如何查找和定位这些模块的呢?本文将详细介绍Node.js的模块查找原理,并提供相应的源代码示例。

PixelNinja的博客 284

Node.js 模块寻址规则

Node.js模块查找规则模块查找分三种。

qq_34399969的博客 1374

nupkg 本地安装_使用Nuget安装离线包nupkg

一:Nuget简介:NuGet 是免费、开源的包管理开发工具,专注于在 .NET 应用开发过程中,简单地合并第三方的组件库。当需要分享开发的工具或是库,需要建立一个Nuget package,然后把这个package放到Nuget的站点。如果想要使用别人已经开发好的工具或是库,只需要从站点获得这个package,并且安装到自己的Visual Studio项目或是解决方案里。NuGet能更方便地把一...

weixin_34460380的博客 1万+

Node.js 中的模块查找规则

模块查找规则的两种情况

weixin_47505105的博客 794

MySQL常见面试题汇总(建议收藏!!!)

目录一、索引相关(1)什么是索引?(2)索引是个什么样的数据结构呢?(3)为什么使用索引?(4)Innodb为什么要用自增id作为主键?(5)Hash 索引和 B+ 树索引有什么区别或者说优劣呢?(6)什么是聚簇索引(6)非聚簇索引一定会回表查询吗?(6)聚簇索引和非聚簇索引的区别(6)MyISAM和InnoDB实现B+树索引方式的区别是什么?(6)MySQL中有四种索引类型,可以简单说说吗?(6)覆盖索引是什么?(6)联合索引是什么?为什么需要注意联合索引中的顺序?(6)创建的索引有没有被使用到?或者说怎

蔡政洁的博客 7万+

WPS和Excel通用!省市区四级联动下拉菜单保姆级教程(附最新行政区划数据包)

本文详细介绍了在WPS和Excel中实现省市区四级联动下拉菜单的完整教程,包含2024年最新行政区划数据的获取与整理方法。通过名称管理器和INDIRECT函数的组合,以及WPS的特色功能,帮助用户高效准确地录入四级行政区划信息,提升数据录入效率并减少错误。

s1t2u3的博客 610

前端 JS 经典:node 的模块查找策略

我们引入模块后,node 大概的查找步骤分为。

weixin_64684095的博客 518

电力现货交易市场-报价方式

电是一种能源,也是一种商品,既然是商品自然可以在市场中进行自由交易。

qq_38225433的博客 5117

nodejs模块查找策略

我们都知道,nodejs目前支持es6模块和commonjs模块,在这个万物皆可为模块的世界里,这篇文章来探讨一下当我们引用一个模块时,nodejs是已一种什么样的策略来查找到对应的模块的 模块分类 nodejs中的模块主要分为两大类,一类是nodejs提供的模块,称为核心模块,另一类是用户编写的模块,称为文件模块,他们的关系如下图所示 文件模块 文件模块根据引用的方式不同,又分为自定...

小敏哥的专栏 2378

HP iLO4报错自救指南:Embedded Flash/SD-CARD故障的3种修复方案(附详细截图)

本文详细解析了HP iLO4出现'Embedded Flash/SD-CARD'故障时的3种修复方案,包括快速恢复、固件级修复和硬件级解决方案。通过Diagnostics诊断和Self-Test报告,帮助运维人员高效解决问题,并提供预防性维护建议,确保服务器远程管理功能的稳定性。

weixin_42522953的博客 508

ISO 15118-3协议栈开发避坑指南:从EvseSlac状态机设计看电动汽车充电握手难题

本文深入剖析了ISO 15118-3协议栈开发中的核心挑战,特别是SLAC握手流程的实现难点。以Everest项目的EvseSlac状态机为例,详细解读了从状态机设计、多厂商PLC芯片兼容性处理,到严苛的时序与超时控制等关键工程实践,为开发者提供了一套超越协议文档的、可直接落地的避坑指南和软件实现方案。

jump7的博客 265

node【引入模块查找机制】

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录前言一、模块分类二、查找机制 前言 我们在开发过程中,经常使用require或import去引入模块,而在使用过程中,会发现有很多简写方式,如引入index/index.js我们直接require('/index')即可,为什么会这样,是因为node中有一套自己的查找规则 一、模块分类 node中加载的模块总共可以分为三个类 核心模块fs、http这些内置模块,在编译时已经注入到内存中 本地模块自己本地开发的模块 npm下.

qq_32019935的博客 1046

Vue3 - 详解实现网站接入钉钉扫码登录功能,钉钉授权生成登录二维码用户用手机扫描二维码登陆,支持弹框式、浏览器单独新开页显示,钉钉扫描二维码登录详细流程及示例代码,最新vue集成钉钉扫码授权登录!

vue3,nuxt3,钉钉,扫码登录,vue3钉钉扫码登陆,钉钉授权第三方WEB网站扫码登录功能,钉钉扫码登录第三方网站,单点登录,二维码不显示,报错,扫了没反应,出错,vue3钉钉扫码登录,内嵌,获取个人信息,pc网页钉钉登录,钉钉扫码登录怎么新开一页,跳页显示二维码,内嵌登录二维码,iframe新页面弹出,弹出一个小窗口显示登录二维码,登录报错,扫码没反应,解决手机点登录报错没反应,官方文档,手机扫描钉钉二维码登录网站,页面弹出一个小窗口而不是打开一个页面,vue3中使用iframe实现另开小窗口扫码登

🏆 前端领域优质创作者 3694

Node.js:模块查找,引用及缓存机制

1. Node.js的模块载入方式与机制 Node.js中模块可以通过文件路径或名字获取模块的引用。模块的引用会映射到一个js文件路径,除非它是一个Node内置模块。Node的内置模块公开了一些常用的API给开发者,并且它们在Node进程开始的时候就预加载了。   其它的如通过NPM安装的第三方模块(third-party modules)或本地模块(local modules),每个模块...

Just Code 1492

osgearth添加经纬度网格,并显示鼠标所指经纬高度信息

一、代码 osgearth官方例子 #include <osg/Notify> #include <osgGA/StateSetManipulator> #include <osgViewer/Viewer> #include <osgViewer/ViewerEventHandlers> #include <osgEarth/MapNode> #include <osgEarthUtil/EarthManipulator> #

ljjjjjjjjjjj的博客 3564

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

Node.js 模块查找机制

1. 当模块拥有路径但没有后缀时 require('./find'); require方法根据模块路径查找模块,如果是完整路径,直接引入模块 如果模块后缀省略,先找同名JS文件再找同名JS文件夹,没有同名文件夹则报错 如果找到了同名文件夹,找文件夹中的index.js 如果文件夹中没有index.js,就会去当前文件夹中的package.json文件中查找main选项中的入口文件 如果找指定的入口文件不存在或者没有指定入口文件就会报错,模块没有被找到 2. 当模块没有路径且没有后缀时 require(

火星基地 540

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

Node.js 的模块查找机制

第三方模块的查找机制是 例如,我需要查找 art-template模块,这个模块已经被我安装到了项目中的node_modules中, 先去node_modules中找到 art-template文件夹 在 art-template文件就按中找到packge.json packge.json文件中找到main.js属性 通过main.js属性值找到找到具体的.js文件指向 执行指向的.js文件 ...

MagicWing的博客 959

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Node.js 中的模块的加载机制(模块查找规则)

模块查找规则-当模块拥有路径但没有后缀时 require('./find.js'); 1.require方法根据模块路径查找模块,如果是完整路径,直接引入模块 require('./find'); 2.如果模块后缀省略,先找同名js文件 ,再找同名js文件夹 如果找到同名文件夹,就找文件夹中的index.js 如果文件夹中没有index.js就会去当前文件夹(find文件夹...

weixin_41984072的博客 475

node的模块查找策略

在查找文件模块时,Node.js 会自动尝试添加 `.js`、`.json`、`.node` 等扩展名。例如,如果你调用 `require('./module')`,Node.js 会依次尝试加载 `./module.js`、`./module.json` 和 `./module.node`。如果没有 `package.json` 或 `main` 字段,Node.js 会尝试加载该目录下的 `index.js` 文件。1. 如果路径指向一个文件,Node.js 会直接加载该文件。

2301_80649723的博客 535

node.js中模块查找机制、npm的常用命令行语句、node.js中的修改代码自启动依赖包

node.js中模块查找机制、npm的常用命令行语句、node.js中的修改代码自启动依赖包

weixin_46054349的博客 651

Node.js - 模块查找规则

1、当模块拥有路径拥有后缀 require('./find.js') 直接引入模块; 2、当模块拥有路径但没有后缀时 require('./find') 先找同级同名的.js文件; 再找同级同名.json文件; 再找同级同名.node文件; 再找同名的文件夹; 再找同名文件夹下的package.json文件中的main选项中的入口文件; 再找同名文件夹下的index.js文件; 3...

前端开发-陈善强 533

nodejs 模块查找一起缓存机制

nodejs在加载外部自定义模块时对模块有查找顺序,找到后还会进行缓存。 查找顺序: 1. 相对路径,比如提供./ 或者../这种以'./'和‘..’开始的路径,简单的,就是相对当前位置的路径。 2.绝对路径,这时候将按以下顺序查找: 假设执行路径为C:\Intel\research\subFolder 那么查找顺序为 [ 'C:\\Intel\\research\\subFo

sxyizhiren的专栏 1342

【nodejs】nodejs中模块加载机制、模块查找规则(5)

沛沛呀、 423

Node:深入模块机制

NodeJS:深入模块机制 1. CommonJS规范 CommonJS(http://www.commonjs.org)规范的出现,其目标是为了构建JavaScript在包括Web服务器,桌面,命令行工具,及浏览器方面的生态系统。CommonJS其实不是一门新的语言,甚至都不能说它是一个新的解释器——实际上它只是一个概念或者是一个规范。 它具体弥补了前端JavaScript 的哪些空白呢?其实这也涉及了很多前端JavaScript 所没有涉及的东西,如二进制、编码、IO、文件、系统、断言测试、套接

yivisir的博客 621

node自定义模块的路径查找

自定义模块指的是非核心模块,也不是路径形式的标识符。它是一种特殊的文件模块,可能是一个文件或者包的形式。这类模块的查找是最费时的,也是所有方式中最慢的一种。 模块路径是Node在定位文件模块的具体文件时制定的查找策略,具体表现为一个路径组成的数组。关于这个路径的生成规则,我们可以手动尝试一番。 创建test.js文件,其内容为 console.log(module.paths); 。将其放到任...

weixin_30384031的博客 160
上一篇: webpack处理vue项目静态资源及public/static/assets目录的区别
下一篇: Flutter接收一个Widget类型可空参数报`A value of type ‘Widget?‘ can‘t be assigned to a variable of type ‘Widget‘`
jsPao
博客等级 码龄7年 549粉丝 107原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值