构建器模式 (Builder)
Trae 插件的构建器模式是一个强大的功能,可以帮助您快速生成项目结构、创建文件模板,并自动化常见的开发任务。本指南将详细介绍如何使用构建器功能来提高开发效率。
什么是构建器模式
构建器模式是 Trae 插件中的一个智能代码生成系统,它可以:
- 🏗️ 快速搭建项目结构:根据项目类型自动生成目录和文件
- 📝 创建代码模板:使用预定义或自定义模板生成代码
- 🔄 批量文件操作:一次性创建多个相关文件
- ⚙️ 配置文件生成:自动生成项目配置文件
- 🎯 智能代码补全:基于项目上下文的代码生成
启动构建器模式
方法一:快捷键
- Windows/Linux:
Ctrl + Shift + B - macOS:
Cmd + Shift + B
方法二:命令面板
- 打开命令面板(
Ctrl+Shift+P或Cmd+Shift+P) - 输入 "Trae: Builder Mode"
- 选择相应的构建器选项
方法三:右键菜单
- 在项目资源管理器中右键点击
- 选择 "Trae Builder" 选项
- 选择要使用的构建器类型
构建器界面
┌─────────────────────────────────────────────────────┐
│ 🏗️ Trae Builder │
├─────────────────────────────────────────────────────┤
│ 项目类型: │
│ ○ Web 应用 ○ API 服务 ○ 移动应用 │
│ ○ 桌面应用 ○ 库/包 ○ 自定义 │
│ │
│ 框架选择: │
│ ○ React ○ Vue ○ Angular │
│ ○ Express ○ FastAPI ○ Spring Boot │
│ │
│ 功能模块: │
│ ☑ 用户认证 ☑ 数据库 ☑ API 文档 │
│ ☑ 测试框架 ☐ 国际化 ☐ 缓存 │
│ │
│ [生成项目] [预览结构] [自定义配置] │
└─────────────────────────────────────────────────────┘项目模板
1. Web 应用模板
React 应用
my-react-app/
├── public/
│ ├── index.html
│ └── favicon.ico
├── src/
│ ├── components/
│ │ ├── Header.jsx
│ │ └── Footer.jsx
│ ├── pages/
│ │ ├── Home.jsx
│ │ └── About.jsx
│ ├── hooks/
│ ├── utils/
│ ├── styles/
│ ├── App.jsx
│ └── index.js
├── package.json
├── README.md
└── .gitignoreVue 应用
my-vue-app/
├── public/
├── src/
│ ├── components/
│ ├── views/
│ ├── router/
│ ├── store/
│ ├── assets/
│ ├── App.vue
│ └── main.js
├── package.json
└── vue.config.js2. API 服务模板
Express.js API
my-api/
├── src/
│ ├── controllers/
│ │ ├── authController.js
│ │ └── userController.js
│ ├── models/
│ │ └── User.js
│ ├── routes/
│ │ ├── auth.js
│ │ └── users.js
│ ├── middleware/
│ │ ├── auth.js
│ │ └── validation.js
│ ├── config/
│ │ └── database.js
│ └── app.js
├── tests/
├── package.json
└── .env.exampleFastAPI 服务
python
# main.py
from fastapi import FastAPI, Depends
from fastapi.middleware.cors import CORSMiddleware
from .routers import users, auth
from .database import engine
from . import models
models.Base.metadata.create_all(bind=engine)
app = FastAPI(title="My API", version="1.0.0")
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
app.include_router(auth.router, prefix="/auth", tags=["authentication"])
app.include_router(users.router, prefix="/users", tags=["users"])
@app.get("/")
def read_root():
return {"message": "Welcome to My API"}3. 移动应用模板
React Native
MyMobileApp/
├── src/
│ ├── components/
│ ├── screens/
│ ├── navigation/
│ ├── services/
│ ├── utils/
│ └── styles/
├── android/
├── ios/
├── package.json
└── metro.config.jsFlutter
my_flutter_app/
├── lib/
│ ├── models/
│ ├── screens/
│ ├── widgets/
│ ├── services/
│ ├── utils/
│ └── main.dart
├── test/
├── android/
├── ios/
└── pubspec.yaml代码模板
1. 组件模板
React 组件模板
jsx
import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types';
import styles from './{{ComponentName}}.module.css';
const {{ComponentName}} = ({
title,
children,
onAction,
...props
}) => {
const [isLoading, setIsLoading] = useState(false);
useEffect(() => {
// 组件挂载时的逻辑
}, []);
const handleAction = () => {
setIsLoading(true);
onAction?.();
setIsLoading(false);
};
return (
<div className={styles.container} {...props}>
<h2 className={styles.title}>{title}</h2>
<div className={styles.content}>
{children}
</div>
<button
onClick={handleAction}
disabled={isLoading}
className={styles.button}
>
{isLoading ? '处理中...' : '确认'}
</button>
</div>
);
};
{{ComponentName}}.propTypes = {
title: PropTypes.string.isRequired,
children: PropTypes.node,
onAction: PropTypes.func,
};
{{ComponentName}}.defaultProps = {
children: null,
onAction: null,
};
export default {{ComponentName}};Vue 组件模板
vue
<template>
<div class="{{component-name}}">
<h2 class="title">{{ title }}</h2>
<div class="content">
<slot></slot>
</div>
<button
@click="handleAction"
:disabled="isLoading"
class="action-button"
>
{{ isLoading ? '处理中...' : '确认' }}
</button>
</div>
</template>
<script>
export default {
name: '{{ComponentName}}',
props: {
title: {
type: String,
required: true
}
},
data() {
return {
isLoading: false
};
},
methods: {
handleAction() {
this.isLoading = true;
this.$emit('action');
this.isLoading = false;
}
},
mounted() {
// 组件挂载时的逻辑
}
};
</script>
<style scoped>
.{{component-name}} {
padding: 1rem;
border: 1px solid #ddd;
border-radius: 8px;
}
.title {
margin-bottom: 1rem;
color: #333;
}
.content {
margin-bottom: 1rem;
}
.action-button {
padding: 0.5rem 1rem;
background-color: #007bff;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
.action-button:disabled {
background-color: #ccc;
cursor: not-allowed;
}
</style>2. API 路由模板
Express 路由
javascript
const express = require('express');
const router = express.Router();
const { body, validationResult } = require('express-validator');
const {{ModelName}} = require('../models/{{ModelName}}');
const auth = require('../middleware/auth');
// GET /api/{{route}} - 获取所有{{resource}}
router.get('/', auth, async (req, res) => {
try {
const { page = 1, limit = 10, search } = req.query;
const query = search ? { name: { $regex: search, $options: 'i' } } : {};
const {{resources}} = await {{ModelName}}.find(query)
.limit(limit * 1)
.skip((page - 1) * limit)
.sort({ createdAt: -1 });
const total = await {{ModelName}}.countDocuments(query);
res.json({
{{resources}},
totalPages: Math.ceil(total / limit),
currentPage: page,
total
});
} catch (error) {
res.status(500).json({ message: error.message });
}
});
// GET /api/{{route}}/:id - 获取单个{{resource}}
router.get('/:id', auth, async (req, res) => {
try {
const {{resource}} = await {{ModelName}}.findById(req.params.id);
if (!{{resource}}) {
return res.status(404).json({ message: '{{Resource}} not found' });
}
res.json({{resource}});
} catch (error) {
res.status(500).json({ message: error.message });
}
});
// POST /api/{{route}} - 创建新{{resource}}
router.post('/', [
auth,
body('name').notEmpty().withMessage('Name is required'),
body('email').isEmail().withMessage('Valid email is required')
], async (req, res) => {
try {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
const {{resource}} = new {{ModelName}}(req.body);
await {{resource}}.save();
res.status(201).json({{resource}});
} catch (error) {
res.status(400).json({ message: error.message });
}
});
// PUT /api/{{route}}/:id - 更新{{resource}}
router.put('/:id', auth, async (req, res) => {
try {
const {{resource}} = await {{ModelName}}.findByIdAndUpdate(
req.params.id,
req.body,
{ new: true, runValidators: true }
);
if (!{{resource}}) {
return res.status(404).json({ message: '{{Resource}} not found' });
}
res.json({{resource}});
} catch (error) {
res.status(400).json({ message: error.message });
}
});
// DELETE /api/{{route}}/:id - 删除{{resource}}
router.delete('/:id', auth, async (req, res) => {
try {
const {{resource}} = await {{ModelName}}.findByIdAndDelete(req.params.id);
if (!{{resource}}) {
return res.status(404).json({ message: '{{Resource}} not found' });
}
res.json({ message: '{{Resource}} deleted successfully' });
} catch (error) {
res.status(500).json({ message: error.message });
}
});
module.exports = router;3. 数据模型模板
Mongoose 模型
javascript
const mongoose = require('mongoose');
const bcrypt = require('bcryptjs');
const {{modelName}}Schema = new mongoose.Schema({
name: {
type: String,
required: [true, 'Name is required'],
trim: true,
maxlength: [100, 'Name cannot exceed 100 characters']
},
email: {
type: String,
required: [true, 'Email is required'],
unique: true,
lowercase: true,
validate: {
validator: function(v) {
return /^\w+([.-]?\w+)*@\w+([.-]?\w+)*(\.\w{2,3})+$/.test(v);
},
message: 'Please enter a valid email'
}
},
password: {
type: String,
required: [true, 'Password is required'],
minlength: [6, 'Password must be at least 6 characters'],
select: false
},
role: {
type: String,
enum: ['user', 'admin'],
default: 'user'
},
isActive: {
type: Boolean,
default: true
},
lastLogin: {
type: Date
}
}, {
timestamps: true,
toJSON: { virtuals: true },
toObject: { virtuals: true }
});
// 索引
{{modelName}}Schema.index({ email: 1 });
{{modelName}}Schema.index({ createdAt: -1 });
// 虚拟字段
{{modelName}}Schema.virtual('fullName').get(function() {
return `${this.firstName} ${this.lastName}`;
});
// 中间件 - 保存前加密密码
{{modelName}}Schema.pre('save', async function(next) {
if (!this.isModified('password')) return next();
this.password = await bcrypt.hash(this.password, 12);
next();
});
// 实例方法 - 验证密码
{{modelName}}Schema.methods.comparePassword = async function(candidatePassword) {
return await bcrypt.compare(candidatePassword, this.password);
};
// 静态方法 - 查找活跃用户
{{modelName}}Schema.statics.findActive = function() {
return this.find({ isActive: true });
};
module.exports = mongoose.model('{{ModelName}}', {{modelName}}Schema);自定义模板
1. 创建自定义模板
json
{
"name": "React Hook Template",
"description": "Custom React Hook with TypeScript",
"category": "react",
"files": [
{
"path": "src/hooks/use{{HookName}}.ts",
"template": "react-hook.template"
},
{
"path": "src/hooks/__tests__/use{{HookName}}.test.ts",
"template": "react-hook-test.template"
}
],
"variables": [
{
"name": "HookName",
"type": "string",
"description": "Hook name (PascalCase)",
"required": true
},
{
"name": "returnType",
"type": "string",
"description": "Return type",
"default": "void"
}
]
}2. 模板文件内容
typescript
// react-hook.template
import { useState, useEffect, useCallback } from 'react';
interface Use{{HookName}}Options {
// 配置选项
}
interface Use{{HookName}}Return {
// 返回值类型
}
export const use{{HookName}} = (
options: Use{{HookName}}Options = {}
): Use{{HookName}}Return => {
const [state, setState] = useState<any>(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<Error | null>(null);
const execute = useCallback(async () => {
try {
setLoading(true);
setError(null);
// Hook 逻辑实现
setState(result);
} catch (err) {
setError(err as Error);
} finally {
setLoading(false);
}
}, [options]);
useEffect(() => {
execute();
}, [execute]);
return {
state,
loading,
error,
execute
};
};批量操作
1. 批量创建文件
javascript
// 构建器配置
const batchConfig = {
baseDir: 'src/components',
components: [
'Header',
'Footer',
'Sidebar',
'Navigation',
'Modal'
],
template: 'react-component',
includeTests: true,
includeStories: true
};
// 生成结果
src/components/
├── Header/
│ ├── Header.jsx
│ ├── Header.test.js
│ ├── Header.stories.js
│ └── Header.module.css
├── Footer/
│ ├── Footer.jsx
│ ├── Footer.test.js
│ ├── Footer.stories.js
│ └── Footer.module.css
└── ...2. 批量更新配置
json
{
"operation": "batch-update",
"files": [
"package.json",
"tsconfig.json",
".eslintrc.js",
"jest.config.js"
],
"updates": {
"package.json": {
"scripts.test": "jest --coverage",
"devDependencies.@types/jest": "^29.0.0"
},
"tsconfig.json": {
"compilerOptions.strict": true,
"include": ["src/**/*", "tests/**/*"]
}
}
}智能代码生成
1. 基于上下文的生成
javascript
// 分析现有代码结构
const analysis = {
framework: 'React',
stateManagement: 'Redux',
styling: 'CSS Modules',
testing: 'Jest + React Testing Library',
typescript: true
};
// 生成符合项目风格的组件
const generatedComponent = generateComponent({
name: 'UserProfile',
props: ['user', 'onEdit', 'onDelete'],
context: analysis
});2. API 优先的开发
yaml
# API 规范
openapi: 3.0.0
info:
title: User API
version: 1.0.0
paths:
/users:
get:
summary: Get all users
responses:
'200':
description: List of users
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/User'
components:
schemas:
User:
type: object
properties:
id:
type: string
name:
type: string
email:
type: stringjavascript
// 自动生成的客户端代码
class UserAPI {
async getUsers() {
const response = await fetch('/api/users');
return response.json();
}
async getUser(id) {
const response = await fetch(`/api/users/${id}`);
return response.json();
}
async createUser(userData) {
const response = await fetch('/api/users', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(userData)
});
return response.json();
}
}配置和自定义
1. 构建器配置文件
json
{
"trae.builder.enabled": true,
"trae.builder.defaultTemplate": "react-typescript",
"trae.builder.customTemplatesPath": "./templates",
"trae.builder.autoImport": true,
"trae.builder.codeStyle": "prettier",
"trae.builder.fileNaming": "kebab-case",
"trae.builder.includeTests": true,
"trae.builder.includeDocumentation": true
}2. 项目级配置
json
// .trae/builder.json
{
"projectType": "web-app",
"framework": "react",
"language": "typescript",
"styling": "tailwind",
"stateManagement": "zustand",
"testing": "vitest",
"templates": {
"component": "./templates/component.template",
"page": "./templates/page.template",
"hook": "./templates/hook.template"
},
"conventions": {
"componentNaming": "PascalCase",
"fileNaming": "kebab-case",
"folderStructure": "feature-based"
}
}最佳实践
1. 模板设计原则
- 保持简洁:模板应该包含必要的代码结构
- 遵循约定:符合项目的编码规范和命名约定
- 可扩展性:设计时考虑未来的扩展需求
- 文档完整:包含必要的注释和文档
2. 项目结构建议
project/
├── .trae/
│ ├── templates/
│ ├── builder.json
│ └── snippets/
├── src/
├── tests/
├── docs/
└── scripts/3. 团队协作
- 共享自定义模板
- 统一项目结构约定
- 版本控制模板文件
- 定期更新和维护模板
故障排除
常见问题
模板生成失败
- 检查模板语法
- 验证变量定义
- 确认文件路径权限
生成的代码不符合预期
- 检查模板配置
- 验证变量值
- 更新模板内容
性能问题
- 减少批量操作规模
- 优化模板复杂度
- 检查系统资源
快捷键参考
| 功能 | Windows/Linux | macOS |
|---|---|---|
| 启动构建器 | Ctrl+Shift+B | Cmd+Shift+B |
| 快速模板 | Ctrl+Alt+T | Cmd+Option+T |
| 批量操作 | Ctrl+Alt+B | Cmd+Option+B |
| 自定义模板 | Ctrl+Alt+C | Cmd+Option+C |
下一步
掌握构建器模式后,您可以继续学习:
使用构建器模式,让项目搭建和代码生成变得简单高效!