关于 vendure-developing
Vendure Development 是面向 Vendure 项目开发者的开发入口技能,适用于构建或审查 Vendure 项目。它提供架构参考、编码模式,并指导通过 vendure-expert Agent 协调专门技能。
主要功能
- 01覆盖六个 Vendure 领域的速查
- 02插件与 GraphQL 模式指南
- 03实体和数据库实现指南
- 04Admin UI 扩展模式
- 05通过 vendure-expert 协调专门技能
适用场景
- 01开始实现 Vendure 插件
- 02扩展 Shop 或 Admin GraphQL API
- 03构建实体并创建数据库迁移
- 04按安全和规范审查插件代码
MCP 相关
README 提到通过类似 MCP 工具名称的接口访问 Context7 文档,但未将此技能描述为 MCP 服务或客户端。
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ meriley/ claude-code-skills --skill vendure-developing安装后在 Claude Code 中输入/vendure-developing确认已加载。
详细介绍
Vendure 开发
用途
所有 Vendure 开发任务的入口。为 vendure-expert Agent 提供快速参考和指南,以便协调多个领域的指导。
不适用场景
- 非 Vendure 电商平台(Shopify、Magento 等)
- 不涉及 Vendure 的基础 TypeScript/NestJS
- 不涉及 Vendure Admin UI 的纯前端 React
快速开始:使用 Agent
如需全面的 Vendure 指导,请使用 vendure-expert Agent:
Task(subagent_type: "vendure-expert", prompt: "Your Vendure task here")
该 Agent 协调 9 项专业技能:
- 插件开发(编写 + 审查)
- GraphQL API(编写 + 审查)
- 实体/数据库(编写 + 审查)
- Admin UI(编写 + 审查)
- 配送/运输功能(专项)
Vendure 架构速查
6 个核心领域
| 领域 | 核心概念 |
|---|---|
| 插件 | @VendurePlugin、NestJS DI、生命周期钩子 |
| GraphQL | 双 API(Shop/Admin)、RequestContext、gql 模板 |
| 实体 | VendureEntity、TypeORM、迁移、自定义字段 |
| Admin UI | React/Angular、UI DevKit、延迟加载 |
| 策略 | InjectableStrategy、自定义逻辑 |
| 事件 | EventBus、事务安全的订阅 |
插件脚手架
import { PluginCommonModule, VendurePlugin } from "@vendure/core";
@VendurePlugin({
imports: [PluginCommonModule],
providers: [MyService],
entities: [MyEntity],
adminApiExtensions: {
schema: gql`...`,
resolvers: [MyResolver],
},
})
export class MyPlugin {
static init(options: MyPluginOptions) {
this.options = options;
return MyPlugin;
}
}
GraphQL Resolver 模式
import { Ctx, RequestContext, Query, Resolver } from "@vendure/core";
import { Allow, Permission } from "@vendure/core";
@Resolver()
export class MyResolver {
constructor(private myService: MyService) {}
@Query()
@Allow(Permission.ReadSettings)
async myQuery(@Ctx() ctx: RequestContext): Promise<MyType[]> {
return this.myService.findAll(ctx);
}
}
实体模式
import { VendureEntity, DeepPartial } from "@vendure/core";
import { Entity, Column, ManyToOne } from "typeorm";
@Entity()
export class MyEntity extends VendureEntity {
constructor(input?: DeepPartial<MyEntity>) {
super(input);
}
@Column()
name: string;
@ManyToOne(() => OtherEntity)
relation: OtherEntity;
}
Admin UI 扩展
// providers.ts
import { addNavMenuSection } from "@vendure/admin-ui/react";
export default [
addNavMenuSection(
{
id: "my-section",
label: "My Feature",
items: [
{
id: "my-page",
label: "My Page",
routerLink: ["/extensions/my-feature"],
icon: "cog",
},
],
},
"settings",
),
];
禁止使用的模式
插件开发
- 缺少 @VendurePlugin 装饰器
- 未使用 NestJS DI(@Injectable)
- 使用硬编码值,而非插件配置
- 绕过服务直接访问数据库
GraphQL
- 缺少 @Ctx() RequestContext 参数
- 绕过 @Allow() 权限装饰器
- 混用 Shop/Admin 架构类型
- 未使用 gql 模板字面量
实体
- 未继承 VendureEntity
- 缺少 @Entity() 装饰器
- 未创建迁移文件
- 使用
any类型
Admin UI
- 未对路由进行延迟加载
- 使用硬编码字符串(未使用 i18n)
- 缺少加载/错误状态
- 未处理权限
必须遵循的模式
RequestContext 传递
// ALWAYS pass ctx through service calls
async myResolver(@Ctx() ctx: RequestContext) {
return this.service.findAll(ctx); // Pass ctx!
}
权限装饰器
@Query()
@Allow(Permission.ReadCatalog) // ALWAYS specify permissions
async products(@Ctx() ctx: RequestContext) { }
实体输入类型
// Use DeepPartial for constructor input
constructor(input?: DeepPartial<MyEntity>) {
super(input);
}
InputMaybe 处理
// Check BOTH undefined AND null for GraphQL inputs
if (input.field !== undefined && input.field !== null) {
entity.field = input.field;
}
领域技能决策树
Task Type
│
├─> Creating/modifying plugin structure
│ └─> vendure-plugin-writing
│
├─> Reviewing plugin code
│ └─> vendure-plugin-reviewing
│
├─> Extending GraphQL schema or resolvers
│ └─> vendure-graphql-writing
│
├─> Reviewing GraphQL code
│ └─> vendure-graphql-reviewing
│
├─> Creating/modifying entities
│ └─> vendure-entity-writing
│
├─> Reviewing entity definitions
│ └─> vendure-entity-reviewing
│
├─> Building Admin UI components
│ └─> vendure-admin-ui-writing
│
├─> Reviewing Admin UI code
│ └─> vendure-admin-ui-reviewing
│
└─> Delivery/shipping features
└─> vendure-delivery-plugin
常见模式
双 API 分离
// Admin API - full access
export const graphqlAdminSchema = gql`
extend type Query {
myAdminQuery: [MyType!]!
}
extend type Mutation {
updateMyType(input: UpdateInput!): MyType!
}
`;
// Shop API - customer-facing, read-only or limited
export const graphqlShopSchema = gql`
extend type Query {
myPublicQuery: [MyType!]!
}
`;
带 RequestContext 的服务模式
@Injectable()
export class MyService {
constructor(private connection: TransactionalConnection) {}
async findAll(ctx: RequestContext): Promise<MyEntity[]> {
return this.connection.getRepository(ctx, MyEntity).find();
}
async create(ctx: RequestContext, input: CreateInput): Promise<MyEntity> {
const entity = new MyEntity(input);
return this.connection.getRepository(ctx, MyEntity).save(entity);
}
}
事务装饰器
@Mutation()
@Transaction() // Wrap in database transaction
@Allow(Permission.UpdateSettings)
async updateMyEntity(
@Ctx() ctx: RequestContext,
@Args() { input }: { input: UpdateInput }
): Promise<MyEntity> {
return this.service.update(ctx, input);
}
示例
示例 1:创建简单插件
任务: 创建一个用于跟踪产品浏览量的插件。
方法:
- 使用 vendure-plugin-writing 搭建插件脚手架
- 使用 vendure-entity-writing 创建 ProductView 实体
- 使用 vendure-graphql-writing 扩展查询
结果:
@VendurePlugin({
imports: [PluginCommonModule],
entities: [ProductViewEntity],
providers: [ProductViewService],
shopApiExtensions: {
schema: gql`
extend type Query {
productViews(productId: ID!): Int!
}
`,
resolvers: [ProductViewResolver],
},
})
export class ProductViewsPlugin {}
示例 2:添加 Admin UI 页面
任务: 添加一个用于管理插件配置的设置页面。
方法:
- 使用 vendure-admin-ui-writing 编写 React 组件
- 注册路由和导航项
- 使用 DataService 调用 API
结果:
// pages/SettingsPage.tsx
export function SettingsPage() {
const dataService = useInjector(DataService);
const [settings, setSettings] = useState<Settings>();
useEffect(() => {
dataService
.query(GetSettingsDocument)
.stream$.subscribe((result) => setSettings(result.mySettings));
}, []);
return <SettingsForm settings={settings} />;
}
示例 3:审查插件代码
任务: 审查插件的安全性和最佳实践。
方法:
- 使用 vendure-plugin-reviewing 检查插件结构
- 使用 vendure-graphql-reviewing 检查 resolver 模式
- 使用 vendure-entity-reviewing 检查数据库模式
检查项:
- 所有服务调用都传递了 RequestContext
- 所有 resolver 都声明了权限
- 没有直接执行数据库查询(使用 TransactionalConnection)
- 正确处理错误
故障排查
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 未找到实体 | 不在插件实体数组中 | 添加到 @VendurePlugin({ entities: [] }) |
| 未调用解析器 | 不在 resolvers 数组中 | 添加到 apiExtensions.resolvers |
| 权限被拒绝 | 缺少 @Allow 装饰器 | 添加 @Allow(Permission.X) |
| TypeScript 错误 | 导入路径错误 | 从 @vendure/core 导入 |
| 管理界面未加载 | 未延迟加载 | 对路由使用 React.lazy() |
外部文档
Context7(推荐)
mcp__context7__get-library-docs
context7CompatibleLibraryID: "/vendure-ecommerce/vendure"
topic: "plugins" or "entities" or "graphql" etc.
官方文档
相关 Agent
如需全面的多领域 Vendure 指南,请使用 vendure-expert Agent。
该 Agent 协调全部 9 项 Vendure 技能,并提供:
- 完整的插件生命周期指南
- 安全与质量审计
- 最佳实践规范
- 特定领域的模式
评论
支持 Markdown