返回顶部
首页 > 资讯 > 前端开发 > VUE >NodeJS中的模块是单例吗
  • 403
分享到

NodeJS中的模块是单例吗

2024-04-02 19:04:59 403人浏览 泡泡鱼
摘要

本篇内容介绍了“nodejs中的模块是单例吗”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!nodejs的模

本篇内容介绍了“nodejs中的模块是单例吗”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

nodejs的模块默认情况下是单例性质的,不过其并不能保证如我们编程时设想的那样一定是单例,根据NodeJS的官方文档中描述,某个模块导入是否为单例受以下两个因素的影响:

  • Node  模块的缓存机制是大小写敏感的,譬如如果你require('/foo')与require('/FOO')会返回两个不同的对象,尽管你的foo与FOO是完全相同的文件。

  • 模块是基于其被解析得到的文件名进行缓存的,鉴于不同的模块会依赖于其被调用的路径进行缓存鉴别,因此并不能保证你使用require('foo')会永远返回相同的对象,可能会根据不同的文件路径得到不同的对象。

创建新的NodeJS模块

根据NodeJS文档所述,文件和模块是一一对应的关系。这个也是解释上文提及的模块缓存机制的基础,我们首先创建一个简单的模块:

// counter.js   let value = 0  module.exports = {   increment: () => value++,   get: () => value, }

在counter.js中我们创建了某个私有变量,并且只能通过公共的increment与get方法进行操作。在应用中我们可以如下方法使用该模块:

// app.js const counter = require(‘./counter.js’)  counter.increment() counter.increment()  console.log(counter.get()) // prints 2 console.log(counter.value) // prints undefined as value is private

Module Caching

NodeJS会在***次导入某个模块之后将该模块进行缓存,在官方文档中有如下描述:

Every call to require(‘foo’) will get exactly the same object returned, if it  would resolve to the same file.

我们也可以通过如下简单的例子来验证这句话:

// app-singleton.js  const counter1 = require(‘./counter.js’) const counter2 = require(‘./counter.js’)  counter1.increment() counter1.increment() counter2.increment()  console.log(counter1.get()) // prints 3 console.log(counter2.get()) // also prints 3

可以看出尽管我们两次导入了该模块,但是还是指向了同一个对象。不过并不是每次我们导入同一个模块时,都会得到相同的对象。在NodeJS中,模块对象有个内置的方法:Module._resolveFilename(),其负责寻找require中合适的模块,在找到正确的文件之后,会根据其文件名作为缓存的键名。官方的搜索算法伪代码为:

require(X) from module at path Y 1. If X is a core module,    a. return the core module    b. STOP 2. If X begins with './' or '/' or '../' a. LOAD_AS_FILE(Y + X)       1. If X is a file, load X as javascript text.  STOP       2. If X.js is a file, load X.js as JavaScript text.  STOP       3...       4... b. LOAD_AS_DIRECTORY(Y + X)       1. If X/package.JSON is a file,          a. Parse X/package.json, and look for "main" field.          b. let M = X + (json main field)          c. LOAD_AS_FILE(M)       2. If X/index.js is a file, load X/index.js as JS text.  STOP       3...       4... 3. LOAD_NODE_MODULES(X, dirname(Y)) 4. THROW "not found"

简单来说,加载的逻辑或者说优先级为:

  • 优先判断是不是核心模块

  • 如果不是核心模块则搜索node_modules

  • 否则在相对路径中进行搜索

解析之后的文件名可以根据module对象或得到:

// counter-debug.js  console.log(module.filename) // prints absolute path to counter.js console.log(__filename) // prints same as above // i get: "/Users/laz/repos/medium/modules/counter-debug.js"  let value = 0  module.exports = {   increment: () => value++,   get: () => value,

在上述的例子中我们可以看出,解析得到的文件名即使被加载模块的绝对路径。而根据文件与模块一一映射的原则,我们可以得出下面两个会破坏模块导入单例性的特例。

Case Sensitivity

在大小写敏感的文件系统中或者操作系统中,不同的解析之后的文件可能会指向相同的文件,但是其缓存键名会不一致,即不同的导入会生成不同的对象。

// app-no-singleton-1.js const counter1 = require('./counter.js') const counter2 = require('./COUNTER.js')  counter1.increment() console.log(counter1.get()) // prints 1 console.log(counter2.get()) // prints 0, not same object as counter1  

在上面的例子中,我们分别用counter、COUNTER这仅仅是大小写不同的方式导入相同的某个文件,如果是在某个大小写敏感的系统中,譬如ubuntu中会直接抛出异常:

NodeJS中的模块是单例吗

解析为不同的文件名

当我们使用require(x)并且x不属于核心模块时,其会自动搜索node_modules文件夹。而在npm3之前,项目会以嵌套的方式安装依赖。因此当我们的项目依赖module-a与module-b,并且module-a与module-b也相互依赖时,其会生成如下文件路径格式:

// npm2 installed dependencies in nested way app.js package.json node_modules/ |---module-a/index.js |---module-b/index.js     |---node_modules         |---module-a/index.js

这样的话,我们对于同一个模块就有两个副本,那当我们在应用中导入module-a时,岂会载入如下文件:

 // app.js const moduleA = require(‘module-a’) loads: “/node_modules/module-a/index.js”

而从module-b中载入module-a时,其载入的是如下文件:

 // /node_modules/module-b/index.js const moduleA = require(‘module-a’) loads “/node_modules/module-b/node_modules/module-a/index.js”

