Plop与Drizzle ORM:TypeScript ORM的代码生成自动化

Plop与Drizzle ORM:TypeScript ORM的代码生成自动化

【免费下载链接】plop Consistency Made Simple 【免费下载链接】plop 项目地址: https://gitcode.com/gh_mirrors/pl/plop

你是否还在手动编写TypeScript ORM的模型定义和数据库迁移文件?是否因团队成员创建数据模型时格式不一致而头疼?本文将展示如何通过Plop与Drizzle ORM的组合,实现TypeScript ORM代码的自动化生成,让你专注于业务逻辑而非重复劳动。

读完本文后,你将能够:

  • 使用Plop创建Drizzle ORM模型的自动化生成器
  • 通过命令行快速生成标准化的数据模型文件
  • 配置模板实现团队统一的数据模型规范
  • 结合Plop的交互能力定制代码生成流程

为什么需要代码生成自动化?

在现代TypeScript后端开发中,Drizzle ORM以其类型安全、SQL友好的API和零依赖特性受到越来越多开发者的青睐。然而,手动创建和维护Drizzle模型文件仍然是一项繁琐且容易出错的工作。

Plop作为一个微型生成器框架,能够帮助团队创建具有统一格式的文件。通过结合Plop和Drizzle ORM,我们可以:

  • 减少重复劳动,提高开发效率
  • 确保团队遵循一致的数据模型规范
  • 降低手动编写代码时的错误率
  • 快速适应数据模型的变化

plop demo

Plop是一个微型生成器框架,它使整个团队能够轻松创建具有统一格式的文件。项目主页

准备工作

安装必要依赖

首先,确保你的项目中已经安装了Plop和Drizzle ORM的相关依赖:

# 安装Plop(本地和全局)
npm install --save-dev plop
npm install -g plop

# 安装Drizzle ORM核心包和数据库驱动(以PostgreSQL为例)
npm install drizzle-orm pg
npm install --save-dev drizzle-kit

项目结构准备

建议的项目结构如下,我们将在后续步骤中创建相关文件:

project-root/
├── plopfile.js          # Plop配置文件
├── plop-templates/      # 代码模板目录
│   └── drizzle-model.hbs # Drizzle模型模板
├── src/
│   └── db/
│       ├── schema/      # Drizzle模型文件目录
│       └── index.ts     # 数据库连接配置
└── drizzle.config.ts    # Drizzle配置文件

创建Plop生成器

初始化Plop配置文件

在项目根目录创建plopfile.js,这是Plop的核心配置文件:

// plopfile.js
export default function (plop) {
  // 创建Drizzle模型生成器
  plop.setGenerator("drizzle-model", {
    description: "生成Drizzle ORM数据模型文件",
    prompts: [
      {
        type: "input",
        name: "modelName",
        message: "请输入模型名称( PascalCase 格式,如User)",
        validate: (value) => {
          if (/^[A-Z][a-zA-Z0-9]*$/.test(value)) return true;
          return "模型名称必须是PascalCase格式(首字母大写,无空格和特殊字符)";
        }
      },
      {
        type: "input",
        name: "tableName",
        message: "请输入数据库表名(snake_case格式,如users)",
        validate: (value) => {
          if (/^[a-z_][a-z0-9_]*$/.test(value)) return true;
          return "表名必须是snake_case格式(小写字母、数字和下划线)";
        }
      },
      {
        type: "confirm",
        name: "hasTimestamps",
        message: "是否添加createdAt和updatedAt字段?",
        default: true
      }
    ],
    actions: [
      {
        type: "add",
        path: "src/db/schema/{{dashCase modelName}}.ts",
        templateFile: "plop-templates/drizzle-model.hbs",
        skipIfExists: true
      }
    ]
  });
}

创建Drizzle模型模板

在项目根目录创建plop-templates文件夹,并在其中创建drizzle-model.hbs模板文件:

// src/db/schema/{{dashCase modelName}}.ts
import { pgTable, serial, text, timestamp } from 'drizzle-orm/pg-core';

