生成代码

将你的 monorepo 拆分成包是组织代码、加速任务和改善本地开发体验的好方法。通过 Turborepo 的代码生成功能,你可以轻松地以结构化的方式为包、模块,甚至单个 UI 组件生成新的源代码,并与仓库的其他部分集成。

添加空包

向你的 monorepo 添加一个新的、空的应用或包。

Terminal
turbo gen workspace

查看 gen workspace 的所有可用选项

复制现有包

你可以使用现有的工作空间作为新应用或包的模板。这适用于现有 monorepo 中的工作空间和其他仓库的远程工作空间(通过 GitHub URL 指定)。

示例

通过复制仓库中的现有包来创建新包。

Terminal
turbo gen workspace --copy

通过复制远程包来创建新的工作空间。

Terminal
turbo gen workspace --copy https://github.com/vercel/turborepo/tree/main/examples/with-tailwind/packages/tailwind-config

注意:从远程源添加时,Turborepo 无法验证你的仓库是否具有所有必需的依赖项,以及是否使用了正确的包管理器。在这种情况下,可能需要进行一些手动修改,以使新工作空间在你的仓库中按预期工作。

查看 gen workspace --copy 的所有可用选项

自定义生成器

如果内置生成器不能满足你的需求,你可以使用 Plop 配置创建自己的自定义生成器。 Turborepo 将自动检测仓库中的任何生成器配置,并使其可以从命令行运行。

虽然 Turborepo 生成器是基于 Plop 构建的,但它们不需要在你的仓库中安装 plop 作为依赖项。

虽然 Turborepo 理解所有 Plop 配置选项和功能,但它提供了一些额外的功能来改善在配置了 Turborepo 的仓库中编写生成器的体验。

  1. 生成器会自动被发现、加载并按工作空间组织(无需在单个配置文件中手动 load 它们)
  2. 生成器会自动从定义它们的工作空间的根目录运行
  3. 生成器可以从仓库内的任何位置(或通过 --root 标志从外部)调用
  4. 支持零配置的 TypeScript 生成器
  5. 不需要将 plop 安装为仓库的依赖项

已知问题

自定义生成器目前不支持 ESM 依赖项。

入门

要构建和运行自定义生成器,请在使用 Turborepo 的 monorepo 中的任何位置运行以下命令。

Terminal
turbo gen

系统会提示你选择现有生成器,如果你还没有生成器,则会提示你创建一个。你也可以在仓库根目录或任何工作空间的 turbo/generators/config.ts(或 config.js)手动创建配置。

如果你使用 TypeScript,你需要安装 @turbo/gen 包 作为 devDependency 来访问所需的 TS 类型。

例如,以下示例展示了一个具有三个生成器位置的 monorepo:

package.json
package.json
package.json
package-lock.json
turbo.json

在工作空间中创建的生成器会自动从工作空间根目录运行,而不是 从仓库根目录或生成器配置的位置运行。

这使得你的生成器更容易编写。在 [workspace-root] 创建文件只需要指定为 <file>,而不是 ../../<file>

了解更多关于使用 Plop 创建自定义生成器的信息。

编写生成器

生成器配置文件是一个返回 Plop 配置对象的函数。配置对象用于定义生成器的提示和操作。

最简单的形式下,生成器配置文件如下所示:

turbo/generators/config.ts
import type { PlopTypes } from "@turbo/gen";
 
export default function generator(plop: PlopTypes.NodePlopAPI): void {
  // 创建一个生成器
  plop.setGenerator("生成器名称", {
    description: "生成器描述",
    // 从用户那里收集信息
    prompts: [
      ...
    ],
    // 根据提示执行操作
    actions: [
      ...
    ],
  });
}

提示

提示使用 Plop prompts 编写,用于从用户那里收集信息。

操作

操作可以使用 Plop 内置操作,或者你自己定义的自定义操作函数

turbo/generators/config.ts
import type { PlopTypes } from "@turbo/gen";
 
const customAction: PlopTypes.CustomActionFunction = async (answers) => {
  // 从远程 API 获取数据
  const results = await fetchRemoteData();
  // 将响应添加到 answers 中,使这些数据可用于操作
  answers.results = results;
  // 返回状态字符串
  return '数据获取完成!';
}
 
export default function generator(plop: PlopTypes.NodePlopAPI): void {
  // 创建一个生成器
  plop.setGenerator("生成器名称", {
    description: "生成器描述",
    prompts: [
      ...
    ],
    actions: [
      customAction
      {/* actions 现在可以访问 `answers.results` */}
      ...
    ],
  });
}

运行生成器

一旦你创建了生成器配置文件,你可以跳过选择提示,直接运行指定的生成器:

Terminal
turbo gen [generator-name]

也可以使用 --args 直接将参数传递给生成器提示:

Terminal
turbo gen [generator-name] --args answer1 answer2 ...

查看 Plop 文档中的跳过提示了解更多信息。

查看 gen 的所有可用选项