项目脚手架Skill project-scaffolder

项目脚手架是一个用于快速搭建项目基础的技能,提供模板、配置、最佳实践和自动化工具,支持多种框架和语言,加速软件开发流程。关键词:项目脚手架、快速设置、模板、最佳实践、配置、自动化、软件开发、DevOps。

DevOps 0 次安装 0 次浏览 更新于 3/11/2026

名称: 项目脚手架 描述: 快速项目设置,使用模板、最佳实践和完整配置,支持各种框架和语言。

项目脚手架技能

快速项目设置,使用模板、最佳实践和完整配置,支持各种框架和语言。

指令

您是一个项目脚手架专家。当调用时:

  1. 分析项目需求

    • 识别项目类型(Web应用、API、CLI、库等)
    • 确定技术栈
    • 理解目标环境
    • 评估团队规模和工作流需求
  2. 生成项目结构

    • 创建适当的目录结构
    • 设置配置文件
    • 初始化版本控制
    • 配置包管理器
    • 添加必要的依赖项
  3. 配置开发环境

    • 设置代码检查和格式化
    • 配置测试框架
    • 添加预提交钩子
    • 创建环境文件
    • 设置CI/CD管道基础
  4. 提供文档

    • 包含设置说明的README
    • 贡献指南
    • 行为准则(如果需要)
    • 开发工作流文档
    • 架构概述

支持的项目类型

  • 前端:React、Vue、Angular、Next.js、Svelte
  • 后端:Node.js(Express、Fastify)、Python(Django、FastAPI、Flask)、Go、Rust
  • 移动端:React Native、Flutter
  • 桌面端:Electron、Tauri
  • CLI工具:Node.js、Python、Go、Rust
  • :NPM包、Python包、Go模块
  • 全栈:MERN、MEAN、JAMstack
  • 单仓库:Turborepo、Nx、Lerna

使用示例

@project-scaffolder 创建 React + TypeScript 应用
@project-scaffolder --template express-api
@project-scaffolder --monorepo turborepo
@project-scaffolder --cli go
@project-scaffolder --library npm-package

项目模板

React + TypeScript + Vite

# 初始化项目
npm create vite@latest my-app -- --template react-ts
cd my-app
npm install

# 添加必要的依赖项
npm install -D eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin
npm install -D prettier eslint-config-prettier eslint-plugin-prettier
npm install -D husky lint-staged
npm install -D vitest @testing-library/react @testing-library/jest-dom
npm install -D @vitejs/plugin-react

目录结构:

my-app/
├── src/
│   ├── components/
│   │   ├── common/
│   │   └── features/
│   ├── hooks/
│   ├── utils/
│   ├── services/
│   ├── types/
│   ├── styles/
│   ├── App.tsx
│   └── main.tsx
├── public/
├── tests/
│   ├── unit/
│   └── integration/
├── .github/
│   └── workflows/
│       └── ci.yml
├── .husky/
│   └── pre-commit
├── .eslintrc.json
├── .prettierrc
├── .gitignore
├── tsconfig.json
├── vite.config.ts
├── package.json
└── README.md

.eslintrc.json:

{
  "parser": "@typescript-eslint/parser",
  "extends": [
    "eslint:recommended",
    "plugin:@typescript-eslint/recommended",
    "plugin:react/recommended",
    "plugin:react-hooks/recommended",
    "prettier"
  ],
  "plugins": ["@typescript-eslint", "react", "react-hooks", "prettier"],
  "rules": {
    "prettier/prettier": "error",
    "react/react-in-jsx-scope": "off",
    "@typescript-eslint/explicit-module-boundary-types": "off",
    "@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }]
  },
  "settings": {
    "react": {
      "version": "detect"
    }
  }
}

.prettierrc:

{
  "semi": true,
  "trailingComma": "es5",
  "singleQuote": true,
  "printWidth": 100,
  "tabWidth": 2,
  "useTabs": false
}

vite.config.ts:

import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import path from 'path';

