@asyncapi/bundler

中文文档
1.1.1发布于 2026/11/02Apache-2.0TypeScriptCommonJS构建来源已验证近 30 天下载 58万

Bundle references from a single AsyncAPI document into a single file.

原始使用文档
文档目录10 节
  1. Overview
  2. Installation
  3. Usage
  4. Dereference of the external references
  5. Option baseDir
  6. Property x-origin
  7. Movement of components to components
  8. Code examples
  9. bundle(files, [options])
  10. Contributors

AsyncAPI Bundler

Github license PR testing - if Node project npm

This package is developed in the AsyncAPI CLI monorepo.

Overview

An official library that lets you bundle/dereference or merge into one your AsyncAPI Documents.

AsyncAPI Bundler can help you if:

your specification file is divided into different smaller files and is using JSON `$ref` property to reference components

# asyncapi.yaml
asyncapi: '2.4.0'
info:
  title: Account Service
  version: 1.0.0
  description: This service is in charge of processing user signups
channels:
  user/signup:
    subscribe:
      message:
        $ref: './messages.yaml#/messages/UserSignedUp'

# messages.yaml
messages:
  UserSignedUp:
    payload:
      type: object
      properties:
        displayName:
          type: string
          description: Name of the user
        email:
          type: string
          format: email
          description: Email of the user

# After combining
asyncapi: 2.4.0
info:
  title: Account Service
  version: 1.0.0
  description: This service is in charge of processing user signups
channels:
  user/signedup:
    subscribe:
      message:
        payload:
          type: object
          properties:
            displayName:
              type: string
              description: Name of the user
            email:
              type: string
              format: email
              description: Email of the user

you have different standalone specification files that define a larger system, see examples here

# signup.yaml
asyncapi: '2.4.0'
info:
  title: Account Service
  version: 1.0.0
  description: This service is in charge of processing user Signup

channels:
  user/signedup:
    subscribe:
      message:
        payload:
          type: object
          properties:
            displayName:
              type: string
            email:
              type: string
              format: email


# login.yaml
asyncapi: '2.4.0'
info:
  title: Account Service
  version: 1.0.0
  description: This service is in charge of processing user signup

channels:
  user/loggenin:
    subscribe:
      message:
        payload:
          type: object
          properties:
            displayName:
              type: string

# After combining
# asyncapi.yaml
asyncapi: '2.4.0'
info:
  title: Account Service
  version: 1.0.0
  description: This service is in charge for processing user authentication

channles:
  user/signedup:
    subscribe:
      message:
        payload:
          type: object
          properties:
            displayName:
              type: string
            email:
              type: string
              format: email
  user/loggedin:
    subscribe:
      message:
        payload:
          type: object
          properties:
            displayName:
              type: string

Installation

npm install @asyncapi/bundler

Usage

AsyncAPI Bundler can be easily used within your JavaScript projects as a Node.js module:

'use strict';

const { writeFileSync } = require('fs');
const bundle = require('@asyncapi/bundler');

async function main() {
  const document = await bundle(['social-media/comments-service/main.yaml'], {
    baseDir: 'example-data',
    xOrigin: true,
  });
  if (document.yml()) {
    console.log(document.yml()); // the complete bundled AsyncAPI document
    writeFileSync('asyncapi.yaml', document.yml()); // the complete bundled AsyncAPI document
  }
}

main().catch(e => console.error(e));

Dereference of the external references

Bundler dereferences the provided AsyncAPI Document to the maximum possible extent, leaving intact only those internal references that MUST be Reference Objects according to the AsyncAPI Specification (thus, should never be dereferenced):

  • AsyncAPI Specification v2.6.0

There are no internal references that MUST be Reference Objects.

  • AsyncAPI Specification v3.0.0

Regexes of internal references that MUST be Reference Objects:

/#\/channels\/.*\/servers/
/#\/operations\/.*\/channel/
/#\/operations\/.*\/messages/
/#\/operations\/.*\/reply\/channel/
/#\/operations\/.*\/reply\/messages/
/#\/components\/channels\/.*\/servers/
/#\/components\/operations\/.*\/channel/
/#\/components\/operations\/.*\/messages/
/#\/components\/operations\/.*\/reply\/channel/
/#\/components\/operations\/.*\/reply\/messages/

Option baseDir

Option baseDir represents the main working directory of the program, "root directory," relatively to which will be resolved all paths of AsyncAPI Documents passed to the Bundler.

Starting from Bundler v0.5.0, option baseDir is reimplemented with changed logic, and Bundler accepts only paths of AsyncAPI Documents, which will be read with readFileSync() internally.

In a nutshell, the process looks like this:

  • Paths of AsyncAPI Documents are passed as 'main.yaml' | './main.yaml' | '../main.yaml' | ['./main.yaml'] | ['main.yaml', 'audio.yaml'], etc.

  • Path/paths are assured to have an Array type with Array.from() to make them iterable.

  • Working directory of the program is changed to the baseDir with process.chdir().

  • And only then are the paths of the AsyncAPI Documents starting to be read from the array the are currently in, one by one, resolving paths and $refs relatively to the baseDir.

Take a look at ./example/bundle-cjs.cjs, which demonstrates working with baseDir and $refs of different levels of nesting.

Property x-origin

