HoRain云--Node.js模块系统

发布时间:2026/11/1 17:00:47

HoRain云--Node.js模块系统 Node.js 模块系统是其核心功能之一它允许开发者将代码组织成小的、可重用的单元这些单元被称为模块。模块是一个封装了特定功能的独立文件可以在其他文件中引入和使用。Node.js 的模块系统是构建 Node.js 应用程序的重要基础使开发者能够将代码拆分成可重用、可维护的小块。每个模块都是一个单独的 JavaScript 文件包含一组相关的函数、对象或变量通过这种方式Node.js 提供了一种结构化的方法来管理大型应用程序使代码更加清晰和易于维护。Node.js 中的每个文件都可以作为一个模块默认处于独立的作用域内。模块系统遵循 CommonJS 规范但也支持 ES 模块。模块类型Node.js 支持以下几种模块内置模块Node.js 自带的模块如fs、http、path等。用户自定义模块由开发者创建的模块。第三方模块通过 npm 安装的模块如express、lodash等。导入内置模块内置模块是由 Node.js 自带的模块在安装 Node.js 时就已经包含在环境中因此无需额外安装。常见的内置模块包括 fs、http、path、os、crypto 等。导入内置模块只需要使用 require() 函数并传入模块名称即可。例如要导入文件系统模块 fs、path、http可以这样做// 导入文件系统模块 const fs require(fs); // 导入路径模块 const path require(path); // 导入 HTTP 模块 const http require(http);这里fs 是一个字符串表示要加载的模块名称。Node.js 会自动识别这是一个内置模块并加载相应的功能。实例const os require(os);console.log(Operating System:, os.platform());console.log(Total Memory:, os.totalmem());导入第三方模块第三方模块是开发者或开源社区发布的模块可以通过 npmNode 包管理器安装到项目中常见的第三方模块有 express、lodash、axios 等。第三方模块安装后这些模块会被放置在项目的 node_modules 目录下。要导入一个第三方模块同样使用 require() 函数但传入的是模块的名称。例如要导入 express 框架可以这样做// 导入第三方模块 express const express require(express);在导入第三方模块之前确保已经通过 npm 安装了该模块。例如安装 express 可以通过以下命令完成npm install express安装第三方模块 lodash并导入测试实例const lodash require(lodash);const array [1, 2, 3, 4];const reversedArray lodash.reverse(array.slice()); // 使用 lodash 反转数组console.log(Reversed Array:, reversedArray);自定义模块导出与导入CommonJS 模块1、导出模块使用 module.exports 或 exports 将函数、对象或变量导出。2、导入模块使用 require() 导入模块。导入模块在 Node.js 中引入一个模块非常简单如下我们创建一个main.js文件并引入 hello 模块代码如下:main.js 文件代码var hello require(./hello);hello.world();以上实例中代码 require(./hello) 引入了当前目录下的hello.js文件./ 为当前目录node.js 文件默认后缀为 .js。Node.js 提供了 exports 和 require 两个对象其中 exports 是模块公开的接口require 用于从外部获取一个模块的接口即所获取模块的 exports 对象。接下来我们就来创建 hello.js 文件代码如下hello.js 文件代码exports.world function() {console.log(Hello World);}在以上示例中hello.js 通过 exports 对象把 world 作为模块的访问接口在 main.js 中通过 require(./hello) 加载这个模块然后就可以直接访问 hello.js 中exports对象的成员函数了。有时候我们只是想把一个对象封装到模块中格式如下module.exports function() { // ... }例如:hello.js 文件代码// hello.jsfunction Hello() {var name;this.setName function(thyName) {name thyName;};this.sayHello function() {console.log(Hello name);};};module.exports Hello;这样就可以直接获得这个对象了main.js 文件代码// main.jsvar Hello require(./hello);hello new Hello();hello.setName(BYVoid);hello.sayHello();模块接口的唯一变化是使用 module.exports Hello 代替了 exports.world function(){}。 在外部引用该模块时其接口对象就是要输出的 Hello 对象本身而不是原先的 exports。module.exports 与 exports 的区别module.exports是导出对象的真正引用。exports是module.exports的快捷方式。不能直接赋值exports ...否则会断开引用。自定义模块导出与导入ES 模块ES 模块使用 import 和 export是现代 JavaScript 的模块规范。ES 模块使用import和export关键字需将文件扩展名设置为.mjs或者在package.json中声明type: module。ES 模块支持静态导入import ... from ...和动态导入import()。实例// myModule.mjsexport function greet(name) {return Hello, ${name}!;}// main.mjsimport { greet } from ./myModule.mjs;console.log(greet(Bob)); // 输出Hello, Bob!加载模块的路径解析1、核心模块如 http 和 fs在 Node.js 安装时就包含可以直接加载。const http require(http);2、本地文件模块使用相对路径或绝对路径加载需指定 ./ 或 /。const myModule require(./myModule);3、第三方模块位于node_modules目录中只需输入模块名称即可加载。const express require(express);模块缓存模块缓存机制Node.js 会将已加载的模块缓存起来以提高性能。再次 require() 同一模块时直接返回缓存中的模块而不是重新加载。刷新缓存要重新加载模块可以删除缓存delete require.cache[require.resolve(./myModule)];循环依赖当两个或多个模块相互导入时称为循环依赖。Node.js 能处理简单的循环依赖但可能导致部分模块导出的对象未完全初始化。实例// a.jsconst b require(./b);console.log(a.js:, b.message);module.exports { message: Hello from a };// b.jsconst a require(./a);console.log(b.js:, a.message);module.exports { message: Hello from b };// main.jsrequire(./a);输出说明 b.js 导入 a.js 时由于 a.js 尚未完全执行a.message 为 undefined。模块包装与作用域Node.js 会将每个模块包装在一个函数中使得每个模块都有独立的作用域。 示例// Node.js 内部将模块包装为类似这样的函数 (function(exports, require, module, __filename, __dirname) { // 模块代码在这里 });这意味着在模块中定义的变量不会污染全局作用域。服务端的模块放在哪里也许你已经注意到我们已经在代码中使用了模块了。像这样var http require(http); ... http.createServer(...);Node.js 中自带了一个叫做http的模块在我们的代码中请求它并把返回值赋给一个本地变量。这把我们的本地变量变成了一个拥有所有 http 模块所提供的公共方法的对象。Node.js 的 require 方法中的文件查找策略如下由于 Node.js 中存在 4 类模块原生模块和3种文件模块尽管 require 方法极其简单但是内部的加载却是十分复杂的其加载优先级也各自不同。如下图所示从文件模块缓存中加载尽管原生模块与文件模块的优先级不同但是都会优先从文件模块的缓存中加载已经存在的模块。从原生模块加载原生模块的优先级仅次于文件模块缓存的优先级。require 方法在解析文件名之后优先检查模块是否在原生模块列表中。以http模块为例尽管在目录下存在一个 http/http.js/http.node/http.json 文件require(http) 都不会从这些文件中加载而是从原生模块中加载。原生模块也有一个缓存区同样也是优先从缓存区加载。如果缓存区没有被加载过则调用原生模块的加载方式进行加载和执行。从文件加载当文件模块缓存中不存在而且不是原生模块的时候Node.js 会解析 require 方法传入的参数并从文件系统中加载实际的文件加载过程中的包装和编译细节在前一节中已经介绍过这里我们将详细描述查找文件模块的过程其中也有一些细节值得知晓。require方法接受以下几种参数的传递http、fs、path等原生模块。./mod或../mod相对路径的文件模块。/pathtomodule/mod绝对路径的文件模块。mod非原生模块的文件模块。在路径 Y 下执行 require(X) 语句执行顺序1. 如果 X 是内置模块 a. 返回内置模块 b. 停止执行 2. 如果 X 以 / 开头 a. 设置 Y 为文件根路径 3. 如果 X 以 ./ 或 / or ../ 开头 a. LOAD_AS_FILE(Y X) b. LOAD_AS_DIRECTORY(Y X) 4. LOAD_NODE_MODULES(X, dirname(Y)) 5. 抛出异常 not found LOAD_AS_FILE(X) 1. 如果 X 是一个文件, 将 X 作为 JavaScript 文本载入并停止执行。 2. 如果 X.js 是一个文件, 将 X.js 作为 JavaScript 文本载入并停止执行。 3. 如果 X.json 是一个文件, 解析 X.json 为 JavaScript 对象并停止执行。 4. 如果 X.node 是一个文件, 将 X.node 作为二进制插件载入并停止执行。 LOAD_INDEX(X) 1. 如果 X/index.js 是一个文件, 将 X/index.js 作为 JavaScript 文本载入并停止执行。 2. 如果 X/index.json 是一个文件, 解析 X/index.json 为 JavaScript 对象并停止执行。 3. 如果 X/index.node 是一个文件, 将 X/index.node 作为二进制插件载入并停止执行。 LOAD_AS_DIRECTORY(X) 1. 如果 X/package.json 是一个文件, a. 解析 X/package.json, 并查找 main 字段。 b. let M X (json main 字段) c. LOAD_AS_FILE(M) d. LOAD_INDEX(M) 2. LOAD_INDEX(X) LOAD_NODE_MODULES(X, START) 1. let DIRSNODE_MODULES_PATHS(START) 2. for each DIR in DIRS: a. LOAD_AS_FILE(DIR/X) b. LOAD_AS_DIRECTORY(DIR/X) NODE_MODULES_PATHS(START) 1. let PARTS path split(START) 2. let I count of PARTS - 1 3. let DIRS [] 4. while I 0, a. if PARTS[I] node_modules CONTINUE b. DIR path join(PARTS[0 .. I] node_modules) c. DIRS DIRS DIR d. let I I - 1 5. return DIRSexports 和 module.exports 的使用如果要对外暴露属性或方法就用exports就行要暴露对象(类似class包含了很多属性和方法)就用module.exports。
延伸阅读

