@adonisjs/assembler

中文文档
8.6.0发布于 2026/10/18MITTypeScriptES Module构建来源已验证近 30 天下载 73万

提供运行AdonisJS开发服务器和建设生产项目的公用事业

中文使用文档
文档目录26 节
  1. 导言
  2. 目标
  3. Dev 服务器
  4. 测试运行器
  5. 使用量
  6. 邦德勒语Name
  7. 使用量
  8. 代码
  9. 使用量
  10. 定义输入
  11. 添加Middleware 到Stack 软件
  12. 更新Rc文件
  13. 添加贾帕普吕金
  14. 添加维特普卢金
  15. 添加政策
  16. 添加变量
  17. 添加范围
  18. 添加模式混合
  19. 添加控制器方法
  20. RcFile 转换器额外方法
  21. 索引生成器
  22. Barrel 文件生成
  23. 类型生成
  24. 捐款
  25. 行为守则
  26. 许可证

@ adonisjs/ 组装器


gh-workflow-image npm-image license-image

导言

阿多尼斯·贾克 Assembler是AdonisJS用于执行类似任务的一个开发工具包 在监视模式下启动 dev 服务器, (中文(简体) ), 在监视模式下运行测试,以及 应用代码 以修改源文件.

Assembler应始终作为发展依赖而安装. 如果您的工程在生产中需要Assembler API, 您必须重新考虑您的方法 .

目标

Assembler围绕以下目标而建.

  • 显示编码接口而不是用户界面。 也就是说,Assembler永远不会暴露任何CLI命令.
  • 在单个 API 下封装任务 。 Assembler不提供十种不同的公用设备来运行一款dev服务器,而是会曝光一个API来运行dev服务器.
  • 拥有AdonisJS所需的所有开发API. 因此,Assembler号的范围可能会随着时间的推移而扩大.

Dev 服务器

开发服务器可以使用 DevServer 课。 它会运行 bin/server.ts 从AdonisJS项目中产生的文件作为一个孩子进程,并监测其变化(无论是HMR模式还是监视模式).

每当有文件更改 DevServer 将执行文件监视器钩钩,如果需要,将重新启动开发服务器.

您可以导入并使用 DevServer 如下所示.

import ts from 'typescript'
import { DevServer } from '@adonisjs/assembler'

const appRoot = new URL('./', import.meta.url)

const devServer = new DevServer(appRoot, {
  /**
   * Arguments to pass to the "bin/server.ts" file
   */
  scriptArgs: [],

  /**
   * Arguments to pass to the Node.js CLI
   */
  nodeArgs: [],

  /**
   * An array of metaFiles to watch and re-start the
   * HTTP server only if the "reloadServer" flag is
   * true.
   */
  metaFiles: [
    {
      pattern: 'resources/views/**/*.edge',
      reloadServer: false,
    }
  ]
})

devServer.onError((error) => {
  process.exitCode = 1
})
devServer.onClose((exitCode) => {
  process.exitCode = exitCode
})

await devServer.runAndWatch(ts)

您可以通过设置启动 HMR 模式的 dev 服务器 hmr: true 并呼唤 start 方法.

const devServer = new DevServer(appRoot, {
  hmr: true,
  // ...rest of the config
})

await devServer.start()

测试运行器

这个 TestRunner 用于执行 bin/test.ts 您的 AdonisJS 应用程序的文档。 喜欢 DevServer,则 TestRunner 允许您查看文件更改并重新运行测试。 现采取以下步骤,以表模式再进行测试.

  • 如果更改的文件是测试文件,则将只重新运行该文件的测试.
  • 否则,所有测试将针对运行时应用的初始过滤器重新运行 node ace test 命令.

使用量

您可以导入并使用 TestRunner 如下所示.

import ts from 'typescript'
import { TestRunner } from '@adonisjs/assembler'

const appRoot = new URL('./', import.meta.url)

const runner = new TestRunner(appRoot, {
  /**
   * Arguments to pass to the "bin/test.ts" file
   */
  scriptArgs: [],

  /**
   * Arguments to pass to the Node.js CLI
   */
  nodeArgs: [],

  /**
   * An array of suites and their glob patterns
   */
  suites: [
    {
      name: 'unit',
      files: ['tests/unit/**/*.spec.ts']
    },
    {
      name: 'functional',
      files: ['tests/functional/**/*.spec.ts']
    }
  ],

  /**
   * Initial set of filters to apply. These filters
   * will be re-applied when re-running tests in
   * watch mode
   */
  filters: {
    suites: ['unit'],
    tags: ['@slow']
  }
})

await runner.runAndWatch(ts)