Property x-origin is used for origin tracing in Bundler and component naming in Optimizer.

It originated from this comment in a year-long discussion:

The $ref usually also carries a semantical meaning to understand easier what it is (example "$ref : financial-system.yaml#/components/schemas/bankAccountIdentifier"). If the bundling just resolves this ref inline, the semantical meaning of the $ref pointer gets lost and cannot be recovered in later steps. The optimizer would need to invent an artificial component name for the "bankAccountIdentifier" when moving it to the components section.

Thus, property x-origin contains historical values of dereferenced $refs, which are also used by Optimizer to give meaningful names to components it moves through the AsyncAPI Document.

However, if a user doesn't need / doesn't want x-origin properties to be present in the structure of the AsyncAPI Document (values of the x-origin property may leak internal details about how the system described by the AsyncAPI Document is structured,) they can pass { xOrigin: false } (or omit passing xOrigin at all) to the Bundler in the options object.

Movement of components to components

The movement of all AsyncAPI Specification-valid components to the components section of the AsyncAPI Document starting from Bundler v0.5.0 is done by the Optimizer v1.0.0+.

To get in CI/code an AsyncAPI Document, that is dereferenced to its maximum possible extent with all of its components moved to the components section, the original AsyncAPI Document must be run through chain Bundler -> Optimizer.

If Optimizer is not able to find x-origin properties during optimization of the provided AsyncAPI Document, the existing names of components are used as a fallback mechanism, but keep in mind that components' names may lack semantic meaning in this case.

Code examples

TypeScript

import { writeFileSync } from 'fs';
import bundle from '@asyncapi/bundler';

async function main() {
  const document = await bundle(['social-media/comments-service/main.yaml'], {
    baseDir: 'example-data',
    xOrigin: true,
  });
  if (document.yml()) {
    writeFileSync('asyncapi.yaml', document.yml());
  }

main().catch(e => console.error(e));

JavaScript CJS module system

'use strict';

const { writeFileSync } = require('fs');
const bundle = require('@asyncapi/bundler');

async function main() {
  const document = await bundle(['social-media/comments-service/main.yaml'], {
    baseDir: 'example-data',
    xOrigin: true,
  });
  if (document.yml()) {
    writeFileSync('asyncapi.yaml', document.yml());
  }

main().catch(e => console.error(e));

JavaScript ESM module system

'use strict';

import { writeFileSync } from 'fs';
import bundle from '@asyncapi/bundler';

async function main() {
  const document = await bundle(['social-media/comments-service/main.yaml'], {
    baseDir: 'example-data',
    xOrigin: true,
  });
  if (document.yml()) {
    writeFileSync('asyncapi.yaml', document.yml());
  }

main().catch(e => console.error(e)); 

bundle(files, [options])

Kind: global function

ParamTypeDescription
filesstring | Array.<string>

One or more relative/absolute paths to AsyncAPI Documents that should be bundled.

[options]Object
[options.base]string

One relative/absolute path to base object whose properties will be retained.

[options.baseDir]string

One relative/absolute path to directory relative to which paths to AsyncAPI Documents that should be bundled will be resolved.

[options.xOrigin]boolean

Pass true to generate properties x-origin that will contain historical values of dereferenced $refs.

Contributors

Thanks goes to these wonderful people (emoji key):

souvik
souvik

💻 🤔 🎨 👀 🚧 📖
Maciej Urbańczyk
Maciej Urbańczyk

🤔 👀
Mohd Toukir Khan
Mohd Toukir Khan

🚇
MrYugs
MrYugs

📖
Amanpreet Singh Bedi
Amanpreet Singh Bedi

📖
Alexey Vasilevich
Alexey Vasilevich

📖
Viacheslav Turovskyi
Viacheslav Turovskyi

💻 🚇 📖 🚧 👀 🤔
Lukasz Gornicki
Lukasz Gornicki

🚇 👀
Akshat Nema
Akshat Nema

💻
sambhavgupta0705
sambhavgupta0705

💻

This project follows the all-contributors specification. Contributions of any kind welcome!

版本与发布记录

@asyncapi/bundler 共发布 39 个版本,首次发布于 2022/02/07;过去 12 个月发布了 6 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
1.1.1latest2026/11/025 天前
1.1.02026/10/2712 天前
1.0.22026/06/144 个月前
1.0.12026/02/238 个月前
0.6.62025/11/2411 个月前
0.6.52025/11/2411 个月前

关于 @asyncapi/bundler 的常见问题

@asyncapi/bundler 是什么?

Bundle references from a single AsyncAPI document into a single file.

如何安装 @asyncapi/bundler?

在项目目录运行 npm install @asyncapi/bundler,或使用 pnpm add / yarn add / bun add。

@asyncapi/bundler 支持 TypeScript 吗?

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

@asyncapi/bundler 支持 ESM 还是 CommonJS?

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

@asyncapi/bundler 需要什么版本的 Node.js?

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

@asyncapi/bundler 可以商用吗?

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

@asyncapi/bundler 的下载量有多少?

根据 npm 官方下载统计,@asyncapi/bundler 在 2026/10/07 – 2026/11/05 这 30 天内被下载 579,612 次,日均约 19,320 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@asyncapi/bundler 还在维护吗?

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