export default defineConfig({
  plugins: [react()],
  resolve: {
    alias: {
      '@': path.resolve(__dirname, './src'),
      '@components': path.resolve(__dirname, './src/components'),
      '@hooks': path.resolve(__dirname, './src/hooks'),
      '@utils': path.resolve(__dirname, './src/utils'),
      '@types': path.resolve(__dirname, './src/types'),
    },
  },
  test: {
    globals: true,
    environment: 'jsdom',
    setupFiles: './tests/setup.ts',
  },
});

package.json 脚本:

{
  "scripts": {
    "dev": "vite",
    "build": "tsc && vite build",
    "preview": "vite preview",
    "lint": "eslint src --ext .ts,.tsx",
    "lint:fix": "eslint src --ext .ts,.tsx --fix",
    "format": "prettier --write \"src/**/*.{ts,tsx,css}\"",
    "test": "vitest",
    "test:ui": "vitest --ui",
    "test:coverage": "vitest --coverage",
    "prepare": "husky install"
  }
}

Node.js Express API + TypeScript

# 初始化项目
mkdir my-api && cd my-api
npm init -y
npm install express cors helmet dotenv
npm install -D typescript @types/node @types/express @types/cors
npm install -D ts-node-dev
npm install -D eslint prettier
npm install -D jest @types/jest ts-jest supertest @types/supertest

目录结构:

my-api/
├── src/
│   ├── config/
│   │   └── database.ts
│   ├── controllers/
│   ├── middleware/
│   │   ├── errorHandler.ts
│   │   ├── validation.ts
│   │   └── auth.ts
│   ├── models/
│   ├── routes/
│   │   └── index.ts
│   ├── services/
│   ├── utils/
│   │   ├── logger.ts
│   │   └── asyncHandler.ts
│   ├── types/
│   │   └── express.d.ts
│   ├── app.ts
│   └── server.ts
├── tests/
│   ├── unit/
│   └── integration/
├── .env.example
├── .gitignore
├── tsconfig.json
├── jest.config.js
├── package.json
└── README.md

src/app.ts:

import express, { Application } from 'express';
import cors from 'cors';
import helmet from 'helmet';
import { errorHandler } from './middleware/errorHandler';
import routes from './routes';

const app: Application = express();

// 安全中间件
app.use(helmet());
app.use(cors());

// 正文解析中间件
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

// 路由
app.use('/api', routes);

// 健康检查
app.get('/health', (req, res) => {
  res.status(200).json({ status: 'ok', timestamp: new Date().toISOString() });
});

// 错误处理
app.use(errorHandler);

export default app;

src/server.ts:

import app from './app';
import dotenv from 'dotenv';

dotenv.config();

const PORT = process.env.PORT || 3000;

app.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});

src/middleware/errorHandler.ts:

import { Request, Response, NextFunction } from 'express';

export class AppError extends Error {
  statusCode: number;
  isOperational: boolean;

  constructor(message: string, statusCode: number) {
    super(message);
    this.statusCode = statusCode;
    this.isOperational = true;
    Error.captureStackTrace(this, this.constructor);
  }
}

export const errorHandler = (
  err: Error,
  req: Request,
  res: Response,
  next: NextFunction
) => {
  if (err instanceof AppError) {
    return res.status(err.statusCode).json({
      status: 'error',
      message: err.message,
    });
  }

  console.error('ERROR:', err);
  return res.status(500).json({
    status: 'error',
    message: 'Internal server error',
  });
};

src/utils/asyncHandler.ts:

import { Request, Response, NextFunction } from 'express';

export const asyncHandler = (
  fn: (req: Request, res: Response, next: NextFunction) => Promise<any>
) => {
  return (req: Request, res: Response, next: NextFunction) => {
    Promise.resolve(fn(req, res, next)).catch(next);
  };
};

tsconfig.json:

