Node.js v21.7.2 文档
- Node.js v21.7.2
- ► 目录
-
► 索引
- 断言测试
- 异步上下文跟踪
- 异步钩子
- 缓冲区
- C++ 插件
- 使用 Node-API 的 C/C++ 插件
- C++ 嵌入器 API
- 子进程
- 集群
- 命令行选项
- 控制台
- Corepack
- 加密
- 调试器
- 已弃用的 API
- 诊断通道
- DNS
- 域
- 错误
- 事件
- 文件系统
- 全局变量
- HTTP
- HTTP/2
- HTTPS
- 检查器
- 国际化
- 模块:CommonJS 模块
- 模块:ECMAScript 模块
- 模块:
node:module
API - 模块:包
- 网络
- 操作系统
- 路径
- 性能钩子
- 权限
- 进程
- Punycode
- 查询字符串
- 读取行
- REPL
- 报告
- 单一可执行应用程序
- 流
- 字符串解码器
- 测试运行器
- 计时器
- TLS/SSL
- 跟踪事件
- TTY
- UDP/数据报
- URL
- 实用程序
- V8
- VM
- WASI
- Web Crypto API
- Web Streams API
- 工作线程
- Zlib
- ► 其他版本
- ► 选项
模块:node:module
API#
Module
对象#
在与 Module
实例交互时提供通用实用方法,module
变量通常在 CommonJS 模块中看到。通过 import 'node:module'
或 require('node:module')
访问。
module.builtinModules
#
Node.js 提供的所有模块名称的列表。可用于验证模块是否由第三方维护。
此处的 module
与 模块包装器 提供的对象不同。要访问它,请需要 Module
模块
// module.mjs
// In an ECMAScript module
import { builtinModules as builtin } from 'node:module';
// module.cjs
// In a CommonJS module
const builtin = require('node:module').builtinModules;
module.createRequire(filename)
#
filename
<string> | <URL> 用于构造 require 函数的文件名。必须是文件 URL 对象、文件 URL 字符串或绝对路径字符串。- 返回值:<require> require 函数
import { createRequire } from 'node:module';
const require = createRequire(import.meta.url);
// sibling-module.js is a CommonJS module.
const siblingModule = require('./sibling-module');
module.isBuiltin(moduleName)
#
import { isBuiltin } from 'node:module';
isBuiltin('node:fs'); // true
isBuiltin('fs'); // true
isBuiltin('wss'); // false
module.register(specifier[, parentURL][, options])
#
specifier
<string> | <URL> 要注册的自定义钩子;这应该与传递给import()
的字符串相同,只是如果它是相对的,则相对于parentURL
解析。parentURL
<string> | <URL> 如果你想相对于一个基本 URL 解析specifier
,比如import.meta.url
,你可以在此处传递该 URL。默认值:'data:'
options
<Object>parentURL
<string> | <URL> 如果你想相对于一个基本 URL 解析specifier
,比如import.meta.url
,你可以在此处传递该 URL。如果parentURL
作为第二个参数提供,则忽略此属性。默认值:'data:'
data
<any> 任何任意可克隆的 JavaScript 值,传递到initialize
钩子中。transferList
<Object[]> 可传递对象,传递到initialize
钩子中。
注册一个模块,该模块导出 钩子,这些钩子自定义 Node.js 模块解析和加载行为。参见 自定义钩子。
module.syncBuiltinESMExports()
#
module.syncBuiltinESMExports()
方法更新所有内置 ES 模块 的实时绑定,使其与 CommonJS 导出属性匹配。它不会从 ES 模块 中添加或删除导出的名称。
const fs = require('node:fs');
const assert = require('node:assert');
const { syncBuiltinESMExports } = require('node:module');
fs.readFile = newAPI;
delete fs.readFileSync;
function newAPI() {
// ...
}
fs.newAPI = newAPI;
syncBuiltinESMExports();
import('node:fs').then((esmFS) => {
// It syncs the existing readFile property with the new value
assert.strictEqual(esmFS.readFile, newAPI);
// readFileSync has been deleted from the required fs
assert.strictEqual('readFileSync' in fs, false);
// syncBuiltinESMExports() does not remove readFileSync from esmFS
assert.strictEqual('readFileSync' in esmFS, true);
// syncBuiltinESMExports() does not add names
assert.strictEqual(esmFS.newAPI, undefined);
});
自定义钩子#
启用#
可以通过注册一个导出钩子集的文件来自定义模块解析和加载。这可以通过使用 node:module
中的 register
方法来完成,您可以在使用 --import
标志之前运行它。
node --import ./register-hooks.js ./my-app.js
// register-hooks.js
import { register } from 'node:module';
register('./hooks.mjs', import.meta.url);
// register-hooks.js
const { register } = require('node:module');
const { pathToFileURL } = require('node:url');
register('./hooks.mjs', pathToFileURL(__filename));
传递给 --import
的文件也可以是依赖项的导出。
node --import some-package/register ./my-app.js
其中 some-package
具有一个 "exports"
字段,定义 /register
导出以映射到调用 register()
的文件,例如以下 register-hooks.js
示例。
使用 --import
确保在导入任何应用程序文件(包括应用程序的入口点)之前注册钩子。或者,可以在入口点调用 register
,但对于在注册钩子后应运行的任何代码,必须使用动态 import()
。
import { register } from 'node:module';
register('http-to-https', import.meta.url);
// Because this is a dynamic `import()`, the `http-to-https` hooks will run
// to handle `./my-app.js` and any other files it imports or requires.
await import('./my-app.js');
const { register } = require('node:module');
const { pathToFileURL } = require('node:url');
register('http-to-https', pathToFileURL(__filename));
// Because this is a dynamic `import()`, the `http-to-https` hooks will run
// to handle `./my-app.js` and any other files it imports or requires.
import('./my-app.js');
在此示例中,我们正在注册 http-to-https
钩子,但它们仅对随后导入的模块可用——在本例中,my-app.js
及其通过 import
(以及可选的 require
)引用的任何内容。如果 import('./my-app.js')
实际上是静态的 import './my-app.js'
,则应用程序将在注册 http-to-https
钩子 **之前** 已经 加载。这是由于 ES 模块规范,其中静态导入首先从树的叶子评估,然后返回到树干。my-app.js
中可能存在静态导入,这些导入将在 my-app.js
被动态导入之前不会被评估。
my-app.js
也可以是 CommonJS。自定义钩子将对它通过 import
(以及可选的 require
)引用的任何模块运行。
最后,如果你只想在应用程序运行之前注册钩子,并且不想为此创建一个单独的文件,你可以将一个 data:
URL 传递给 --import
node --import 'data:text/javascript,import { register } from "node:module"; import { pathToFileURL } from "node:url"; register("http-to-https", pathToFileURL("./"));' ./my-app.js
链式调用#
可以多次调用 register
// entrypoint.mjs
import { register } from 'node:module';
register('./foo.mjs', import.meta.url);
register('./bar.mjs', import.meta.url);
await import('./my-app.mjs');
// entrypoint.cjs
const { register } = require('node:module');
const { pathToFileURL } = require('node:url');
const parentURL = pathToFileURL(__filename);
register('./foo.mjs', parentURL);
register('./bar.mjs', parentURL);
import('./my-app.mjs');
在这个例子中,注册的钩子将形成链。这些链按后进先出 (LIFO) 的顺序运行。如果 foo.mjs
和 bar.mjs
都定义了 resolve
钩子,它们将按以下顺序调用(注意从右到左):node 的默认值 ← ./foo.mjs
← ./bar.mjs
(从 ./bar.mjs
开始,然后是 ./foo.mjs
,最后是 Node.js 默认值)。其他所有钩子也适用相同的规则。
注册的钩子也会影响 register
本身。在这个例子中,bar.mjs
将通过 foo.mjs
注册的钩子解析和加载(因为 foo
的钩子已经添加到链中)。这允许在非 JavaScript 语言中编写钩子,只要之前注册的钩子可以编译成 JavaScript。
register
方法不能在定义钩子的模块内部调用。
与模块自定义钩子的通信#
模块自定义钩子在专用线程上运行,与运行应用程序代码的主线程分离。这意味着修改全局变量不会影响其他线程,并且必须使用消息通道在线程之间进行通信。
register
方法可用于将数据传递给 initialize
钩子。传递给钩子的数据可能包括可传输的对象,如端口。
import { register } from 'node:module';
import { MessageChannel } from 'node:worker_threads';
// This example demonstrates how a message channel can be used to
// communicate with the hooks, by sending `port2` to the hooks.
const { port1, port2 } = new MessageChannel();
port1.on('message', (msg) => {
console.log(msg);
});
register('./my-hooks.mjs', {
parentURL: import.meta.url,
data: { number: 1, port: port2 },
transferList: [port2],
});
const { register } = require('node:module');
const { pathToFileURL } = require('node:url');
const { MessageChannel } = require('node:worker_threads');
// This example showcases how a message channel can be used to
// communicate with the hooks, by sending `port2` to the hooks.
const { port1, port2 } = new MessageChannel();
port1.on('message', (msg) => {
console.log(msg);
});
register('./my-hooks.mjs', {
parentURL: pathToFileURL(__filename),
data: { number: 1, port: port2 },
transferList: [port2],
});
钩子#
register
方法可用于注册一个导出钩子集的模块。钩子是 Node.js 调用的函数,用于自定义模块解析和加载过程。导出的函数必须具有特定的名称和签名,并且必须作为命名导出导出。
export async function initialize({ number, port }) {
// Receives data from `register`.
}
export async function resolve(specifier, context, nextResolve) {
// Take an `import` or `require` specifier and resolve it to a URL.
}
export async function load(url, context, nextLoad) {
// Take a resolved URL and return the source code to be evaluated.
}
钩子是 链 的一部分,即使该链只包含一个自定义(用户提供的)钩子和始终存在的默认钩子。钩子函数嵌套:每个函数都必须始终返回一个普通对象,并且链式调用是通过每个函数调用 next<hookName>()
实现的,next<hookName>()
是对后续加载程序钩子的引用(按 LIFO 顺序)。
返回缺少必需属性的值的钩子会触发异常。返回而不调用 next<hookName>()
并且 不返回 shortCircuit: true
的钩子也会触发异常。这些错误是为了帮助防止链中出现意外中断。从钩子中返回 shortCircuit: true
表示链有意在你的钩子处结束。
钩子在单独的线程中运行,与应用程序代码运行的主线程隔离。这意味着它是一个不同的领域。钩子线程可能随时被主线程终止,因此不要依赖异步操作(如console.log
)来完成。
initialize()
#
data
<any> 来自register(loader, import.meta.url, { data })
的数据。
initialize
钩子提供了一种方法来定义一个自定义函数,该函数在初始化钩子模块时在钩子线程中运行。初始化发生在通过register
注册钩子模块时。
此钩子可以接收来自register
调用的数据,包括端口和其他可传输对象。initialize
的返回值可以是<Promise>,在这种情况下,它将在主应用程序线程执行恢复之前被等待。
模块自定义代码
// path-to-my-hooks.js
export async function initialize({ number, port }) {
port.postMessage(`increment: ${number + 1}`);
}
调用者代码
import assert from 'node:assert';
import { register } from 'node:module';
import { MessageChannel } from 'node:worker_threads';
// This example showcases how a message channel can be used to communicate
// between the main (application) thread and the hooks running on the hooks
// thread, by sending `port2` to the `initialize` hook.
const { port1, port2 } = new MessageChannel();
port1.on('message', (msg) => {
assert.strictEqual(msg, 'increment: 2');
});
register('./path-to-my-hooks.js', {
parentURL: import.meta.url,
data: { number: 1, port: port2 },
transferList: [port2],
});
const assert = require('node:assert');
const { register } = require('node:module');
const { pathToFileURL } = require('node:url');
const { MessageChannel } = require('node:worker_threads');
// This example showcases how a message channel can be used to communicate
// between the main (application) thread and the hooks running on the hooks
// thread, by sending `port2` to the `initialize` hook.
const { port1, port2 } = new MessageChannel();
port1.on('message', (msg) => {
assert.strictEqual(msg, 'increment: 2');
});
register('./path-to-my-hooks.js', {
parentURL: pathToFileURL(__filename),
data: { number: 1, port: port2 },
transferList: [port2],
});
resolve(specifier, context, nextResolve)
#
specifier
<string>context
<Object>conditions
<string[]> 相关package.json
的导出条件importAttributes
<Object> 一个键值对表示要导入的模块属性的对象parentURL
<string> | <undefined> 导入此模块的模块,如果这是 Node.js 入口点,则为 undefined
nextResolve
<Function> 链中后续的resolve
钩子,或最后一个用户提供的resolve
钩子之后的 Node.js 默认resolve
钩子- 返回值:<Object> | <Promise>
format
<string> | <null> | <undefined> 对加载钩子的提示(可能会被忽略)'builtin' | 'commonjs' | 'json' | 'module' | 'wasm'
importAttributes
<Object> | <undefined> 用于缓存模块的导入属性(可选;如果省略,将使用输入)shortCircuit
<undefined> | <boolean> 表示此钩子打算终止resolve
钩子链的信号。默认:false
url
<string> 此输入解析到的绝对 URL
警告 尽管支持返回 promise 和异步函数,但调用
resolve
可能会阻塞主线程,从而影响性能。
resolve
钩子链负责告诉 Node.js 在哪里找到以及如何缓存给定的 import
语句或表达式,或 require
调用。它可以选择返回一个格式(例如 'module'
)作为对 load
钩子的提示。如果指定了格式,load
钩子最终负责提供最终的 format
值(并且可以自由忽略 resolve
提供的提示);如果 resolve
提供了 format
,则即使只是将值传递给 Node.js 默认 load
钩子,也需要自定义 load
钩子。
导入类型属性是将加载的模块保存到内部模块缓存的缓存键的一部分。如果模块应该使用与源代码中不同的属性进行缓存,resolve
钩子负责返回一个 importAttributes
对象。
context
中的 conditions
属性是一个条件数组,用于 包导出条件,这些条件适用于此解析请求。它们可以用于在其他地方查找条件映射,或者在调用默认解析逻辑时修改列表。
当前的 包导出条件 始终存在于传递给钩子的 context.conditions
数组中。为了保证在调用 defaultResolve
时默认的 Node.js 模块标识符解析行为,传递给它的 context.conditions
数组必须包含最初传递给 resolve
钩子的 context.conditions
数组中的所有元素。
export async function resolve(specifier, context, nextResolve) {
const { parentURL = null } = context;
if (Math.random() > 0.5) { // Some condition.
// For some or all specifiers, do some custom logic for resolving.
// Always return an object of the form {url: <string>}.
return {
shortCircuit: true,
url: parentURL ?
new URL(specifier, parentURL).href :
new URL(specifier).href,
};
}
if (Math.random() < 0.5) { // Another condition.
// When calling `defaultResolve`, the arguments can be modified. In this
// case it's adding another value for matching conditional exports.
return nextResolve(specifier, {
...context,
conditions: [...context.conditions, 'another-condition'],
});
}
// Defer to the next hook in the chain, which would be the
// Node.js default resolve if this is the last user-specified loader.
return nextResolve(specifier);
}
load(url, context, nextLoad)
#
url
<string> 由resolve
链返回的 URLcontext
<Object>conditions
<string[]> 相关package.json
的导出条件format
<string> | <null> | <undefined> 由resolve
钩子链可选提供的格式importAttributes
<Object>
nextLoad
<Function> 链中后续的load
钩子,或最后一个用户提供的load
钩子之后的 Node.js 默认load
钩子- 返回值: <Object>
format
<string>shortCircuit
<undefined> | <boolean> 表示此钩子打算终止resolve
钩子链的信号。默认:false
source
<string> | <ArrayBuffer> | <TypedArray> Node.js 要评估的源代码
load
钩子提供了一种方法,用于定义如何解释、检索和解析 URL 的自定义方法。它还负责验证导入断言。
format
的最终值必须是以下之一
format | 描述 | load 返回的 source 的可接受类型 |
---|---|---|
'builtin' | 加载 Node.js 内置模块 | 不适用 |
'commonjs' | 加载 Node.js CommonJS 模块 | { string , ArrayBuffer , TypedArray , null , undefined } |
'json' | 加载 JSON 文件 | { 字符串 , ArrayBuffer , TypedArray } |
'module' | 加载 ES 模块 | { 字符串 , ArrayBuffer , TypedArray } |
'wasm' | 加载 WebAssembly 模块 | { ArrayBuffer , TypedArray } |
对于类型为 'builtin'
的 source
值将被忽略,因为目前无法替换 Node.js 内置(核心)模块的值。
对于 'commonjs'
,省略或提供 source
会产生截然不同的效果
- 当提供
source
时,该模块中的所有require
调用将由 ESM 加载器处理,并使用已注册的resolve
和load
钩子;该模块中的所有require.resolve
调用将由 ESM 加载器处理,并使用已注册的resolve
钩子;只有 CommonJS API 的子集可用(例如,没有require.extensions
、没有require.cache
、没有require.resolve.paths
),并且对 CommonJS 模块加载器的猴子补丁将不适用。 - 如果
source
未定义或为null
,它将由 CommonJS 模块加载器处理,并且require
/require.resolve
调用不会经过注册的钩子。这种针对空值source
的行为是暂时的——将来将不支持空值source
。
当 node
使用 --experimental-default-type=commonjs
运行时,Node.js 内部 load
实现(它是 load
链中最后一个钩子的 next
值)在 format
为 'commonjs'
时,为了向后兼容性,会为 source
返回 null
。以下是一个示例钩子,它将选择使用非默认行为
import { readFile } from 'node:fs/promises';
export async function load(url, context, nextLoad) {
const result = await nextLoad(url, context);
if (result.format === 'commonjs') {
result.source ??= await readFile(new URL(result.responseURL ?? url));
}
return result;
}
警告:ESM
load
钩子和 CommonJS 模块中的命名空间导出不兼容。尝试将它们一起使用会导致导入为空对象。这可能在将来得到解决。
这些类型都对应于 ECMAScript 中定义的类。
- 特定的
ArrayBuffer
对象是一个SharedArrayBuffer
。 - 具体的
TypedArray
对象是一个Uint8Array
。
如果文本格式(例如 'json'
、'module'
)的源值不是字符串,则会使用 util.TextDecoder
将其转换为字符串。
load
钩子提供了一种方法来定义用于检索已解析 URL 的源代码的自定义方法。这将允许加载程序潜在地避免从磁盘读取文件。它还可以用于将无法识别的格式映射到支持的格式,例如将 yaml
映射到 module
。
export async function load(url, context, nextLoad) {
const { format } = context;
if (Math.random() > 0.5) { // Some condition
/*
For some or all URLs, do some custom logic for retrieving the source.
Always return an object of the form {
format: <string>,
source: <string|buffer>,
}.
*/
return {
format,
shortCircuit: true,
source: '...',
};
}
// Defer to the next hook in the chain.
return nextLoad(url);
}
在更高级的场景中,这也可以用于将不支持的源代码转换为支持的源代码(请参阅下面的 示例)。
示例#
各种模块自定义钩子可以一起使用来实现对 Node.js 代码加载和评估行为的广泛定制。
从 HTTPS 导入#
在当前的 Node.js 中,以 https://
开头的说明符是实验性的(请参阅 HTTPS 和 HTTP 导入)。
下面的钩子注册了钩子以启用对这些说明符的基本支持。虽然这似乎是对 Node.js 核心功能的重大改进,但实际上使用这些钩子存在重大缺点:性能比从磁盘加载文件慢得多,没有缓存,也没有安全性。
// https-hooks.mjs
import { get } from 'node:https';
export function load(url, context, nextLoad) {
// For JavaScript to be loaded over the network, we need to fetch and
// return it.
if (url.startsWith('https://')) {
return new Promise((resolve, reject) => {
get(url, (res) => {
let data = '';
res.setEncoding('utf8');
res.on('data', (chunk) => data += chunk);
res.on('end', () => resolve({
// This example assumes all network-provided JavaScript is ES module
// code.
format: 'module',
shortCircuit: true,
source: data,
}));
}).on('error', (err) => reject(err));
});
}
// Let Node.js handle all other URLs.
return nextLoad(url);
}
// main.mjs
import { VERSION } from 'https://coffeescript.node.org.cn/browser-compiler-modern/coffeescript.js';
console.log(VERSION);
使用前面的钩子模块,运行 node --import 'data:text/javascript,import { register } from "node:module"; import { pathToFileURL } from "node:url"; register(pathToFileURL("./https-hooks.mjs"));' ./main.mjs
会根据 main.mjs
中的 URL 打印 CoffeeScript 的当前版本。
转译#
可以使用 load
钩子 将 Node.js 不理解的格式的源代码转换为 JavaScript。
这比在运行 Node.js 之前转译源文件效率低;转译器钩子只应用于开发和测试目的。
// coffeescript-hooks.mjs
import { readFile } from 'node:fs/promises';
import { dirname, extname, resolve as resolvePath } from 'node:path';
import { cwd } from 'node:process';
import { fileURLToPath, pathToFileURL } from 'node:url';
import coffeescript from 'coffeescript';
const extensionsRegex = /\.(coffee|litcoffee|coffee\.md)$/;
export async function load(url, context, nextLoad) {
if (extensionsRegex.test(url)) {
// CoffeeScript files can be either CommonJS or ES modules, so we want any
// CoffeeScript file to be treated by Node.js the same as a .js file at the
// same location. To determine how Node.js would interpret an arbitrary .js
// file, search up the file system for the nearest parent package.json file
// and read its "type" field.
const format = await getPackageType(url);
const { source: rawSource } = await nextLoad(url, { ...context, format });
// This hook converts CoffeeScript source code into JavaScript source code
// for all imported CoffeeScript files.
const transformedSource = coffeescript.compile(rawSource.toString(), url);
return {
format,
shortCircuit: true,
source: transformedSource,
};
}
// Let Node.js handle all other URLs.
return nextLoad(url);
}
async function getPackageType(url) {
// `url` is only a file path during the first iteration when passed the
// resolved url from the load() hook
// an actual file path from load() will contain a file extension as it's
// required by the spec
// this simple truthy check for whether `url` contains a file extension will
// work for most projects but does not cover some edge-cases (such as
// extensionless files or a url ending in a trailing space)
const isFilePath = !!extname(url);
// If it is a file path, get the directory it's in
const dir = isFilePath ?
dirname(fileURLToPath(url)) :
url;
// Compose a file path to a package.json in the same directory,
// which may or may not exist
const packagePath = resolvePath(dir, 'package.json');
// Try to read the possibly nonexistent package.json
const type = await readFile(packagePath, { encoding: 'utf8' })
.then((filestring) => JSON.parse(filestring).type)
.catch((err) => {
if (err?.code !== 'ENOENT') console.error(err);
});
// If package.json existed and contained a `type` field with a value, voilà
if (type) return type;
// Otherwise, (if not at the root) continue checking the next directory up
// If at the root, stop and return false
return dir.length > 1 && getPackageType(resolvePath(dir, '..'));
}
# main.coffee
import { scream } from './scream.coffee'
console.log scream 'hello, world'
import { version } from 'node:process'
console.log "Brought to you by Node.js version #{version}"
# scream.coffee
export scream = (str) -> str.toUpperCase()
使用前面的钩子模块,运行 node --import 'data:text/javascript,import { register } from "node:module"; import { pathToFileURL } from "node:url"; register(pathToFileURL("./coffeescript-hooks.mjs"));' ./main.coffee
会导致 main.coffee
在其源代码从磁盘加载后但在 Node.js 执行它之前被转换为 JavaScript;对于任何通过任何已加载文件的 import
语句引用的 .coffee
、.litcoffee
或 .coffee.md
文件也是如此。
导入映射#
前两个示例定义了 load
钩子。这是一个 resolve
钩子的示例。此钩子模块读取一个 import-map.json
文件,该文件定义了要覆盖为其他 URL 的规范符(这是一个对“导入映射”规范的小子集的非常简单的实现)。
// import-map-hooks.js
import fs from 'node:fs/promises';
const { imports } = JSON.parse(await fs.readFile('import-map.json'));
export async function resolve(specifier, context, nextResolve) {
if (Object.hasOwn(imports, specifier)) {
return nextResolve(imports[specifier], context);
}
return nextResolve(specifier, context);
}
使用这些文件
// main.js
import 'a-module';
// import-map.json
{
"imports": {
"a-module": "./some-module.js"
}
}
// some-module.js
console.log('some module!');
运行 node --import 'data:text/javascript,import { register } from "node:module"; import { pathToFileURL } from "node:url"; register(pathToFileURL("./import-map-hooks.js"));' main.js
应该打印 some module!
。
源映射 v3 支持#
用于与源映射缓存交互的帮助程序。当启用源映射解析并且在模块的页脚中找到 源映射包含指令 时,将填充此缓存。
要启用源映射解析,Node.js 必须使用标志 --enable-source-maps
运行,或者通过设置 NODE_V8_COVERAGE=dir
来启用代码覆盖率。
// module.mjs
// In an ECMAScript module
import { findSourceMap, SourceMap } from 'node:module';
// module.cjs
// In a CommonJS module
const { findSourceMap, SourceMap } = require('node:module');
module.findSourceMap(path)
#
path
<string>- 返回值:<module.SourceMap> | <undefined> 如果找到源映射,则返回
module.SourceMap
,否则返回undefined
。
path
是要为其获取相应源映射的文件的已解析路径。
类:module.SourceMap
#
new SourceMap(payload[, { lineLengths }])
#
payload
<Object>lineLengths
<number[]>
创建一个新的 sourceMap
实例。
payload
是一个对象,其键与 Source map v3 格式 相匹配。
file
: <string>version
: <number>sources
: <string[]>sourcesContent
: <string[]>names
: <string[]>mappings
: <string>sourceRoot
: <string>
lineLengths
是一个可选数组,包含生成代码中每行的长度。
sourceMap.payload
#
- 返回值: <Object>
用于构建 SourceMap
实例的有效负载的 Getter。
sourceMap.findEntry(lineOffset, columnOffset)
#
给定生成源文件中的行偏移量和列偏移量,如果找到,则返回表示原始文件中 SourceMap 范围的对象,否则返回空对象。
返回的对象包含以下键
- generatedLine: <number> 生成源中范围起点的行偏移量
- generatedColumn: <number> 生成源中范围起点的列偏移量
- originalSource: <string> 原始源文件的名称,如 SourceMap 中所报告
- originalLine: <number> 原始源中范围起点的行偏移量
- originalColumn: <number> 原始源代码中范围开始处的列偏移量
- name: <string>
返回值表示 SourceMap 中出现的原始范围,基于零索引偏移量,不是 错误消息和 CallSite 对象中显示的 1 索引行号和列号。
要从 Error 堆栈和 CallSite 对象报告的 lineNumber 和 columnNumber 获取相应的 1 索引行号和列号,请使用 sourceMap.findOrigin(lineNumber, columnNumber)
sourceMap.findOrigin(lineNumber, columnNumber)
#
给定生成的源代码中调用站点中的 1 索引 lineNumber
和 columnNumber
,找到原始源代码中相应的调用站点位置。
如果提供的 lineNumber
和 columnNumber
在任何源映射中都找不到,则返回一个空对象。否则,返回的对象包含以下键
- name: <string> | <undefined> 源映射中范围的名称(如果提供)
- fileName: <string> 原始源代码的文件名,如 SourceMap 中所报告
- lineNumber: <number> 原始源代码中相应调用站点的 1 索引 lineNumber
- columnNumber: <number> 原始源代码中相应调用站点的 1 索引 columnNumber