更多相关文章

2026/10/29 2:52:04

cadence快捷键如何添加?cadence快捷键设置?

快捷键如何设置 1、找到安装cadence的SPB_DATA/env路径; 2、在图中位置Env中复制添加funckey快捷键命令; 3、最后关闭allegro pcb,重新打开即可。 快捷键命令 Env中funckey快捷键命令: 命令格式:funckey 快…

2026/10/30 19:55:59

A-Level、IB、AP、OSSD,普高生到底该选哪条路

国际课程不止一种,适配人群差别很大,直接说结论。 A-Level 定位:英国方向主流课程,大考定胜负。 适合:理科强、目标英本的尖子生。 短板:偏科或考试型弱的孩子难出分,一次大考失误代价大。 IB 定…

2026/10/29 9:12:19

AWK文本处理实战:从核心原理到日志分析应用

1. 从文本处理“瑞士军刀”说起:为什么是AWK?如果你在Linux或Unix环境下工作过,哪怕只是偶尔敲敲命令行,大概率都听过grep、sed和awk这三剑客的大名。如果说grep是精准的“搜索器”,sed是高效的“流编辑器”&#xff0…

2026/11/1 2:01:37

1.c++入门篇

1.c中的关键字asmdoifreturntrycontinueautodoubleinlineshorttypedefforbooldynamic_castintsignedtypeidpublicbreakelselongsizeoftypenamethrowcaseenummutablestaticunionwchar_tcatchexplicitnamespacestatic_castunsigneddefaultcharexportnewstructusingfriendclassext…

