import-in-the-middle

中文文档
3.5.3发布于 2026/10/26Apache-2.0TypeScriptCommonJS构建来源已验证近 30 天下载 3.3亿

在节点.js中拦截进口

中文使用文档
文档目录8 节
  1. 使用量
  2. 只截取钩状模块
  3. 发展基准
  4. 同步加载车钩
  5. 自定义匹配 shouldInclude
  6. 选择退出 CJS 源代码
  7. 类型脚本模块
  8. 限制

导入中

import-in-the-middle 是一个模块加载拦截器,灵感来自 require-in-the-middle不过 具体针对无害环境管理模块。 事实上,它甚至可以在装入后修改模块 时间.

使用量

API 为 require-in-the-middle 尽可能密切跟踪默认 输出。 有低级的 addHook 财务报告和审定财务报表 removeHook 现有出口 不对模块进行任何过滤, 并将完整文件 URL 作为参数显示 到钩上。 请参看详细 API 文档的 Typescription 定义文件 .

您可以修改从任何给定的无害环境管理或CJS模块中导出的任何内容 进口到无害环境管理文件中,无论它们是静态进口还是 充满活力.

import { Hook } from 'import-in-the-middle'
import { foo } from 'package-i-want-to-modify'

console.log(foo) // whatever that module exported

Hook(['package-i-want-to-modify'], (exported, name, baseDir) => {
  // `exported` is effectively `import * as exported from ${url}`
  exported.foo += 1
})

console.log(foo) // 1 more than whatever that module exported

这需要使用无害环境管理装载机钩,可添加如下内容: 命令行选项.

node --loader=import-in-the-middle/hook.mjs my-app.mjs

自兹 --loader 您也可以通过节点程序注册装入器钩 module.register() API (英语). 然而,为了能够钩住非动态进口商品,必须 在您的应用程序代码通过 --import 命令行选项.

my-loader.mjs

import * as module from 'module'

module.register('import-in-the-middle/hook.mjs', import.meta.url)
node --import=./my-loader.mjs ./my-code.mjs

在程序上注册装车钩时,可以通过列表 模块、文件 URL 或正则表达式 exclude 或特别 include 哪些模块被截取。 如果模块不可用, 则此功能将有所帮助 兼容装入器钩.

说明: 此特性与 {internals: true} 钩子选项

import * as module from 'module'

// Exclude intercepting a specific module by name
module.register('import-in-the-middle/hook.mjs', import.meta.url, {
  data: { exclude: ['package-i-want-to-exclude'] }
})

// Only intercept a specific module by name
module.register('import-in-the-middle/hook.mjs', import.meta.url, {
  data: { include: ['package-i-want-to-include'] }
})

只截取钩状模块

说明: 这个特征是实验性的,不符合 {internals: true} 钩子选项

如果你是的话 Hook“在导入所有模块之前进行,例如: 通过节点.js装入的模块 --import CLI 参数, 您可以配置 装入器只截取被锁定的模块 .

instrument.mjs

import { register } from 'module'
import { Hook, createAddHookMessageChannel } from 'import-in-the-middle'

const { registerOptions, waitForAllMessagesAcknowledged } = createAddHookMessageChannel()

register('import-in-the-middle/hook.mjs', import.meta.url, registerOptions)

Hook(['fs'], (exported, name, baseDir) => {
  // Instrument the fs module
})

// Ensure that the loader has acknowledged all the modules
// before we allow execution to continue
await waitForAllMessagesAcknowledged()

my-app.mjs

import * as fs from 'fs'
// fs will be instrumented!
fs.readFileSync('file.txt')
node --import=./instrument.mjs ./my-app.mjs

发展基准

见 基准/README.md pR基准方法 如何在当地检查测量噪音.

同步加载车钩

在支持的节点.js版本上 module.registerHooks() 装载器可以运行 同步,在应用程序线索上,而不是在 独立线程 module.register() 用户。 运行内行删除 消息频道 : Hook() 登记器直接可见,所以 页:1 createAddHookMessageChannel 编号 : waitForAllMessagesAcknowledged 显示步骤 上文已无必要.

module.registerHooks() 在22.15.0/24.0.0中添加,但其同步负载 钩子拒绝了无效的普通JS source 装入器返回 require()编号 进入无害环境管理图,直到 节点/节点# 59929。运入的固定器 22.22.3、24.11.1、25.1.0和26.0.0; 早先的版本飞船 module.registerHooks() 但不能运行同步加载器。 使用 supportsSyncHooks() 以切换到此选项, 而不是手写版本检查 :

import { register, supportsSyncHooks } from 'import-in-the-middle/register-hooks.mjs'

if (supportsSyncHooks()) {
  register({ include: ['package-i-want-to-include'] })
} else {
  // Fall back to the asynchronous loader, e.g. module.register('import-in-the-middle/hook.mjs').
}

instrument.mjs

import { register } from 'import-in-the-middle/register-hooks.mjs'
import { Hook } from 'import-in-the-middle'

register({ include: ['package-i-want-to-include'] })

Hook(['package-i-want-to-include'], (exported, name, baseDir) => {
  // Instrument the module
})
node --import=./instrument.mjs ./my-app.mjs

register() 接受相同的建议 include 编号 : exclude 选项为同步 加载器和投放到一个节点.js版本中 supportsSyncHooks() 实值 false。 。 。 .