不过在npm3之后,其以扁平化方式进行文件加载,其文件目录结构如下所示:

 // npm3 flattens secondary dependencies by installing in same folder app.js package.json node_modules/ |---module-a/index.js |---module-b/index.js

不过此时就存在另一个场景,即我们应用本身依赖module-a@v1.1与module-b,而module-b又依赖于module-a@v1.2,在这种情况下还是会采用类似于npm3之前的嵌套式目录结构。这样的话对于module-a一样会产生不同的对象,不过此时本身就是不同的文件了,因此相互之间不会产生冲突。

“NodeJS中的模块是单例吗”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

--结束END--

本文标题: NodeJS中的模块是单例吗

本文链接: https://lsjlt.com/news/86300.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • NodeJS中的模块是单例吗
    本篇内容介绍了“NodeJS中的模块是单例吗”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!NodeJS的模...
    99+
    2024-04-02
  • nodejs中模块定义的示例分析
    这篇文章将为大家详细讲解有关nodejs中模块定义的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。具体如下:1.模块定义nodejs所谓的模块就是一个文件!一个....
    99+
    2024-04-02
  • Nodejs中模块规范的示例分析
    这篇文章主要为大家展示了“Nodejs中模块规范的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Nodejs中模块规范的示例分析”这篇文章吧。CommonJS 模块规范以前加载 JS 文...
    99+
    2023-06-15
  • nodejs中模块化指的是什么
    这篇“nodejs中模块化指的是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“node...
    99+
    2024-04-02
  • 什么是nodejs模块
    本篇内容介绍了“什么是nodejs模块”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成! ...
    99+
    2024-04-02
  • nodejs中模块定义实例详解
    本文实例讲述了nodejs中模块定义方法。分享给大家供大家参考,具体如下: 1.模块定义 nodejs所谓的模块就是一个文件!一个.js文件就是一个nodejs的模块,模块与文件是一一对应的,那么引用模块就...
    99+
    2022-06-04
    详解 实例 模块
  • Nodejs中Buffer模块的用法是什么
    这篇文章主要介绍“Nodejs中Buffer模块的用法是什么”,在日常操作中,相信很多人在Nodejs中Buffer模块的用法是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解...
    99+
    2024-04-02
  • Nodejs中cluster模块的作用是什么
    这期内容当中小编将会给大家带来有关Nodejs中cluster模块的作用是什么,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。code1const cluster...
    99+
    2024-04-02
  • nodejs中的http模块与npm模块使用
    目录http模块创建服务器基本步骤request对象详解response对象详解实现静态WEB服务器服务器响应首页根据根据不同url,响应不同文件静态资源的通用处理npm - Nod...
    99+
    2022-11-13
    nodejs中http模块 nodejs中npm模块 http模块与npm模块使用
  • ws是不是nodejs的内置模块
    这篇文章给大家分享的是有关ws是不是nodejs的内置模块的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。 ws不是nodejs的内置模块。ws是nod...
    99+
    2024-04-02
  • nodejs是单进程吗
    这篇文章主要讲解了“nodejs是单进程吗”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“nodejs是单进程吗”吧! nodej...
    99+
    2024-04-02
  • NodeJs中的VM模块详解
    什么是VM? VM模块是NodeJS里面的核心模块,支撑了require方法和NodeJS的运行机制,我们有些时候可能也要用到VM模板来做一些特殊的事情。 通过VM,JS可以被编译后立即执行或者编译保存下来...
    99+
    2022-06-04
    详解 模块 NodeJs
  • Nodejs中crypto模块的用法
    这篇文章主要介绍“Nodejs中crypto模块的用法”,在日常操作中,相信很多人在Nodejs中crypto模块的用法问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Node...
    99+
    2024-04-02
  • nodejs官方模块是什么
    这篇文章主要介绍了nodejs官方模块是什么,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。 nodejs官方模块...
    99+
    2024-04-02
  • NodeJS中Buffer模块详解
    一,开篇分析 所谓缓冲区Buffer,就是 "临时存贮区" 的意思,是暂时存放输入输出数据的一段内存。 JS语言自身只有字符串数据类型,没有二进制数据类型,因此NodeJS提供了一个与String对等的全局...
    99+
    2022-06-04
    详解 模块 NodeJS
  • Nodejs文件模块中fs.mkdir和fs.rmdir的示例分析
    这篇文章主要为大家展示了“Nodejs文件模块中fs.mkdir和fs.rmdir的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Nodejs文件模块中...
    99+
    2024-04-02
  • nodejs中的读取文件fs模块示例详解
    目录什么是 nodejs?global 模块-全局变量fs模块读取文件写文件追加文件文件同步与异步的说明总结:什么是 nodejs? Node.js 是一个基于 Chrome V8...
    99+
    2022-12-19
    nodejs 读取文件fs模块 nodejs读取fs
  • nodejs连接mysql数据库简单封装示例-mysql模块
    本人最近在学习研究nodejs,下面我来记录一下,有需要了解nodejs连接mysql数据库简单封装的朋友可参考。希望此文章对各位有所帮助。 安装mysql模块 npm install mysql ...
    99+
    2022-06-04
    示例 模块 简单
  • Nodejs中的net模块怎么用
    这篇文章主要介绍了Nodejs中的net模块怎么用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Nodejs中的net模块怎么用文章都会有所收获,下面我们一起来看看吧。1. O...
    99+
    2024-04-02
  • nodejs中events模块怎么办
    这篇文章将为大家详细讲解有关nodejs中events模块怎么办,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。events模块是node的核心模块,几乎所有常用的node模块都继承了events模块,比如...
    99+
    2023-06-06
软考高级职称资格查询
推荐阅读
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作