一、模块规范

NodeJSCommonJS进行了支持和实现,让我们在开发node的过程中可以方便的进行模块化开发:

  • 在Node中每一个js文件都是一个单独的模块
  • 模块中包括CommonJS规范的核心变量:exports、module.exports、require
  • 通过上述变量进行模块化开发

而模块化的核心是导出与导入,在Node中通过exportsmodule.exports负责对模块中的内容进行导出,通过require函数导入其他模块(自定义模块、系统模块、第三方库模块)中的内容

二、查找策略

require方法接收一下几种参数的传递:

  • 原生模块:http、fs、path等
  • 相对路径的文件模块:./mod或../mod
  • 绝对路径的文件模块:/pathtomodule/mod
  • 目录作为模块:./dirname
  • 非原生模块的文件模块:mod

require参数较为简单,但是内部的加载却是十分复杂的,其加载优先级也各自不同,如下图:

从上图可以看见,文件模块存在缓存区,寻找模块路径的时候都会优先从缓存中加载已经存在的模块

原生模块

而像原生模块这些,通过require方法在解析文件名之后,优先检查模块是否在原生模块列表中,如果在则从原生模块中加载

绝对路径、相对路径

如果require绝对路径的文件,则直接查找对应的路径,速度最快

相对路径的模块则相对于当前调用require的文件去查找

如果按确切的文件名没有找到模块,则 NodeJs 会尝试带上 .js.json或 .node拓展名再加载

目录作为模块

默认情况是根据根目录中package.json文件的main来指定目录模块,如:

{ "name" : "some-library",
  "main" : "main.js" }

如果这是在./some-library node_modules目录中,则 require('./some-library') 会试图加载 ./some-library/main.js

如果目录里没有 package.json文件,或者 main入口不存在或无法解析,则会试图加载目录下的 index.js 或 index.node 文件

非原生模块

在每个文件中都存在module.paths,表示模块的搜索路径,require就是根据其来寻找文件

window下输出如下:

[ 'c:\\nodejs\\node_modules',
'c:\\node_modules' ]

可以看出module path的生成规则为:从当前文件目录开始查找node_modules目录;然后依次进入父目录,查找父目录下的node_modules目录,依次迭代,直到根目录下的node_modules目录

当都找不到的时候,则会从系统NODE_PATH环境变量查找

举个例子:

如果在/home/ry/projects/foo.js文件里调用了 require('bar.js'),则 Node.js 会按以下顺序查找:

  • /home/ry/projects/node_modules/bar.js
  • /home/ry/node_modules/bar.js
  • /home/node_modules/bar.js
  • /node_modules/bar.js

这使得程序本地化它们的依赖,避免它们产生冲突

三、总结

通过上面模块的文件查找策略之后,总结下文件查找的优先级:

  • 缓存的模块优先级最高

  • 如果是内置模块,则直接返回,优先级仅次缓存的模块

  • 如果是绝对路径 / 开头,则从根目录找

  • 如果是相对路径 ./开头,则从当前require文件相对位置找

  • 如果文件没有携带后缀,先从js、json、node按顺序查找

  • 如果是目录,则根据 package.json的main属性值决定目录下入口文件,默认情况为 index.js

  • 如果文件为第三方模块,则会引入 node_modules 文件,如果不在当前仓库文件中,则自动从上级递归查找,直到根目录