你可以运行测试 没有监视器使用 run 方法.

await runner.run()

邦德勒语Name

这个 Bundler 用于创建 AdonisJS 应用程序的生产建筑。 现采取以下步骤生成构件.

  • 清理现有建设目录.
  • 使用 JavaScript 构建 tsc (TypeScript的官方编译器).
  • 复制 ace.js 创建文件夹。 由于王牌文件以 .js 扩展名,它不是由 TypeScript 编译器编译的.
  • 复制 package.json 编辑 软件包管理器的锁定文件 您正在使用到 build 文件夹。 此操作仅支持 bun | npm | yarn | pnpm。对于其他捆绑者,您需要手动复制锁文件.
  • 终也.

使用量

您可以导入并使用 Bundler 如下所示.

import ts from 'typescript'
import { Bundler } from '@adonisjs/assembler'

const appRoot = new URL('./', import.meta.url)

const bundler = new Bundler(appRoot, ts, {
  /**
   * Metafiles to copy to the build folder
   */
  metaFiles: [
    {
      pattern: 'resources/views/**/*.edge',
      reloadServer: false,
    }
  ],
})

代码

Assembler还输出了某些代码来修改一个AdonisJS项目的源文件来配置软件包.

代码mods依赖于AdonisJS的默认,如果一个项目不遵循默认,则将不起作用. 这是一个有意的限制,因为我们只有有限的时间来制作与每一个可能的设置相配合的代码.

使用量

您可以导入并使用 Codemods 如下所示.

import { CodeTransformer } from '@adonisjs/assembler/code_transformer'

const appRoot = new URL('./', import.meta.url)

const transformer = new CodeTransformer(appRoot)

定义输入

定义环境变量的验证规则。 该方法接受一对按键值变量. 这个 key 是嵌入变量名称,并且 value 是作为字符串的验证表达式.