2026/11/1 2:01:37

《江灯合声》:有可行的分框版,也仍可以选择连续鸣谢

武汉江岸区栎坡合唱团在免费节目册《江灯合声》中,以表格集中鸣谢资助者。各家共同要求改为独立小框,团里仍想保留表格。现有全名与支持事项清楚可见,双方此前未承诺具体排版。我支持保留表格。补充的试排材料让选择更具体:分框能…

2026/11/1 2:01:37

关于“贾子猜想”的数学地位、结构特征与讨论边界

关于“贾子猜想”的数学地位、结构特征与讨论边界摘要 本文对“贾子猜想”进行基于公开表述与现有数学事实的分析。该猜想主张:当正整数 n3m>5(即 n6,9,12,15,…)时,方程x₁ⁿ x₂ⁿ ⋯ xₙⁿ yⁿ不存在正整数解。文章首先…

2026/11/1 2:01:37

启动报Port 8088 was already in use?先查是谁占的

启动报Port 8088 was already in use?先查是谁占的 项目启动报 Port 8088 was already in use,意思很直白:这个端口已经有人占了。 先说原理:端口是"门牌号",一间房只住一个进程 端口就是一台机器上的门牌号…

2026/11/1 2:01:37

担心文档上云?本地运行的办公AI才敢放心用

单位上周开了个会,主题是"AI 提效",散会时领导补了一句:涉及客户资料的文档,不许往云端传。这话一出,会议室里本来跃跃欲试的同事全蔫了——大家平时用的那些在线 AI,文档一上传就不知道存哪儿去…

2026/11/1 1:56:37

华为OD机试真题 新系统 2026-10-28 JavaGoC【社交网络消息转发】

目录 题目 思路 Code 题目 题目内容: 在一个社交网络中,有 N 个用户(编号 0 到 N−1);每个用户都有一个「转发名单」(整数),该数二进制格式中的第 i 位为 1 表示此用户会把消息转发给第 i 个用户。 给定一个整数数组 forwardLists 和一个整数 initialSenders,请…

2026/11/1 0:01:26

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/1 1:01:33

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/1 0:01:26

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/1 1:01:33

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/1 0:01:26

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/1 1:01:33

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