- assert断言
- async_hooks异步钩子
- async_hooks/context异步上下文
- buffer缓冲区
- C++插件
- C/C++插件(使用Node-API)
- C++嵌入器
- child_process子进程
- cluster集群
- CLI命令行
- console控制台
- Corepack核心包
- crypto加密
- crypto/webcrypto网络加密
- debugger调试器
- deprecation弃用
- dgram数据报
- diagnostics_channel诊断通道
- dns域名服务器
- domain域
- Error错误
- events事件触发器
- fs文件系统
- global全局变量
- http超文本传输协议
- http2超文本传输协议2.0
- https安全超文本传输协议
- inspector检查器
- Intl国际化
- module模块
- module/cjsCommonJS模块
- module/esmECMAScript模块
- module/package包模块
- net网络
- os操作系统
- path路径
- perf_hooks性能钩子
- policy安全策略
- process进程
- punycode域名代码
- querystring查询字符串
- readline逐行读取
- repl交互式解释器
- report诊断报告
- stream流
- stream/web网络流
- string_decoder字符串解码器
- test测试
- timers定时器
- tls安全传输层
- trace_events跟踪事件
- tty终端
- url网址
- util实用工具
- v8引擎
- vm虚拟机
- wasi网络汇编系统接口
- worker_threads工作线程
- zlib压缩
Node.js v18.7.0 文档
- Node.js 18.7.0
- ► 目录
-
►
索引
- assert 断言
- async_hooks 异步钩子
- async_hooks/context 异步上下文
- buffer 缓冲区
- C++插件
- C/C++插件(使用Node-API)
- C++嵌入器
- child_process 子进程
- cluster 集群
- CLI 命令行
- console 控制台
- Corepack 核心包
- crypto 加密
- crypto/webcrypto 网络加密
- debugger 调试器
- deprecation 弃用
- dgram 数据报
- diagnostics_channel 诊断通道
- dns 域名服务器
- domain 域
- Error 错误
- events 事件触发器
- fs 文件系统
- global 全局变量
- http 超文本传输协议
- http2 超文本传输协议2.0
- https 安全超文本传输协议
- inspector 检查器
- Intl 国际化
- module 模块
- module/cjs CommonJS模块
- module/esm ECMAScript模块
- module/package 包模块
- net 网络
- os 操作系统
- path 路径
- perf_hooks 性能钩子
- policy 安全策略
- process 进程
- punycode 域名代码
- querystring 查询字符串
- readline 逐行读取
- repl 交互式解释器
- report 诊断报告
- stream 流
- stream/web 网络流
- string_decoder 字符串解码器
- test 测试
- timers 定时器
- tls 安全传输层
- trace_events 跟踪事件
- tty 终端
- url 网址
- util 实用工具
- v8 引擎
- vm 虚拟机
- wasi 网络汇编系统接口
- worker_threads 工作线程
- zlib 压缩
- ► 其他版本
- 文档搜索
- 会员登录
package 包模块#
介绍#
包是由 package.json
文件描述的文件夹树。
包由包含 package.json
文件的文件夹和所有子文件夹组成,直到包含另一个 package.json
文件的下一个文件夹或名为 node_modules
的文件夹。
确定模块系统#
当作为初始输入传入、或者当被 import
语句或 import()
表达式引用时,Node.js 会将以下视为ES 模块:
模块加载器#
Node.js 有两个系统用于解析说明符和加载模块。
package.json 和文件扩展名#
在包中,package.json
"type"
字段定义了 Node.js 应该如何解释 .js
文件。
如果 package.json
文件没有 "type"
字段,则 .js
文件将被视为 CommonJS。
--input-type 标志#
作为参数传给 --eval
(或 -e
),或通过 STDIN
管道传输到 node
的字符串,在设置 --input-type=module
标志时被视为 ES 模块。
确定包管理器#
虽然所有 Node.js 项目在发布后都可以由所有包管理器安装,但他们的开发团队通常需要使用特定的包管理器。 为了使这个过程更容易,Node.js 附带了一个名为 Corepack 的工具,旨在使所有包管理器在您的环境中透明可用,只要您安装了 Node.js
包的入口#
在包的 package.json
文件中,两个字段可以定义包的入口点:"main"
和 "exports"
。
这两个字段都适用于 ES 模块和 CommonJS 模块入口点。
主入口的导出#
当编写新包时,建议使用 "exports"
字段:
子路径的导出#
当使用 "exports"
字段时,可以通过将主入口点视为 "."
子路径来定义自定义子路径以及主入口点:
Extensions in subpaths#
包作者应在其导出中提供扩展 (import 'pkg/subpath.js'
) 或无扩展 (import 'pkg/subpath'
) 子路径。
这确保每个导出的模块只有一个子路径,以便所有依赖项导入相同的一致说明符,使消费者清楚地了解包合同并简化包子路径的完成。
导出的语法糖#
如果 "."
导出是唯一的导出,则 "exports"
字段为这种情况提供了语法糖,即直接的 "exports"
字段值。
子路径的导入#
除了 "exports"
字段之外,还有一个包 "imports"
字段用于创建仅适用于包本身的导入说明符的私有映射。
子路径的模式#
对于具有少量导出或导入的包,我们建议显式地列出每个导出子路径条目。
但是对于具有大量子路径的包,这可能会导致 package.json
膨胀和维护问题。
条件导出#
条件导出提供了一种根据特定条件映射到不同路径的方法。 CommonJS 和 ES 模块导入都支持它们。
嵌套的条件#
除了直接映射,Node.js 还支持嵌套条件对象。
处理用户条件#
运行 Node.js 时,可以使用 --conditions
标志添加自定义用户条件:
社区条件定义#
除了在 Node.js 核心中实现的 "import"
、"require"
、"node"
、"node-addons"
和 "default"
条件之外的条件字符串默认被忽略。
使用名称来引用包#
在一个包中,包的 package.json
"exports"
字段中定义的值可以通过包的名称引用。
例如,假设 package.json
是:
双 CommonJS/ES 模块包#
在 Node.js 中引入对 ES 模块的支持之前,包作者的一种常见模式是在他们的包中包含 CommonJS 和 ES 模块 JavaScript 源代码,其中 package.json
"main"
指定了 CommonJS 入口点,而 package.json
"module"
指定了 ES模块入口点。
这使 Node.js 能够运行 CommonJS 入口点,而构建工具(例如捆绑器)使用 ES 模块入口点,因为 Node.js 忽略(并且仍然忽略)顶层 "module"
字段。
双包的危害#
当应用程序使用提供 CommonJS 和 ES 模块源的包时,如果包的两个版本都被加载,则存在某些错误的风险。
此潜力来自于 const pkgInstance = require('pkg')
创建的 pkgInstance
与 import pkgInstance from 'pkg'
创建的 pkgInstance
(或像 'pkg/module'
这样的替代主路径)不同的事实。
这是“双包风险”,同一包的两个版本可以在同一个运行时环境中加载。
虽然应用程序或包不太可能有意直接加载两个版本,但应用程序加载一个版本而应用程序的依赖项加载另一个版本是很常见的。
这种危险可能发生,因为 Node.js 支持混合 CommonJS 和 ES 模块,并可能导致意外行为。
在避免或最小化危害的同时编写双包#
首先,当一个包同时包含 CommonJS 和 ES 模块源并且这两个源都通过单独的主入口点或导出路径提供以在 Node.js 中使用时,就会发生上一节中描述的危险。
一个包可能被写成任何版本的 Node.js 只接收 CommonJS 源,并且包可能包含的任何单独的 ES 模块源仅用于其他环境,例如浏览器。
这样的包可以被任何版本的 Node.js 使用,因为 import
可以引用 CommonJS 文件;但它不会提供使用 ES 模块语法的任何优点。
方法1:使用 ES 模块封装器#
在 CommonJS 中编写包或将 ES 模块源代码转换为 CommonJS,并创建定义命名导出的 ES 模块封装文件。
使用条件导出, import
使用 ES 模块封装器,require
使用 CommonJS 入口点。
方法2:隔离状态#
package.json
文件可以直接定义单独的 CommonJS 和 ES 模块入口点:
Node.js package.json 字段定义#
本节描述了 Node.js 运行时使用的字段。 其他工具(例如 npm)使用 Node.js 忽略且未在此处记录的其他字段。
"name"
#
"name"
字段定义了你的包名。
发布到 npm 仓库需要满足特定要求的名称。
"main"
#
当通过 node_modules
查找按名称导入时,则 "main"
字段定义了包的入口点。
其值为路径。
"packageManager"
#
"packageManager"
字段定义了在处理当前项目时预期使用的包管理器。
它可以设置为任何支持的包管理器,并确保您的团队使用完全相同的包管理器版本,而无需安装 Node.js 以外的任何其他东西。
"type"
#
"type"
字段定义了 Node.js 用于所有 .js
文件的模块格式,这些 .js
文件将该 package.json
文件作为其最近的父文件。
"exports"
#
"exports"
字段允许定义包的入口点,当通过 node_modules
查找或自引用加载到其自身的名称的名称导入时。
Node.js 12+ 支持它作为 "main"
的替代方案,它可以支持定义子路径导出和条件导出,同时封装内部未导出的模块。
"imports"
#
导入字段中的条目必须是以 #
开头的字符串。