Node 文件查找的优先级以及 Require 方法的文件查找策略的更多相关文章

  1. XML序列化 判断是否是手机 字符操作普通帮助类 验证数据帮助类 IO帮助类 c# Lambda操作类封装 C# -- 使用反射(Reflect)获取dll文件中的类型并调用方法 C# -- 文件的压缩与解压(GZipStream)

    XML序列化   #region 序列化 /// <summary> /// XML序列化 /// </summary> /// <param name="ob ...

  2. Node.js 使用Stream的pipe(管道)方法实现文件复制

    Stream模块有一个pipe方法,可以将两个流串起来,实现所有的数据自动从Readable流进入Writable流 "use strict"; const fs = requir ...

  3. Node.js require 方法

    Node.js 中存在 4 类模块(原生模块和3种文件模块),尽管 require 方法极其简单,但是内部的加载却是十分复杂的,其加载优先级也各自不同

  4. nodejs中 require 方法的加载规则

    require参数类型 http.fs.path等,原生模块 ./mod或../mod,相对路径的文件模块 /pathtomodule/mod,绝对路径的文件模块 mod,非原生模块的文件模块 在进 ...

  5. Node.js中exports,module.exports以及require方法

    在Node.js中,使用module.exports.f = ...与使用exports.f = ...是一样的,此时exports就是module.exports的一种简写方式.但是,需要注意的是, ...

  6. uni-app开发的应用(小程序,app,web等),使用Node+Koa2开发的后端程序接收上传文件的方法

    uni-app使用使用Node+Koa2开发的后端程序接收上传的文件 通过gitbook浏览此随笔 通过其它客户端上传(h5,小程序等),接收方法一致 使用koa接收时,我们需安装一个中间件koa-b ...

  7. python查找指定目录下所有文件,以及改文件名的方法

    一: os.listdir(path) 把path目录下的所有文件保存在列表中: >>> import os>>> import re>>> pa ...

  8. appium 元素文件 -查找元素 封装思路和方法

    方法1. try: target="//android.widget.TextView[@text='立即體驗']" element = WebDriverWait(dr,5,0. ...

  9. node.js 在 Express4.0 框架使用 Connect-Busboy 实现文件上传

    node.js下四种post提交数据的方式 今天说分享的是其中一种,就是上传文件. Express 4.0 以后,将功能原子化,高内聚,低耦合,独立出了很多中间件 今天主要分享文件上传 对于conne ...

  10. [js高手之路]node js系列课程-创建简易web服务器与文件读写

    web服务器至少有以下几个特点: 1.24小时不停止的工作,也就是说这个进程要常驻在内存中 2.24小时在某一端口监听,如: http://localhost:8080, www服务器默认端口80 3 ...

随机推荐

  1. Python 潮流周刊第 41 期(摘要),赠书5本

    本周刊由 Python猫 出品,精心筛选国内外的 250+ 信息源,为你挑选最值得分享的文章.教程.开源项目.软件工具.播客和视频.热门话题等内容.愿景:帮助所有读者精进 Python 技术,并增长职 ...

  2. Pod中断预算 PodDisruptionBudget(PDB)

    PodDisruptionBudget(PDB)是Kubernetes中的一个资源对象,用于确保在进行维护.升级或其他操作时,系统中的Pod不会被意外中断或终止.PDB提供了一种机制,通过限制在给定时 ...

  3. CMake的作用和价值--概念简介

    一 简介: CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程).他能够输出各种各样的makefile或者project文件,能测试编译器所支持的C++特性,类似 ...

  4. JavaFx实现倒计时按钮组件(类似发送激活码)

    原文地址: JavaFx实现倒计时按钮组件(类似发送激活码) - Stars-One的杂货小窝 本文基于TornadoFx框架进行编写,封装工具代码是kotlin版本 然后也是顺便把这个封装成了sta ...

  5. atcoder: Moves on Binary Tree

    先进行压缩move的次数,再用biginteger. import java.io.BufferedReader; import java.io.IOException; import java.io ...

  6. 说JS作用域,就不得不说说自执行函数

    一个兜兜转转,从"北深"回到三线城市的小码农,热爱生活,热爱技术,在这里和大家分享一个技术人员的点点滴滴.欢迎大家关注我的微信公众号:果冻想 前言 不得不吐槽,学个JS,这个概念也 ...

  7. 3DCAT首届行业生态交流会|升大科技CEO邱杰:5G云渲染助力企业培训

    2021年12月17日下午,由深圳市瑞云科技有限公司主办,深圳市虚拟现实产业联合会协办的 云XR如何赋能元宇宙--3DCAT实时云渲染首届行业生态合作交流会 圆满落幕 .此次活动围绕"云XR ...

  8. java 发送 http 请求练习两年半(HttpURLConnection)

    1.起一个 springboot 程序做 http 测试: @GetMapping("/http/get") public ResponseEntity<String> ...

  9. Asp-Net-Core开发笔记:实现动态审计日志功能

    前言 最近一直在写 Go 和 Python ,好久没写 C# ,重新回来写 C# 代码时竟有一种亲切感~ 说回正题. 在当今这个数字化迅速发展的时代,每一个操作都可能对业务产生深远的影响,无论是对数据 ...

  10. 使用graphviz图形化展示路径(决策树用到此库)

    问题:当出现错误 graphviz.backend.execute.ExecutableNotFound: failed to execute WindowsPath('dot'), make sur ...