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
- 查詢字串
- Readline
- 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)
#
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
<字串> | <URL> 要註冊的客製化掛勾;這應該是傳遞給import()
的相同字串,但如果它是相對的,它會相對於parentURL
解析。parentURL
<字串> | <URL> 如果您想相對於基本 URL 解析specifier
,例如import.meta.url
,您可以在此處傳遞該 URL。預設:'data:'
options
<物件>
註冊一個模組,匯出 鉤子,自訂 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
掛鉤,它們會像這樣被呼叫(請注意從右到左):節點預設 ← ./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>()
(後續載入器的掛鉤參考,順序為 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 進入點時為未定義
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
警告儘管支援傳回承諾和非同步函式,呼叫
resolve
仍可能會封鎖主執行緒,這可能會影響效能。
resolve
掛勾鏈負責告知 Node.js 在何處尋找並如何快取給定的 import
陳述式或運算式,或 require
呼叫。它可以選擇傳回格式(例如 'module'
)作為提示提供給 load
掛勾。如果指定格式,load
掛勾最終負責提供最後的 format
值(而且可以忽略 resolve
提供的提示);如果 resolve
提供 format
,則需要自訂 load
掛勾,即使只是將值傳遞給 Node.js 預設的 load
掛勾。
匯入類型屬性是快取已載入模組至內部模組快取的快取金鑰的一部分。如果應該使用與原始碼中存在的屬性不同的屬性快取模組,resolve
掛勾負責傳回 importAttributes
物件。
context
中的 conditions
屬性是適用於此解析要求的 套件匯出條件 條件陣列。它們可用於在其他地方查詢條件對應,或在呼叫預設解析邏輯時修改清單。
目前 套件匯出條件 始終在傳遞給 hook 的 context.conditions
陣列中。若要在呼叫 defaultResolve
時保證預設 Node.js 模組指定符解析行為,傳遞給它的 context.conditions
陣列必須包含最初傳遞給 resolve
hook 的 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
hook 鏈選用提供的格式importAttributes
<Object>
nextLoad
<Function> 鏈中的後續load
hook,或最後一個使用者提供的load
hook 之後的 Node.js 預設load
hook- 傳回:<Object>
format
<string>shortCircuit
<undefined> | <boolean> 此掛勾打算終止resolve
掛勾鏈的訊號。預設值:false
source
<string> | <ArrayBuffer> | <TypedArray> 要由 Node.js 評估的來源
load
鉤子提供一種自訂方法,用來決定如何詮釋、擷取和剖析 URL。它也負責驗證 import 斷言。
format
的最終值必須為下列其中之一
格式 | 說明 | load 傳回的 source 可接受的類型 |
---|---|---|
'builtin' | 載入 Node.js 內建模組 | 不適用 |
'commonjs' | 載入 Node.js CommonJS 模組 | { 字串 , ArrayBuffer , TypedArray , null , undefined } |
'json' | 載入 JSON 檔案 | { 字串 , ArrayBuffer , TypedArray } |
'module' | 載入 ES 模組 | { 字串 , ArrayBuffer , TypedArray } |
'wasm' | 載入 WebAssembly 模組 | { ArrayBuffer , TypedArray } |
'builtin'
類型的 source
值會被忽略,因為目前無法取代 Node.js 內建 (核心) 模組的值。
省略或提供 'commonjs'
的 source
會有非常不同的效果
- 當提供
source
時,此模組的所有require
呼叫都會由已註冊resolve
和load
鉤子的 ESM 載入器處理;此模組的所有require.resolve
呼叫都會由已註冊resolve
鉤子的 ESM 載入器處理;只會提供 CommonJS API 的子集 (例如,沒有require.extensions
、沒有require.cache
、沒有require.resolve.paths
),而且無法在 CommonJS 模組載入器上進行熱修補。 - 如果
source
是未定義或null
,它會由 CommonJS 模組載入器處理,而require
/require.resolve
呼叫不會通過已註冊的鉤子。此 nullishsource
行為是暫時的 — 未來將不支援 nullishsource
。
當 node
以 --experimental-default-type=commonjs
執行時,Node.js 內部的 load
實作,也就是 load
鏈中最後一個鉤子的 next
值,會在 format
為 'commonjs'
時,為了向後相容而傳回 null
給 source
。以下是一個範例鉤子,用於選擇使用非預設行為
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.dev.org.tw/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 的目前版本。
轉譯#
Node.js 無法理解的格式的來源可以使用 load
掛鉤 轉換成 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 支援#
與來源地圖快取互動的輔助函式。當啟用來源地圖剖析,且在模組的頁尾找到 來源地圖包含指令 時,就會填入此快取。
若要啟用來源地圖剖析,必須使用旗標 --enable-source-maps
執行 Node.js,或透過設定 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
<字串>- 傳回:<module.SourceMap> | <未定義> 如果找到來源地圖,傳回
module.SourceMap
,否則傳回undefined
。
path
是應擷取對應來源地圖的檔案之已解析路徑。
類別:module.SourceMap
#
new SourceMap(payload[, { lineLengths }])
#
建立一個新的 sourceMap
實例。
payload
是包含符合 Source map v3 格式 的金鑰的物件
file
: <string>version
: <number>sources
: <string[]>sourcesContent
: <string[]>names
: <string[]>mappings
: <string>sourceRoot
: <string>
lineLengths
是產生程式碼中每一行長度的陣列,為選用項目。
sourceMap.payload
#
- 傳回:<Object>
取得用於建構 SourceMap
實例的 payload。
sourceMap.findEntry(lineOffset, columnOffset)
#
針對產生來源檔案中的行偏移量和欄偏移量,傳回一個物件,如果找到,則表示原始檔案中的 SourceMap 範圍,如果找不到,則傳回一個空物件。
傳回的物件包含下列金鑰
- generatedLine: <數字> 範圍開始時在產生來源中的行偏移量
- generatedColumn: <數字> 範圍開始時在產生來源中的行偏移量
- originalSource: <字串> 原始來源的檔案名稱,如 SourceMap 中所報告
- originalLine: <數字> 範圍開始時在原始來源中的行偏移量
- originalColumn: <數字> 範圍開始時在原始來源中的行偏移量
- name: <字串>
傳回的值表示 SourceMap 中出現的原始範圍,根據以 0 為起始的偏移量,而非錯誤訊息和 CallSite 物件中出現的 1 為起始的行號和欄號。
若要從 lineNumber 和 columnNumber(如錯誤堆疊和 CallSite 物件所報告)取得對應的 1 為起始的行號和欄號,請使用 sourceMap.findOrigin(lineNumber, columnNumber)
sourceMap.findOrigin(lineNumber, columnNumber)
#
給定產生來源中呼叫站點的 1 為起始的 lineNumber
和 columnNumber
,找出原始來源中對應的呼叫站點位置。
如果在任何來源地圖中找不到提供的 lineNumber
和 columnNumber
,則傳回一個空物件。否則,傳回的物件包含下列金鑰