自定义匹配 shouldInclude

改为 include 编号 : exclude 列表,您可以通过 shouldInclude(url, specifier) 以决定哪些模块被截取 。 它要求每一个决心 模块,包含已解析的 URL 和导入指定符;返回一个真实值到 截取模块。 如果上游地区接管裁决 页:1 include 编号 : exclude 选项被忽略.

当匹配不清晰地映射到光谱、文件 URL 和 正则表达式——例如自配置构建的匹配器,或 取决于比说明者更多的决定.

import { register } from 'import-in-the-middle/register-hooks.mjs'

register({
  shouldInclude (url, specifier) {
    return specifier === 'package-i-want-to-include' ||
      url.includes('/node_modules/some-scope/')
  }
})

上游只接收到URL和指定符,从没有解析出的文件路径. 因为 module.register() 转让 data 按结构排列到装入器线索 克隆——不能承担一个函数—— shouldInclude 支持同步 登记register-hooks.mjs上表所示),并用于构造于 装入器线程; 无法通过 data 同步选项 module.register('import-in-the-middle/hook.mjs', ...)。 。 。 .

选择退出 CJS 源代码

在节点22+上,当一个CJS模块通过无害环境管理翻译器和另一个模块被装入时 加载车钩提供了它的源(而不是离开它) null 将节点改为 土生土长, require() 调用 CJS 模块内使用 "module-sync" 输出条件失败 ERR_VM_MODULE_LINK_FAILURE工作时 围绕这个节点错误, import-in-the-middle 条形钩提供源 同步中的 CJS 模块需要链条, 强制节点使用其本地 CJS 正确处理这个的加载器 .

如果依靠下游装船钩看到(并采取行动) CJS 模块在要求链中,您可以通过通过 disableCjsSourceStripping: true 在钩子配置。 继续工作 默认启用.

import { register } from 'import-in-the-middle/register-hooks.mjs'

register({
  include: ['package-i-want-to-include'],
  disableCjsSourceStripping: true
})

此选项为两个同步器所接受( S)register-hooks.mjs和 同步( a)module.register('import-in-the-middle/hook.mjs', ...)登记.

类型脚本模块

在 Node.js 版本上, 以本地方式剥取 TypeScript 类型( 那些曝光) module.stripTypeScriptTypes(), (中文(简体) ),

= 22.13.0 / = 23.9.0 / = 24.0.0), (中文(简体) ), import-in-the-middle 拦截 .ts, (中文(简体) ), .mts 财务报告和审定财务报表 .cts 模块,就像他们的 JavaScript 对等。 这些类型是: 在读取模块导出前剥离, 所以只类型导出 (单位:千美元)export type, (中文(简体) ), export interface) 被拦截者不在 名称空间; 值导出为 .

// math.mts
export type Op = '+' | '-'
export function add (a: number, b: number): number {
  return a + b
}
Hook(['./math.mts'], (exported) => {
  // `exported.add` is interceptable; the `Op` type is not part of the namespace
})

在默认无法启用类型剥取的Node.js版本上,以 --experimental-strip-types。更早的版本 module.stripTypeScriptTypes() 保留类型脚本模块.

限制

  • 您无法在模块中添加新导出 。 您只能修改已有的 .
  • 对模块导出绑定时,如果修改为 钩,动态导入的模块被装入后不能被更改.
  • 模块通过 require 完全没有受到影响.
  • 一个模块的导出集 名称 被假定为终生稳定 过程. import-in-the-middle 读取模块的源头一次 输出和再利用将导出设定为同一 URL 的后期负载。 一个上游 返回 a 的加载器 各类出口 相同 URL 的呼叫 – 状态的编码加载器,或其输出变化为 context 已经.. 不支持,并且将使用第一个出口集的设备 装入。 异能变换(取出型号、AST仪器、变异器) 不受影响, 而实际模块仍然执行源其实际负载 返回; 只有可截取导出 名称 被纪念.

版本与发布记录

import-in-the-middle 共发布 65 个版本,首次发布于 2021/08/19;过去 12 个月发布了 20 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
3.5.3latest2026/10/2610 天前
3.5.22026/10/011 个月前
3.5.12026/09/111 个月前
3.5.02026/09/091 个月前
3.4.02026/08/312 个月前
3.3.32026/08/013 个月前

关于 import-in-the-middle 的常见问题

import-in-the-middle 是什么?

在节点.js中拦截进口

如何安装 import-in-the-middle?

在项目目录运行 npm install import-in-the-middle,或使用 pnpm add / yarn add / bun add。

import-in-the-middle 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

import-in-the-middle 支持 ESM 还是 CommonJS?

以 CommonJS 形式发布,可以直接 require();在 ES Module 项目中也可以用 import 引入(Node.js 会把 module.exports 作为默认导出)。

import-in-the-middle 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=18。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

import-in-the-middle 可以商用吗?

import-in-the-middle 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

import-in-the-middle 的下载量有多少?

根据 npm 官方下载统计,import-in-the-middle 在 2026/10/05 – 2026/11/03 这 30 天内被下载 330,821,495 次,日均约 11,027,383 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

import-in-the-middle 还在维护吗?

最新版本 3.5.3 发布于 2026/10/26(10 天前);至今共发布 65 个版本,其中过去 12 个月发布了 20 个;首次发布于 2021/08/19。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。