{
  "compilerOptions": {
    "target": "ES2020",
    "module": "commonjs",
    "lib": ["ES2020"],
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "resolveJsonModule": true,
    "moduleResolution": "node",
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"],
      "@controllers/*": ["src/controllers/*"],
      "@services/*": ["src/services/*"],
      "@models/*": ["src/models/*"],
      "@middleware/*": ["src/middleware/*"],
      "@utils/*": ["src/utils/*"]
    }
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist", "tests"]
}

package.json 脚本:

{
  "scripts": {
    "dev": "ts-node-dev --respawn --transpile-only src/server.ts",
    "build": "tsc",
    "start": "node dist/server.js",
    "test": "jest",
    "test:watch": "jest --watch",
    "test:coverage": "jest --coverage",
    "lint": "eslint src --ext .ts",
    "lint:fix": "eslint src --ext .ts --fix"
  }
}

Python FastAPI 项目

# 创建项目目录
mkdir my-fastapi-app && cd my-fastapi-app

# 创建虚拟环境
python -m venv venv
source venv/bin/activate  # 在Windows上: venv\Scripts\activate

# 安装依赖项
pip install fastapi uvicorn pydantic python-dotenv
pip install pytest pytest-cov pytest-asyncio httpx
pip install black flake8 mypy isort

目录结构:

my-fastapi-app/
├── app/
│   ├── api/
│   │   ├── __init__.py
│   │   ├── dependencies.py
│   │   └── routes/
│   │       ├── __init__.py
│   │       └── users.py
│   ├── core/
│   │   ├── __init__.py
│   │   ├── config.py
│   │   └── security.py
│   ├── models/
│   │   ├── __init__.py
│   │   └── user.py
│   ├── schemas/
│   │   ├── __init__.py
│   │   └── user.py
│   ├── services/
│   │   ├── __init__.py
│   │   └── user_service.py
│   ├── db/
│   │   ├── __init__.py
│   │   └── session.py
│   ├── __init__.py
│   └── main.py
├── tests/
│   ├── __init__.py
│   ├── conftest.py
│   └── test_api/
│       └── test_users.py
├── .env.example
├── .gitignore
├── requirements.txt
├── requirements-dev.txt
├── pyproject.toml
├── pytest.ini
└── README.md

app/main.py:

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from app.api.routes import users
from app.core.config import settings

app = FastAPI(
    title=settings.PROJECT_NAME,
    version=settings.VERSION,
    description=settings.DESCRIPTION,
)

# CORS
app.add_middleware(
    CORSMiddleware,
    allow_origins=settings.ALLOWED_ORIGINS,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# 包含路由器
app.include_router(users.router, prefix="/api/users", tags=["users"])

@app.get("/health")
async def health_check():
    return {"status": "ok"}

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)

app/core/config.py:

from pydantic_settings import BaseSettings
from typing import List

class Settings(BaseSettings):
    PROJECT_NAME: str = "My FastAPI App"
    VERSION: str = "1.0.0"
    DESCRIPTION: str = "FastAPI application"

    # CORS
    ALLOWED_ORIGINS: List[str] = ["http://localhost:3000"]

    # 数据库
    DATABASE_URL: str = "sqlite:///./app.db"

    # 安全
    SECRET_KEY: str = "your-secret-key-here"
    ALGORITHM: str = "HS256"
    ACCESS_TOKEN_EXPIRE_MINUTES: int = 30

    class Config:
        env_file = ".env"
        case_sensitive = True

settings = Settings()

app/schemas/user.py:

from pydantic import BaseModel, EmailStr
from datetime import datetime
from typing import Optional

class UserBase(BaseModel):
    email: EmailStr
    username: str

class UserCreate(UserBase):
    password: str

class UserUpdate(BaseModel):
    email: Optional[EmailStr] = None
    username: Optional[str] = None

class UserResponse(UserBase):
    id: int
    created_at: datetime

    class Config:
        from_attributes = True

pyproject.toml:

[tool.black]
line-length = 100
target-version = ['py311']
include = '\.pyi?$'

[tool.isort]
profile = "black"
line_length = 100

[tool.mypy]
python_version = "3.11"
warn_return_any = true
warn_unused_configs = true
disallow_untyped_defs = true

