登录
注册
开源
企业版
高校版
搜索
帮助中心
使用条款
关于我们
开源
企业版
高校版
私有云
模力方舟
AI 队友
登录
注册
Gitee 2025 年度开源项目评选中
代码拉取完成,页面将自动刷新
捐赠
捐赠前请先登录
取消
前往登录
扫描微信二维码支付
取消
支付完成
支付提示
将跳转至支付宝完成支付
确定
取消
Watch
不关注
关注所有动态
仅关注版本发行动态
关注但不提醒动态
3
Star
45
Fork
21
DreamCoders
/
CoderGuide
代码
Issues
1169
Pull Requests
0
Wiki
统计
流水线
服务
JavaDoc
PHPDoc
质量分析
Jenkins for Gitee
腾讯云托管
腾讯云 Serverless
悬镜安全
阿里云 SAE
Codeblitz
SBOM
我知道了,不再自动展开
更新失败,请稍后重试!
移除标识
内容风险标识
本任务被
标识为内容中包含有代码安全 Bug 、隐私泄露等敏感信息,仓库外成员不可访问
说说 Node 文件查找的优先级以及 Require 方法的文件查找策略?
待办的
#IAG9KW
陌生人
拥有者
创建于
2024-07-29 16:04
<h2>一、模块规范</h2><p><code>NodeJS</code>对<code>CommonJS</code>进行了支持和实现,让我们在开发<code>node</code>的过程中可以方便的进行模块化开发:</p><ul><li>在Node中每一个js文件都是一个单独的模块</li><li>模块中包括CommonJS规范的核心变量:exports、module.exports、require</li><li>通过上述变量进行模块化开发</li></ul><p>而模块化的核心是导出与导入,在<code>Node</code>中通过<code>exports</code>与<code>module.exports</code>负责对模块中的内容进行导出,通过<code>require</code>函数导入其他模块(自定义模块、系统模块、第三方库模块)中的内容</p><h2>二、查找策略</h2><p><code>require</code>方法接收一下几种参数的传递:</p><ul><li>原生模块:http、fs、path等</li><li>相对路径的文件模块:./mod或../mod</li><li>绝对路径的文件模块:/pathtomodule/mod</li><li>目录作为模块:./dirname</li><li>非原生模块的文件模块:mod</li></ul><p><code>require</code>参数较为简单,但是内部的加载却是十分复杂的,其加载优先级也各自不同,如下图:</p><p><img src="https://static.ecool.fun//article/b2d6abb0-d8f5-4398-bcd3-5ee967d1da14.png" alt="" data-href="" style=""/></p><p>从上图可以看见,文件模块存在缓存区,寻找模块路径的时候都会优先从缓存中加载已经存在的模块</p><h3>原生模块</h3><p>而像原生模块这些,通过<code>require</code>方法在解析文件名之后,优先检查模块是否在原生模块列表中,如果在则从原生模块中加载</p><h3>绝对路径、相对路径</h3><p>如果<code>require</code>绝对路径的文件,则直接查找对应的路径,速度最快</p><p>相对路径的模块则相对于当前调用<code>require</code>的文件去查找</p><p>如果按确切的文件名没有找到模块,则 <code>NodeJs</code> 会尝试带上 <code>.js</code>、<code>.json</code>或 <code>.node</code>拓展名再加载</p><h3>目录作为模块</h3><p>默认情况是根据根目录中<code>package.json</code>文件的<code>main</code>来指定目录模块,如:</p><pre><code class="language-json">{ "name" : "some-library", "main" : "main.js" }</code></pre><p>如果这是在<code>./some-library node_modules</code>目录中,则 <code>require('./some-library')</code> 会试图加载 <code>./some-library/main.js</code></p><p>如果目录里没有 <code>package.json</code>文件,或者 <code>main</code>入口不存在或无法解析,则会试图加载目录下的 <code>index.js</code> 或 <code>index.node</code> 文件</p><h3>非原生模块</h3><p>在每个文件中都存在<code>module.paths</code>,表示模块的搜索路径,<code>require</code>就是根据其来寻找文件</p><p>在<code>window</code>下输出如下:</p><pre><code class="language-js">[ 'c:\\nodejs\\node_modules', 'c:\\node_modules' ]</code></pre><p>可以看出<code>module path</code>的生成规则为:从当前文件目录开始查找<code>node_modules</code>目录;然后依次进入父目录,查找父目录下的<code>node_modules</code>目录,依次迭代,直到根目录下的<code>node_modules</code>目录</p><p>当都找不到的时候,则会从系统<code>NODE_PATH</code>环境变量查找</p><h4>举个例子:</h4><p>如果在<code>/home/ry/projects/foo.js</code>文件里调用了 <code>require('bar.js')</code>,则 Node.js 会按以下顺序查找:</p><ul><li>/home/ry/projects/node_modules/bar.js</li><li>/home/ry/node_modules/bar.js</li><li>/home/node_modules/bar.js</li><li>/node_modules/bar.js</li></ul><p>这使得程序本地化它们的依赖,避免它们产生冲突</p><h2>三、总结</h2><p>通过上面模块的文件查找策略之后,总结下文件查找的优先级:</p><ul><li>缓存的模块优先级最高</li><li>如果是内置模块,则直接返回,优先级仅次缓存的模块</li><li>如果是绝对路径 / 开头,则从根目录找</li><li>如果是相对路径 ./开头,则从当前require文件相对位置找</li><li>如果文件没有携带后缀,先从js、json、node按顺序查找</li><li>如果是目录,则根据 package.json的main属性值决定目录下入口文件,默认情况为 index.js</li><li>如果文件为第三方模块,则会引入 node_modules 文件,如果不在当前仓库文件中,则自动从上级递归查找,直到根目录</li></ul>
<h2>一、模块规范</h2><p><code>NodeJS</code>对<code>CommonJS</code>进行了支持和实现,让我们在开发<code>node</code>的过程中可以方便的进行模块化开发:</p><ul><li>在Node中每一个js文件都是一个单独的模块</li><li>模块中包括CommonJS规范的核心变量:exports、module.exports、require</li><li>通过上述变量进行模块化开发</li></ul><p>而模块化的核心是导出与导入,在<code>Node</code>中通过<code>exports</code>与<code>module.exports</code>负责对模块中的内容进行导出,通过<code>require</code>函数导入其他模块(自定义模块、系统模块、第三方库模块)中的内容</p><h2>二、查找策略</h2><p><code>require</code>方法接收一下几种参数的传递:</p><ul><li>原生模块:http、fs、path等</li><li>相对路径的文件模块:./mod或../mod</li><li>绝对路径的文件模块:/pathtomodule/mod</li><li>目录作为模块:./dirname</li><li>非原生模块的文件模块:mod</li></ul><p><code>require</code>参数较为简单,但是内部的加载却是十分复杂的,其加载优先级也各自不同,如下图:</p><p><img src="https://static.ecool.fun//article/b2d6abb0-d8f5-4398-bcd3-5ee967d1da14.png" alt="" data-href="" style=""/></p><p>从上图可以看见,文件模块存在缓存区,寻找模块路径的时候都会优先从缓存中加载已经存在的模块</p><h3>原生模块</h3><p>而像原生模块这些,通过<code>require</code>方法在解析文件名之后,优先检查模块是否在原生模块列表中,如果在则从原生模块中加载</p><h3>绝对路径、相对路径</h3><p>如果<code>require</code>绝对路径的文件,则直接查找对应的路径,速度最快</p><p>相对路径的模块则相对于当前调用<code>require</code>的文件去查找</p><p>如果按确切的文件名没有找到模块,则 <code>NodeJs</code> 会尝试带上 <code>.js</code>、<code>.json</code>或 <code>.node</code>拓展名再加载</p><h3>目录作为模块</h3><p>默认情况是根据根目录中<code>package.json</code>文件的<code>main</code>来指定目录模块,如:</p><pre><code class="language-json">{ "name" : "some-library", "main" : "main.js" }</code></pre><p>如果这是在<code>./some-library node_modules</code>目录中,则 <code>require('./some-library')</code> 会试图加载 <code>./some-library/main.js</code></p><p>如果目录里没有 <code>package.json</code>文件,或者 <code>main</code>入口不存在或无法解析,则会试图加载目录下的 <code>index.js</code> 或 <code>index.node</code> 文件</p><h3>非原生模块</h3><p>在每个文件中都存在<code>module.paths</code>,表示模块的搜索路径,<code>require</code>就是根据其来寻找文件</p><p>在<code>window</code>下输出如下:</p><pre><code class="language-js">[ 'c:\\nodejs\\node_modules', 'c:\\node_modules' ]</code></pre><p>可以看出<code>module path</code>的生成规则为:从当前文件目录开始查找<code>node_modules</code>目录;然后依次进入父目录,查找父目录下的<code>node_modules</code>目录,依次迭代,直到根目录下的<code>node_modules</code>目录</p><p>当都找不到的时候,则会从系统<code>NODE_PATH</code>环境变量查找</p><h4>举个例子:</h4><p>如果在<code>/home/ry/projects/foo.js</code>文件里调用了 <code>require('bar.js')</code>,则 Node.js 会按以下顺序查找:</p><ul><li>/home/ry/projects/node_modules/bar.js</li><li>/home/ry/node_modules/bar.js</li><li>/home/node_modules/bar.js</li><li>/node_modules/bar.js</li></ul><p>这使得程序本地化它们的依赖,避免它们产生冲突</p><h2>三、总结</h2><p>通过上面模块的文件查找策略之后,总结下文件查找的优先级:</p><ul><li>缓存的模块优先级最高</li><li>如果是内置模块,则直接返回,优先级仅次缓存的模块</li><li>如果是绝对路径 / 开头,则从根目录找</li><li>如果是相对路径 ./开头,则从当前require文件相对位置找</li><li>如果文件没有携带后缀,先从js、json、node按顺序查找</li><li>如果是目录,则根据 package.json的main属性值决定目录下入口文件,默认情况为 index.js</li><li>如果文件为第三方模块,则会引入 node_modules 文件,如果不在当前仓库文件中,则自动从上级递归查找,直到根目录</li></ul>
评论 (
0
)
登录
后才可以发表评论
状态
待办的
待办的
进行中
已完成
已关闭
负责人
未设置
标签
Node
未设置
标签管理
里程碑
未关联里程碑
未关联里程碑
Pull Requests
未关联
未关联
关联的 Pull Requests 被合并后可能会关闭此 issue
分支
未关联
未关联
master
开始日期   -   截止日期
-
置顶选项
不置顶
置顶等级:高
置顶等级:中
置顶等级:低
优先级
不指定
严重
主要
次要
不重要
参与者(1)
1
https://gitee.com/DreamCoders/CoderGuide.git
git@gitee.com:DreamCoders/CoderGuide.git
DreamCoders
CoderGuide
CoderGuide
点此查找更多帮助
搜索帮助
Git 命令在线学习
如何在 Gitee 导入 GitHub 仓库
Git 仓库基础操作
企业版和社区版功能对比
SSH 公钥设置
如何处理代码冲突
仓库体积过大,如何减小?
如何找回被删除的仓库数据
Gitee 产品配额说明
GitHub仓库快速导入Gitee及同步更新
什么是 Release(发行版)
将 PHP 项目自动发布到 packagist.org
评论
仓库举报
回到顶部
登录提示
该操作需登录 Gitee 帐号,请先登录后再操作。
立即登录
没有帐号,去注册