
Composio Node.js ESM 兼容性测试解析composio/core 在 ES Module 环境下的导入可用性验证【免费下载链接】composioComposio powers 1000 toolkits, tool search, context management, authentication, and a sandboxed workbench to help you build AI agents that turn intent into action.项目地址: https://gitcode.com/GitHub_Trending/co/composiocomposio/core是 Composio 的 TypeScript 核心 SDK承载Composio客户端类、OpenAIProvider提供器、AuthScheme认证辅助与各类工具 Schema 转换工具。本文以仓库中的 ts/e2e-tests/runtimes/node/esm-basic/README.md 为主体结合 e2e.test.ts、fixtures/test.mjs 以及 composio/core 的发布配置 与 核心导出入口完整解析这套端到端E2E兼容性测试的设计动机、测试矩阵、fixture 实现与底层原理。读完本文你将理解 ESM 双形态包Dual Package的导入陷阱掌握如何验证 SDK 的「动态导入、具名导入、类实例化、枚举与工具函数导出」是否在多个 Node.js 大版本下稳定可用并能在自己的项目里复刻这套 Docker 隔离的测试模式。为什么需要 ESM 兼容测试从 CommonJS 到 ES Module 的模块标准迁移ESMECMAScript Module是现代 JavaScript 的官方模块标准通过import/export语法提供静态分析友好的模块图。Node.js 自 12 版本起逐步完善 ESM 支持但生态中仍有大量以 CommonJSrequire形态发布的包。对 SDK 类库而言模块形态直接决定用户能否以如下方式消费import(composio/core)动态导入是否抛错import { Composio } from composio/core具名导入是否可用包的 ESM-only 入口点entrypoint能否被模块解析器正确命中。这正是本测试套件存在的原因。从 package.json 可以看到测试包自身声明了type: module其脚本为test:e2e: bun test e2e.test.ts即通过 Bun 测试运行时驱动 Docker 容器执行 ESM 脚本。整个套件要回答的问题非常聚焦在纯 ESM 环境下composio/core是否「开箱即用」。测试套件结构一套「声明 执行 隔离」的三层设计该测试目录虽小却完整覆盖了「测试声明、fixture 执行、运行时隔离」三个层次ts/e2e-tests/runtimes/node/esm-basic/ ├── README.md # 套件说明本文主体文档 ├── package.json # e2e-tests/node-esm-basic 包声明type: module ├── tsconfig.json # 仅编译 e2e.test.tsmoduleResolution: bundler ├── e2e.test.ts # bun:test 测试声明定义断言与版本矩阵 └── fixtures/ └── test.mjs # 独立 .mjs 脚本真正在容器内执行 ESM 导入验证其中 e2e.test.ts 通过e2e-tests/utils提供的e2e(import.meta.url, {...})入口声明测试fixtures/test.mjs 是独立于测试框架的裸 Node 脚本它不依赖 bun:test只依赖 Node 自身的assert模块——这保证被验证的是「用户视角的导入行为」而非测试框架的兼容性。从更宏观的视角看这个套件只是 Composio 庞大运行时矩阵中的一环。在 ts/e2e-tests/README.md 的目录结构中runtimes/node/下并列着cjs-basicNode.js 22 的require(esm)互操作测试、esm-basic、typescript-mjs-import-nodenextTypeScriptmoduleResolution: nodenext测试等runtimes/deno/esm-basic则通过npm:specifier 验证 Deno 环境下的 ESM 导入。可见 ESM 兼容并非孤立的单个测试而是覆盖 Node.js、Deno、Cloudflare Workers 全运行时的系统性工程。测试矩阵三个 Node.js 大版本 Docker 隔离README 明确标注了隔离工具与版本隔离工具DockerNode.js 版本矩阵22.22.3、24.17.0、25.9.0。这三个版本并非随手挑选。toolchain-versions.json 中node数组正是[22.22.3, 24.17.0, 25.9.0]而 ts/e2e-tests/_utils/src/const.ts 将其导入为WELL_KNOWN_NODE_VERSIONS同时附带current指 mise.toml 中锁定的当前 Node 版本。因此该矩阵同时覆盖最低支持版本composio/core的engines.node声明为22.22.3见 ts/packages/core/package.json最新 LTS 之后的偶数版本尚在快速迭代的最新奇数版本。三个大版本同时通过说明 ESM 行为与 Node 版本无关属于包本身的稳定能力。执行时e2e.ts 会从调用者的import.meta.url自动推断工作目录与套件名runner.ts 则负责为每个版本预构建 Docker 镜像、创建卷、运行容器并收集 stdout/stderr。测试还通过WELL_KNOWN_ENV_VARSANTHROPIC_API_KEY、COMPOSIO_API_KEY、COMPOSIO_BASE_URL、OPENAI_API_KEY向容器透传环境变量但本套件并不需要 API Key——它验证的是模块解析与导出形态而非网络行为。十项测试逐一印证 composio/core 的公开导出契约fixtures/test.mjs 是套件的执行核心。它以console.log( Testing ESM compatibility for composio/core...)开头依次执行十项断言任何一项失败都会process.exit(1)全部通过则打印 All ESM compatibility tests passed!并以process.exit(0)结束。下表汇总了 README 中定义的测试清单及 fixture 中的实际断言测试验证内容fixture 中的断言方式动态导入import(composio/core)不抛错try/catch 包裹await import(...)失败即退出Composio 类主类被导出且可构造assert.ok(module.Composio)且typeof functionOpenAIProvider提供器类被导出且可实例化检查导出类型并new OpenAIProvider()AuthScheme认证枚举/辅助类可访问assert.ok(module.AuthScheme)ComposioError错误类被导出assert.ok(module.ComposioError)jsonSchemaToZodSchema工具函数被导出typeof functionconstants常量命名空间可访问assert.ok(module.constants)loggerLogger 实例被导出assert.ok(module.logger)具名导入解构导入可用const { Composio, OpenAIProvider } await import(...)完成标志全部通过打印完成横幅并以 0 退出每一项都对应 ts/packages/core/src/index.ts 中的真实导出语句export { Composio } from ./composio——主类定义于 composio.tsexport { OpenAIProvider } from ./provider/OpenAIProvider——定义于 OpenAIProvider.ts继承自BaseNonAgenticProvider是随 SDK 内置、无需单独安装的默认提供器export { AuthScheme } from ./models/AuthScheme——AuthScheme.ts 中是一个携带OAuth2、OAuth1、API_KEY、BASIC、BEARER_TOKEN、GOOGLE_SERVICE_ACCOUNT等静态工厂方法的类README 中称其为 Auth enum从源码结构看实际是静态方法集合类ComposioError类定义于 errors/ComposioError.ts其下派生出ComposioAuthConfigNotFoundError、ComposioNoAPIKeyError、ComposioFileUploadError等完整错误家族jsonSchemaToZodSchema等函数从 utils/jsonSchema.ts 批量导出export * as constants from ./utils/constants与export { default as logger } from ./utils/logger分别支撑第 8、9 项测试。值得注意的是fixture 对每个导出的检查都是类型级的类必须满足typeof function可new工具函数必须满足typeof function。这说明测试的目标不仅是「符号存在」更是「符号形态正确」——一个被错误包装成对象的类会在new时报错一个被错误打包成 class 的函数会在调用时行为异常。实例化测试的特殊价值不依赖 API Key 的构造验证第 4 项测试专门尝试new composioModule.OpenAIProvider()并断言实例存在。这在模块兼容测试中很有讲究构造提供器实例会触发类的初始化路径继承链、字段初始化、可能的模块级副作用如果 ESM 转换过程中存在循环依赖circular dependency或初始化顺序错误这一项会第一时间暴露。而 OpenAIProvider.ts 的构造函数为空实现仅super()因此实例化不需要任何凭据或网络适合在无密钥的 CI 容器中执行。发布形态与条件导出ESM 兼容的底层支撑ESM 测试能稳定通过根因在于composio/core的发布配置本身就是「ESM-first」的。ts/packages/core/package.json 关键字段如下{ name: composio/core, type: module, engines: { node: 22.22.3 }, main: dist/index.mjs, types: dist/index.d.mts, exports: { .: { types: ./dist/index.d.mts, default: ./dist/index.mjs }, ./experimental: { types: ./dist/experimental/index.d.mts, default: ./dist/experimental/index.mjs } } }其中每一项都直接服务于 ESM 消费场景type: module声明包内.js文件按 ESM 解析main指向.mjs后缀产物dist/index.mjstypes指向配套的.d.mts声明文件保证类型与运行时形态一致exports字段采用条件导出conditional exports按types→default顺序解析。测试所验证的import(composio/core)正是命中.条件的default: ./dist/index.mjs分支包内还针对workerd/edge-light/node等平台提供平台差异化条件导出如./platform/node.mjs、./models/Files.node.mjs说明这套 ESM 导出是面向多运行时统一设计的。正是因为发布产物以.mjs形态存在、且类型声明以.d.mts配套动态导入与具名导入才能「既过运行时、又过类型检查」。而tsconfig.json中moduleResolution: bundler与module: esnext的组合则保证测试源码的导入解析方式贴近现代打包器与 Node 原生 ESM 的行为。如何运行从单套件到全量矩阵README 给出的运行入口是pnpm test:e2e在仓库根目录 package.json 中这条命令被定义为turbo test:e2e --filtere2e-tests/*即通过 Turborepo 并行调度所有e2e-tests/*包的test:e2e脚本。若只想跑 Node.js 运行时矩阵可用pnpm test:e2e:node其定义为turbo test:e2e:node --filtere2e-tests/node-*恰好匹配本套件的包名e2e-tests/node-esm-basic。如需锁定特定 Node 版本可按 ts/e2e-tests/README.md 的说明覆盖环境变量COMPOSIO_E2E_NODE_VERSION22.22.3 pnpm test:e2e:node默认情况下 Node 版本取自 mise.toml 中锁定的current版本。每次执行时runner 会先beforeAll调用runFixture({ filename: test.mjs })超时上限为TIMEOUTS.FIXTURE即 120 秒见 const.ts随后以约 5 秒的默认超时逐项断言输出中是否包含各条✅通过标记。运行成功时的判定链是fixture 退出码为 0 → stdout 含 10 条「Test N passed」→ 含最终「All ESM compatibility tests passed!」横幅。这保证了断言与 fixture 内部逻辑一一对应任何一处回归都会在具体测试项上定位。复刻模式如何为自己的 SDK 编写 ESM 兼容测试从本套件可以提炼出一套可移植的 ESM 兼容验证模式fixture 与框架解耦用纯 Node 的.mjs脚本仅依赖node:assert承载真正的导入验证测试框架只负责断言 fixture 的 stdout 与退出码避免「测试框架兼容性」污染「被测包兼容性」。覆盖动态导入与具名导入两种语法import()动态导入覆盖运行时解析路径解构具名导入覆盖导出命名空间两者缺一不可。对导出符号做类型级断言类检查typeof function函数检查typeof function命名空间只检查存在性并额外实例化无副作用依赖的类。多版本矩阵 容器隔离覆盖最低支持版本、LTS 与最新版三个梯度用 Docker 消除宿主 Node 版本干扰。本仓库用versions: { node: [...] }配置矩阵runner.ts负责逐版本构建镜像与运行。断言与 fixture 输出强绑定每一项断言都对应 fixture 中一条带编号的✅输出失败时可精确定位是哪个导出出了问题。小结ESM 兼容性不是「能不能 import」这么简单它牵涉发布产物的模块形态、条件导出映射、类型声明配套、最低 Node 版本承诺以及多运行时的一致性。ts/e2e-tests/runtimes/node/esm-basic 用一份 88 行的 fixture、一份 73 行的测试声明和三层目录结构把「composio/core在 ESM 环境下十项导出契约均可用」这件事变成了 CI 中可重复验证的硬性承诺。对于任何面向 Node.js 生态发布的 TypeScript SDK这套「fixture 裸脚本 Docker 版本矩阵 stdout 断言」的组合都是一份可以直接借鉴的工程范本。【免费下载链接】composioComposio powers 1000 toolkits, tool search, context management, authentication, and a sandboxed workbench to help you build AI agents that turn intent into action.项目地址: https://gitcode.com/GitHub_Trending/co/composio创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考