[tool.pytest.ini_options]
testpaths = ["tests"]
python_files = ["test_*.py"]
python_classes = ["Test*"]
python_functions = ["test_*"]

requirements.txt:

fastapi==0.104.1
uvicorn[standard]==0.24.0
pydantic==2.5.0
pydantic-settings==2.1.0
python-dotenv==1.0.0

requirements-dev.txt:

-r requirements.txt
pytest==7.4.3
pytest-cov==4.1.0
pytest-asyncio==0.21.1
httpx==0.25.2
black==23.11.0
flake8==6.1.0
mypy==1.7.1
isort==5.12.0

Go CLI 应用程序

# 初始化 Go 模块
mkdir my-cli && cd my-cli
go mod init github.com/username/my-cli

# 安装依赖项
go get github.com/spf13/cobra@latest
go get github.com/spf13/viper@latest

目录结构:

my-cli/
├── cmd/
│   ├── root.go
│   └── version.go
├── internal/
│   ├── config/
│   │   └── config.go
│   ├── cli/
│   │   └── ui.go
│   └── utils/
│       └── helpers.go
├── pkg/
│   └── api/
│       └── client.go
├── tests/
├── .gitignore
├── go.mod
├── go.sum
├── main.go
├── Makefile
└── README.md

main.go:

package main

import (
    "github.com/username/my-cli/cmd"
)

func main() {
    cmd.Execute()
}

cmd/root.go:

package cmd

import (
    "fmt"
    "os"

    "github.com/spf13/cobra"
    "github.com/spf13/viper"
)

var (
    cfgFile string
    verbose bool
)

var rootCmd = &cobra.Command{
    Use:   "my-cli",
    Short: "A brief description of your CLI",
    Long:  `A longer description of your CLI application`,
}

func Execute() {
    if err := rootCmd.Execute(); err != nil {
        fmt.Fprintln(os.Stderr, err)
        os.Exit(1)
    }
}

func init() {
    cobra.OnInitialize(initConfig)

    rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.my-cli.yaml)")
    rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "verbose output")
}

func initConfig() {
    if cfgFile != "" {
        viper.SetConfigFile(cfgFile)
    } else {
        home, err := os.UserHomeDir()
        cobra.CheckErr(err)

        viper.AddConfigPath(home)
        viper.SetConfigType("yaml")
        viper.SetConfigName(".my-cli")
    }

    viper.AutomaticEnv()

    if err := viper.ReadInConfig(); err == nil {
        fmt.Fprintln(os.Stderr, "Using config file:", viper.ConfigFileUsed())
    }
}

Makefile:

.PHONY: build test clean install

BINARY_NAME=my-cli
VERSION=$(shell git describe --tags --always --dirty)
LDFLAGS=-ldflags "-X main.Version=${VERSION}"

build:
	go build ${LDFLAGS} -o bin/${BINARY_NAME} main.go

test:
	go test -v ./...

test-coverage:
	go test -v -coverprofile=coverage.out ./...
	go tool cover -html=coverage.out

clean:
	go clean
	rm -rf bin/

install:
	go install ${LDFLAGS}

lint:
	golangci-lint run

run:
	go run main.go

单仓库设置 (Turborepo)

# 创建单仓库
npx create-turbo@latest my-monorepo
cd my-monorepo

目录结构:

my-monorepo/
├── apps/
│   ├── web/              # Next.js 应用
│   ├── api/              # Express API
│   └── docs/             # 文档站点
├── packages/
│   ├── ui/               # 共享 UI 组件
│   ├── config/           # 共享配置 (eslint, tsconfig)
│   ├── types/            # 共享 TypeScript 类型
│   └── utils/            # 共享实用工具
├── turbo.json
├── package.json
└── README.md

turbo.json:

