mcpField
N
nodejs-development

nodejs-development

github.com/mindrally开发287751 次安装3 周前更新
代码仓库

关于 nodejs-development

面向 Node.js 和 TypeScript 开发的技能,涵盖 Payload CMS 与 Next.js、Vue.js、Zod 验证、API、测试及异步代码实践。

主要功能

  1. 01Payload CMS 与 Next.js 模式
  2. 02Vue.js 组件和组合式函数
  3. 03Pinia 状态管理示例
  4. 04Zod 模式验证
  5. 05API 错误与异步处理
  6. 06测试实践

适用场景

  1. 01规划 Payload CMS 项目结构
  2. 02构建类型化 Vue.js 界面
  3. 03使用 Zod 验证 API 输入
  4. 04制定 Node.js 应用测试方案

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/mindrally/skills --skill nodejs-development

安装后在 Claude Code 中输入/nodejs-development确认已加载。

详细介绍

Node.js 开发指南

你是 Node.js 开发专家,熟悉 TypeScript,涵盖各种框架和模式。

Payload CMS 与 Next.js

项目设置
project/
├── src/
│   ├── app/              # Next.js app directory
│   ├── collections/      # Payload collections
│   ├── blocks/          # Custom blocks
│   ├── fields/          # Custom fields
│   └── access/          # Access control functions
├── payload.config.ts    # Payload configuration
└── next.config.js       # Next.js configuration
集合定义
import { CollectionConfig } from 'payload/types';

const Posts: CollectionConfig = {
  slug: 'posts',
  admin: {
    useAsTitle: 'title',
  },
  access: {
    read: () => true,
    create: ({ req: { user } }) => Boolean(user),
    update: ({ req: { user } }) => Boolean(user),
    delete: ({ req: { user } }) => Boolean(user),
  },
  fields: [
    {
      name: 'title',
      type: 'text',
      required: true,
    },
    {
      name: 'content',
      type: 'richText',
    },
    {
      name: 'publishedDate',
      type: 'date',
    },
  ],
};

export default Posts;
API 路由
// app/api/posts/route.ts
import { getPayloadClient } from '@/lib/payload';

export async function GET() {
  const payload = await getPayloadClient();
  const posts = await payload.find({
    collection: 'posts',
    limit: 10,
  });
  return Response.json(posts);
}

Vue.js 与 TypeScript

组件结构
<script setup lang="ts">
import { ref, computed, onMounted } from 'vue';

interface User {
  id: number;
  name: string;
  email: string;
}

const props = defineProps<{
  userId: number;
}>();

const emit = defineEmits<{
  (e: 'update', user: User): void;
}>();

const user = ref<User | null>(null);
const isLoading = ref(false);

const displayName = computed(() => user.value?.name ?? 'Unknown');

async function fetchUser() {
  isLoading.value = true;
  try {
    const response = await fetch(`/api/users/${props.userId}`);
    user.value = await response.json();
  } finally {
    isLoading.value = false;
  }
}

onMounted(fetchUser);
</script>

<template>
  <div v-if="isLoading">Loading...</div>
  <div v-else-if="user">
    <h2>{{ displayName }}</h2>
    <p>{{ user.email }}</p>
  </div>
</template>
Composables
// composables/useApi.ts
import { ref } from 'vue';

export function useApi<T>(url: string) {
  const data = ref<T | null>(null);
  const error = ref<Error | null>(null);
  const isLoading = ref(false);

  async function execute() {
    isLoading.value = true;
    error.value = null;

    try {
      const response = await fetch(url);
      if (!response.ok) throw new Error('Request failed');
      data.value = await response.json();
    } catch (e) {
      error.value = e as Error;
    } finally {
      isLoading.value = false;
    }
  }

  return { data, error, isLoading, execute };
}
Pinia Store
// stores/user.ts
import { defineStore } from 'pinia';

interface UserState {
  user: User | null;
  isAuthenticated: boolean;
}

export const useUserStore = defineStore('user', {
  state: (): UserState => ({
    user: null,
    isAuthenticated: false,
  }),

  getters: {
    displayName: (state) => state.user?.name ?? 'Guest',
  },

  actions: {
    async login(credentials: LoginCredentials) {
      const user = await authService.login(credentials);
      this.user = user;
      this.isAuthenticated = true;
    },

    logout() {
      this.user = null;
      this.isAuthenticated = false;
    },
  },
});

TypeScript 与 Zod

Schema 定义
import { z } from 'zod';

const UserSchema = z.object({
  id: z.number(),
  name: z.string().min(1),
  email: z.string().email(),
  role: z.enum(['user', 'admin']),
  createdAt: z.date(),
});

type User = z.infer<typeof UserSchema>;

const CreateUserSchema = UserSchema.omit({ id: true, createdAt: true });
type CreateUserInput = z.infer<typeof CreateUserSchema>;
验证
function createUser(input: unknown): User {
  const validatedInput = CreateUserSchema.parse(input);
  // Input is now typed as CreateUserInput
  return {
    ...validatedInput,
    id: generateId(),
    createdAt: new Date(),
  };
}

// Safe parsing (doesn't throw)
function validateUser(input: unknown) {
  const result = UserSchema.safeParse(input);
  if (!result.success) {
    console.error(result.error.issues);
    return null;
  }
  return result.data;
}
API 验证中间件
import { z } from 'zod';
import { Request, Response, NextFunction } from 'express';

function validate<T extends z.ZodSchema>(schema: T) {
  return (req: Request, res: Response, next: NextFunction) => {
    const result = schema.safeParse(req.body);
    if (!result.success) {
      return res.status(400).json({ errors: result.error.issues });
    }
    req.body = result.data;
    next();
  };
}

// Usage
app.post('/users', validate(CreateUserSchema), createUserHandler);

通用最佳实践

错误处理
  • 使用自定义错误类
  • 实现全局错误处理器
  • 记录错误及其上下文
  • 返回适当的状态码
异步模式
  • 始终使用 async/await
  • 处理 Promise 拒绝
  • 设置适当的超时时间
  • 使用 Promise.all 并行执行操作
测试
  • 为工具函数编写单元测试
  • 为 API 编写集成测试
  • 使用测试固件
  • 模拟外部依赖

评论

支持 Markdown