[大 此编码器预计 start/env.ts 文件存在且必须拥有 export default await Env.create 方法调用.

另外,代码mod不覆盖给定环境变量的现有验证规则. 这样做是为了尊重应用中的修改.

const transformer = new CodeTransformer(appRoot)

try {
  await transformer.defineEnvValidations({
    leadingComment: 'App environment variables',
    variables: {
      PORT: 'Env.schema.number()',
      HOST: 'Env.schema.string()',
    }
  })
} catch (error) {
  console.error('Unable to define env validations')
  console.error(error)
}

产出

import { Env } from '@adonisjs/core/env'

export default await Env.create(new URL('../', import.meta.url), {
  PORT: Env.schema.number(),
  HOST: Env.schema.string(),
})

添加Middleware 到Stack 软件

将 AdonisJS 中间软件注册到已知的中间软件堆栈中 。 这种方法接受中间软件堆栈和一系列的中间软件来注册.

中间软件堆是其中之一 server | router | named。 。 。 .

[大 此编码器预计 start/kernel.ts 文件要存在,并且必须有一个函数调用中件堆栈,您正试图为此注册中件.

const transformer = new CodeTransformer(appRoot)

try {
  await transformer.addMiddlewareToStack('router', [
    {
      path: '@adonisjs/core/bodyparser_middleware'
    }
  ])
} catch (error) {
  console.error('Unable to register middleware')
  console.error(error)
}

产出

import router from '@adonisjs/core/services/router'

router.use([
  () => import('@adonisjs/core/bodyparser_middleware')
])

您可以定义名为中间软件的如下 .

const transformer = new CodeTransformer(appRoot)

try {
  await transformer.addMiddlewareToStack('named', [
    {
      name: 'auth',
      path: '@adonisjs/auth/auth_middleware'
    }
  ])
} catch (error) {
  console.error('Unable to register middleware')
  console.error(error)
}

更新Rc文件

登记册 providers, (中文(简体) ), commands,定义 metaFiles 财务报告和审定财务报表 commandAliases 页:1 adonisrc.ts 文档.

[大 此编码器预计 adonisrc.ts 要存在的文件, 必须有一个 export default defineConfig 函数调用.

const transformer = new CodeTransformer(appRoot)

try {
  await transformer.updateRcFile((rcFile) => {
    rcFile
      .addProvider('@adonisjs/lucid/db_provider')
      .addCommand('@adonisjs/lucid/commands'),
      .setCommandAlias('migrate', 'migration:run')
  })
} catch (error) {
  console.error('Unable to update adonisrc.ts file')
  console.error(error)  
}

产出

import { defineConfig } from '@adonisjs/core/app'

export default defineConfig({
  commands: [
    () => import('@adonisjs/lucid/commands')
  ],
  providers: [
    () => import('@adonisjs/lucid/db_provider')
  ],
  commandAliases: {
    migrate: 'migration:run'
  }
})

添加贾帕普吕金

将 Japa 插件注册到 tests/bootstrap.ts 文档.

[大 此编码器预计 tests/bootstrap.ts 文件存在且必须拥有 export const plugins: Config['plugins'] 输出.

const transformer = new CodeTransformer(appRoot)

const imports = [
  {
    isNamed: false,
    module: '@adonisjs/core/services/app',
    identifier: 'app'
  },
  {
    isNamed: true,
    module: '@adonisjs/session/plugins/api_client',
    identifier: 'sessionApiClient'
  }
]
const pluginUsage = 'sessionApiClient(app)'

try {
  await transformer.addJapaPlugin(pluginUsage, imports)
} catch (error) {
  console.error('Unable to register japa plugin')
  console.error(error)
}

产出

import app from '@adonisjs/core/services/app'
import { sessionApiClient } from '@adonisjs/session/plugins/api_client'

export const plugins: Config['plugins'] = [
  sessionApiClient(app)
]

添加维特普卢金

将 Vite 插件注册到 vite.config.ts 文档.

[大 此编码器预计 vite.config.ts 文件存在且必须拥有 export default defineConfig 函数调用.

const transformer = new CodeTransformer(appRoot)
const imports = [
  {
    isNamed: false,
    module: '@vitejs/plugin-vue',
    identifier: 'vue'
  },
]
const pluginUsage = 'vue({ jsx: true })'

try {
  await transformer.addVitePlugin(pluginUsage, imports)
} catch (error) {
  console.error('Unable to register vite plugin')
  console.error(error)
}

产出

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

export default defineConfig({
  plugins: [
    vue({ jsx: true })
  ]
})

添加政策

将 AdonisJS 保镖政策登记为 policies 从导出的对象 app/policies/main.ts 文档.

[大 此编码器预计 app/policies/main.ts 文件为存在,必须导出 policies 对象.

const transformer = new CodeTransformer(appRoot)

try {
  await transformer.addPolicies([
    {
      name: 'PostPolicy',
      path: '#policies/post_policy'
    }
  ])
} catch (error) {
  console.error('Unable to register policy')
  console.error(error)
}

产出

export const policies = {
  UserPolicy: () => import('#policies/post_policy')
}

添加变量

创建一个新的验证符文件,或在已有文件中添加验证符 。 如果文件不存在,将随提供的内容创建. 如果它存在,且导出名称尚未定义,则验证符将被附加到文件中.

[大 这个编码器尊重 validators 目录已配置于 adonisrc.ts 默认为 app/validators。 。 。 .

const transformer = new CodeTransformer(appRoot)

try {
  await transformer.addValidator({
    validatorFileName: 'user.ts',
    exportName: 'loginValidator',
    contents: `export const loginValidator = vine.compile(
  vine.object({
    email: vine.string().email(),
    password: vine.string().minLength(8)
  })
)`
  })
} catch (error) {
  console.error('Unable to add validator')
  console.error(error)
}

产出(应用/验证/用户)

export const loginValidator = vine.compile(
  vine.object({
    email: vine.string().email(),
    password: vine.string().minLength(8)
  })
)

添加范围

创建一个新的速率限制文件,或在已有文件中添加限制文件。 如果文件不存在,将随提供的内容创建. 如果存在且导出名称尚未定义, 限制符将附加在文件中 .

[大 在 start 目录已配置于 adonisrc.ts 默认为 start。 。 。 .

const transformer = new CodeTransformer(appRoot)

try {
  await transformer.addLimiter({
    limiterFileName: 'limiters.ts',
    exportName: 'apiThrottle',
    contents: `export const apiThrottle = limiter.define('api', () => {
  return limiter.allowRequests(10).every('1 minute')
})`
  })
} catch (error) {
  console.error('Unable to add limiter')
  console.error(error)
}

产出(启动/限制器.ts)

export const apiThrottle = limiter.define('api', () => {
  return limiter.allowRequests(10).every('1 minute')
})

添加模式混合

将一个或多个混音器应用到模型类中. 这把模型的扩展条款与 compose 帮助和应用指定的混音器.

[大 这个代码mod期望模型文件存在一个默认的导出类,扩展一个基类.

const transformer = new CodeTransformer(appRoot)

try {
  await transformer.addModelMixins('user.ts', [
    {
      name: 'SoftDeletes',
      importPath: '@adonisjs/lucid/orm/mixins/soft_deletes',
      importType: 'named'
    },
    {
      name: 'Sluggable',
      importPath: '#mixins/sluggable',
      importType: 'default',
      args: ['title', '{ strategy: "dbIncrement" }']
    }
  ])
} catch (error) {
  console.error('Unable to add mixins to model')
  console.error(error)
}

投入(应用程序/模型/用户.ts)

import { BaseModel } from '@adonisjs/lucid/orm'

export default class User extends BaseModel {
  // ...
}

产出(应用程序/模型/用户.ts)

import { BaseModel } from '@adonisjs/lucid/orm'
import { compose } from '@adonisjs/core/helpers'
import { SoftDeletes } from '@adonisjs/lucid/orm/mixins/soft_deletes'
import Sluggable from '#mixins/sluggable'

export default class User extends compose(BaseModel, SoftDeletes(), Sluggable(title, { strategy: "dbIncrement" })) {
  // ...
}

添加控制器方法

创建一个新的控制器文件,或者在现有控制器类中添加一个方法. 如果控制器文件不存在,将随类和方法而创建. 如果该方法存在且尚未定义,则该方法会被添加到类中.

[大 这个编码器尊重 controllers 目录已配置于 adonisrc.ts 默认为 app/controllers。 。 。 .

const transformer = new CodeTransformer(appRoot)

try {
  await transformer.addControllerMethod({
    controllerFileName: 'users_controller.ts',
    className: 'UsersController',
    name: 'destroy',
    contents: `async destroy({ params, response }: HttpContext) {
  const user = await User.findOrFail(params.id)
  await user.delete()
  return response.noContent()
}`,
    imports: [
      { isType: false, isNamed: true, name: 'HttpContext', path: '@adonisjs/core/http' },
      { isType: false, isNamed: false, name: 'User', path: '#models/user' }
    ]
  })
} catch (error) {
  console.error('Unable to add controller method')
  console.error(error)
}

输出(应用程序/控制器/用户 控制器.ts)

import type { HttpContext } from '@adonisjs/core/http'
import User from '#models/user'

export default class UsersController {
  async destroy({ params, response }: HttpContext) {
    const user = await User.findOrFail(params.id)
    await user.delete()
    return response.noContent()
  }
}

RcFile 转换器额外方法

这个 RcFileTransformer 类(通过 updateRcFile callback)现在支持额外的进口和钩子管理方法.

添加Named导入

添加一个命名导入到 adonisrc.ts 文档.

const transformer = new CodeTransformer(appRoot)

try {
  await transformer.updateRcFile((rcFile) => {
    rcFile.addNamedImport('@adonisjs/core/types', ['Middleware', 'Provider'])
  })
} catch (error) {
  console.error('Unable to add named import')
  console.error(error)
}

产出

import { defineConfig } from '@adonisjs/core/app'
import { Middleware, Provider } from '@adonisjs/core/types'

export default defineConfig({
  // ...
})

添加默认导入

添加默认导入到 adonisrc.ts 文档.

const transformer = new CodeTransformer(appRoot)

try {
  await transformer.updateRcFile((rcFile) => {
    rcFile.addDefaultImport('#config/database', 'databaseConfig')
  })
} catch (error) {
  console.error('Unable to add default import')
  console.error(error)
}

产出

import { defineConfig } from '@adonisjs/core/app'
import databaseConfig from '#config/database'

export default defineConfig({
  // ...
})

添加 AssemblerHook 语句

添加装配器钩到 adonisrc.ts 文档。 虎克可以被添加为thunk导入(懒活地加载)或者作为直接导入参考的原始值.

const transformer = new CodeTransformer(appRoot)

try {
  await transformer.updateRcFile((rcFile) => {
    // Add a thunk-style hook (lazy import)
    rcFile.addAssemblerHook('onBuildStarting', './commands/build_hook.js')

    // Add a raw hook (direct import reference)
    rcFile.addAssemblerHook('onBuildCompleted', 'buildCompletedHook', true)
  })
} catch (error) {
  console.error('Unable to add assembler hook')
  console.error(error)
}

产出

import { defineConfig } from '@adonisjs/core/app'

export default defineConfig({
  hooks: {
    onBuildStarting: [
      () => import('./commands/build_hook.js')
    ],
    onBuildCompleted: [
      buildCompletedHook
    ]
  }
})

索引生成器

这个 IndexGenerator 是Assembler中的核心概念,用于监视文件系统并从源目录创建桶文件或类型.

例如,框架的核心使用以下配置来生成控制器,事件,以及收听器的管文件.

import hooks from '@adonisjs/assembler/hooks'

export default hooks.init((type, parent, indexGenerator) => {
  indexGenerator.add('controllers', {
    source: './app/controllers',
    importAlias: '#controllers',
    as: 'barrelFile',
    exportName: 'controllers',
    removeSuffix: 'controllers',
    output: './.adonisjs/server/controllers.ts',
  })

  indexGenerator.add('events', {
    source: './app/events',
    importAlias: '#events',
    as: 'barrelFile',
    exportName: 'events',
    output: './.adonisjs/server/events.ts',
  })

  indexGenerator.add('listeners', {
    source: './app/listeners',
    importAlias: '#listeners',
    as: 'barrelFile',
    exportName: 'listeners',
    removeSuffix: 'listener',
    output: './.adonisjs/server/listeners.ts',
  })
})

一旦配置在 IndexGenerator,它将扫描所需的目录并生成输出文件。 此外,当一个文件被添加或从源目录中删除时,文件监视器会重新触发索引生成.

Barrel 文件生成

Barrel文件通过导出从源目录中相继收集的懒惰导入实体的集合,提供一个单一的切入点. 这个 IndexGenerator 通过扫描嵌入目录和生成映射文件结构的导入映射,实现此进程的自动化.

举例来说,如下: controllers 目录结构 :

app/controllers/
├── auth/
│   ├── login_controller.ts
│   └── register_controller.ts
├── blog/
│   ├── posts_controller.ts
│   └── post_comments_controller.ts
└── users_controller.ts

在使用控制器配置处理时 IndexGenerator 生成一个桶文件,反映目录作为嵌入对象的层次,使用资本化文件名作为属性密钥.

export const controllers = {
  auth: {
    Login: () => import('#controllers/auth/login_controller'),
    Register: () => import('#controllers/auth/register_controller'),
  },
  blog: {
    Posts: () => import('#controllers/blog/posts_controller'),
    PostComments: () => import('#controllers/blog/post_comments_controller'),
  },
  Users: () => import('#controllers/users_controller'),
}

类型生成

要生成类型文件, 请注册一个自定义的回调, 引用一个实例 VirtualFileSystem ,并通过 buffer 对象.

收藏以密钥值对表示:

  • 密钥 ——源目录根的相对路径(没有扩展).
  • 数值 - 包含文件对象 importPath, (中文(简体) ), relativePath,以及 absolutePath。 。 。 .
import hooks from '@adonisjs/assembler/hooks'

export default hooks.init((type, parent, indexGenerator) => {
  indexGenerator.add('inertiaPages', {
    source: './inertia/pages',
    as: (vfs, buffer) => {
      buffer.write(`declare module '@adonisjs/inertia' {`).indent()
      buffer.write(`export interface Pages {`).indent()

      const files = vfs.asList()
      Object.keys(files).forEach((filePath) => {
        buffer.write(
          `'${filePath}': InferPageProps<typeof import('${file.importPath}').default>`
        )
      })

      buffer.dedent().write('}')
      buffer.dedent().write('}')
    },
    output: './.adonisjs/server/inertia_pages.d.ts',
  })
})

捐款

AdonisJS的主要目标之一是建立一个充满活力的用户和贡献者社区,他们相信框架的原则.

我们鼓励你读 捐款指南 在对框架作出贡献之前.

行为守则

为确保AdonisJS社区欢迎所有人,请审查并遵守 行为守则。 。 。 .

许可证

AdonisJS Assembler是开源软件,根据该软件许可 麻省理工学院许可证。 。 。 .

版本与发布记录

@adonisjs/assembler 共发布 184 个版本,首次发布于 2019/11/22;过去 12 个月发布了 24 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
8.6.0latest2026/10/1818 天前
8.5.22026/09/231 个月前
8.5.12026/09/042 个月前
8.5.02026/08/192 个月前
8.4.02026/03/307 个月前
8.3.02026/03/267 个月前

其他发布通道:alpha → 3.1.1,beta → 7.8.0-beta.0,next → 8.0.0-next.33。

关于 @adonisjs/assembler 的常见问题

@adonisjs/assembler 是什么?

提供运行AdonisJS开发服务器和建设生产项目的公用事业

如何安装 @adonisjs/assembler?

在项目目录运行 npm install @adonisjs/assembler,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:typescript(^5.0.0 || ^6.0.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@adonisjs/assembler 支持 TypeScript 吗?

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

@adonisjs/assembler 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@adonisjs/assembler 需要什么版本的 Node.js?

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

@adonisjs/assembler 可以商用吗?

@adonisjs/assembler 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@adonisjs/assembler 的下载量有多少?

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

@adonisjs/assembler 还在维护吗?

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