{
  "$schema": "https://turbo.build/schema.json",
  "pipeline": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": [".next/**", "dist/**"]
    },
    "test": {
      "dependsOn": ["build"],
      "outputs": ["coverage/**"]
    },
    "lint": {
      "outputs": []
    },
    "dev": {
      "cache": false,
      "persistent": true
    }
  }
}

根目录 package.json:

{
  "name": "my-monorepo",
  "private": true,
  "workspaces": ["apps/*", "packages/*"],
  "scripts": {
    "dev": "turbo run dev",
    "build": "turbo run build",
    "test": "turbo run test",
    "lint": "turbo run lint",
    "format": "prettier --write \"**/*.{ts,tsx,md}\""
  },
  "devDependencies": {
    "turbo": "latest",
    "prettier": "latest"
  }
}

必要的配置文件

.gitignore (Node.js)

# 依赖项
node_modules/
.pnp
.pnp.js

# 测试
coverage/
*.lcov

# 生产
build/
dist/

# 环境
.env
.env.local
.env.*.local

# IDE
.vscode/
.idea/
*.swp
*.swo

# 操作系统
.DS_Store
Thumbs.db

# 日志
logs/
*.log
npm-debug.log*

.env.example

# 应用程序
NODE_ENV=development
PORT=3000
APP_URL=http://localhost:3000

# 数据库
DATABASE_URL=postgresql://user:password@localhost:5432/mydb

# 身份验证
JWT_SECRET=your-secret-key-here
JWT_EXPIRE=7d

# API 密钥
API_KEY=your-api-key

.github/workflows/ci.yml

name: CI

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main, develop]

jobs:
  test:
    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [18.x, 20.x]

    steps:
      - uses: actions/checkout@v3

      - name: Use Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v3
        with:
          node-version: ${{ matrix.node-version }}
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Run linter
        run: npm run lint

      - name: Run tests
        run: npm test

      - name: Build
        run: npm run build

最佳实践

项目结构

  • 关注点分离:保持路由、业务逻辑和数据访问分离
  • 使用 TypeScript:添加类型安全性以早期捕获错误
  • 模块化设计:创建可重用的模块和组件
  • 清晰的命名:使用描述性的文件和目录名称

配置

  • 环境变量:切勿将秘密提交到版本控制
  • 验证:在启动时验证配置
  • 默认值:为开发提供合理的默认值
  • 文档:记录所有必需的环境变量

代码质量

  • 代码检查:使用 ESLint/Pylint/golangci-lint
  • 格式化:使用 Prettier/Black/gofmt
  • 预提交钩子:在提交前强制执行质量检查
  • 测试:从第一天起设置测试框架

开发工作流

  • README:清楚地记录设置说明
  • 脚本:为常见任务提供 npm/make 脚本
  • CI/CD:设置自动化测试和部署
  • Git 钩子:使用 husky 进行预提交检查

模板检查清单

## 项目设置检查清单

### 初始设置
- [ ] 项目目录已创建
- [ ] 包管理器已初始化 (npm, pip, go mod)
- [ ] Git 仓库已初始化
- [ ] .gitignore 已配置
- [ ] README.md 已创建

### 配置
- [ ] 代码检查已配置 (ESLint, Pylint 等)
- [ ] 格式化已配置 (Prettier, Black 等)
- [ ] TypeScript 已配置(如果适用)
- [ ] 测试框架已设置
- [ ] 环境变量已记录

### 开发工具
- [ ] 预提交钩子已安装
- [ ] VS Code 设置已配置
- [ ] 调试配置已添加
- [ ] 常见任务的脚本已添加

### CI/CD
- [ ] GitHub Actions 工作流已创建
- [ ] 构建管道已配置
- [ ] 测试自动化已设置
- [ ] 部署过程已记录

### 文档
- [ ] 设置说明已编写
- [ ] API 文档已开始
- [ ] 贡献指南已添加
- [ ] 许可证文件已添加

注意事项

  • 始终以适当的项目结构开始
  • 使用模板和生成器以节省时间
  • 尽早配置工具以强制一致性
  • 从一开始就记录所有内容
  • 从第一天起使用版本控制
  • 在项目中尽早设置 CI/CD
  • 保持依赖项最新
  • 遵循技术栈的社区惯例