export const {{camelCase modelName}}Table = pgTable('{{tableName}}', {
  id: serial('id').primaryKey(),
  
  {{#if hasTimestamps}}
  createdAt: timestamp('created_at').defaultNow(),
  updatedAt: timestamp('updated_at').defaultNow().$onUpdate(() => new Date()),
  {{/if}}
});

export type {{modelName}} = typeof {{camelCase modelName}}Table.$inferSelect;
export type New{{modelName}} = typeof {{camelCase modelName}}Table.$inferInsert;

使用生成器创建模型

现在,你可以通过以下命令启动Plop生成器:

plop drizzle-model

Plop会引导你完成几个简单的问题:

? 请输入模型名称( PascalCase 格式,如User) Product
? 请输入数据库表名(snake_case格式,如users) products
? 是否添加createdAt和updatedAt字段? Yes

回答完成后,Plop将自动创建文件src/db/schema/product.ts

// src/db/schema/product.ts
import { pgTable, serial, timestamp } from 'drizzle-orm/pg-core';

export const productTable = pgTable('products', {
  id: serial('id').primaryKey(),
  
  createdAt: timestamp('created_at').defaultNow(),
  updatedAt: timestamp('updated_at').defaultNow().$onUpdate(() => new Date()),
});

export type Product = typeof productTable.$inferSelect;
export type NewProduct = typeof productTable.$inferInsert;

高级定制:添加字段交互

为了使生成器更强大,我们可以扩展Plop配置,允许交互式地添加模型字段:

// plopfile.js(部分代码,仅展示修改部分)
prompts: [
  // ... 之前的prompt保持不变 ...
  
  {
    type: "confirm",
    name: "addFields",
    message: "是否现在添加字段?",
    default: true
  },
  {
    type: "loop",
    name: "fields",
    message: "添加字段",
    when: (answers) => answers.addFields,
    props: [
      {
        type: "input",
        name: "name",
        message: "字段名(camelCase)",
        validate: (value) => {
          if (/^[a-z][a-zA-Z0-9]*$/.test(value)) return true;
          return "字段名必须是camelCase格式";
        }
      },
      {
        type: "list",
        name: "type",
        message: "字段类型",
        choices: [
          { name: "文本 (text)", value: "text" },
          { name: "短文本 (varchar)", value: "varchar" },
          { name: "整数 (integer)", value: "integer" },
          { name: "布尔值 (boolean)", value: "boolean" },
          { name: "浮点数 (float)", value: "float" },
          { name: "日期时间 (timestamp)", value: "timestamp" }
        ]
      },
      {
        type: "confirm",
        name: "isRequired",
        message: "是否必填?",
        default: true
      },
      {
        type: "confirm",
        name: "isUnique",
        message: "是否唯一?",
        default: false
      }
    ],
    separator: "----------------------",
    loopMessage: "是否添加另一个字段?"
  }
]

同时更新模板文件以支持动态字段:

// plop-templates/drizzle-model.hbs(部分代码)
export const {{camelCase modelName}}Table = pgTable('{{tableName}}', {
  id: serial('id').primaryKey(),
  
  {{#each fields}}
  {{name}}: {{type}}('{{snakeCase name}}')
    {{#if isRequired}}.notNull(){{/if}}
    {{#if isUnique}}.unique(){{/if}},
  {{/each}}
  
  {{#if hasTimestamps}}
  createdAt: timestamp('created_at').defaultNow(),
  updatedAt: timestamp('updated_at').defaultNow().$onUpdate(() => new Date()),
  {{/if}}
});

集成Drizzle迁移

为了使工作流更加完整,我们可以添加一个生成迁移文件的Plop生成器:

// plopfile.js(添加新的生成器)
plop.setGenerator("drizzle-migration", {
  description: "生成Drizzle迁移文件并运行迁移",
  prompts: [
    {
      type: "input",
      name: "migrationName",
      message: "请输入迁移名称(简短描述,如add-user-table)",
      validate: (value) => value.trim() !== "" || "迁移名称不能为空"
    }
  ],
  actions: [
    {
      type: "shell",
      command: "npx drizzle-kit generate:pg --name {{migrationName}}",
      message: "生成迁移文件"
    },
    {
      type: "confirm",
      name: "runMigration",
      message: "是否立即运行迁移?",
      default: true
    },
    {
      type: "shell",
      command: "npx drizzle-kit migrate",
      message: "运行数据库迁移",
      when: (answers) => answers.runMigration
    }
  ]
});

使用技巧与最佳实践

1. 添加常用字段预设

你可以扩展生成器,添加预设字段集(如用户模型预设包含name、email、password等字段),进一步提高效率。

2. 模型关系生成

对于复杂项目,可以创建生成模型关系的Plop生成器,自动处理外键和关联关系。

3. 团队共享模板

将Plop配置和模板纳入版本控制,确保团队成员使用统一的代码生成标准。

4. 结合Drizzle Studio

使用Drizzle Studio可视化管理数据库模式,并通过Plop生成器保持代码与数据库结构同步:

npx drizzle-kit studio

总结

通过Plop与Drizzle ORM的结合,我们实现了数据模型代码的自动化生成,这不仅提高了开发效率,还确保了代码风格的一致性。这种方法特别适合团队协作和大型项目,能够显著减少重复劳动和人为错误。

关键收获:

  • Plop提供了强大的交互式代码生成能力,通过简单配置即可创建自定义生成器
  • Drizzle ORM的类型安全特性与代码生成结合,大幅降低了手动编写模型的出错风险
  • 自动化代码生成确保了团队遵循统一的数据模型规范
  • 通过扩展生成器和模板,可以满足不同项目的特定需求

建议进一步探索Plop的高级功能,如自定义操作类型、生命周期钩子和模板助手函数,以及Drizzle ORM的查询优化和迁移策略,打造更完善的数据库开发工作流。

更多Plop使用技巧,请参考官方文档。Drizzle ORM的详细用法,请查阅Drizzle ORM官方文档

【免费下载链接】plop Consistency Made Simple 【免费下载链接】plop 项目地址: https://gitcode.com/gh_mirrors/pl/plop

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值