🚀 全新升级 - Nuxt4 AI企业级开发实战指南现已发布!

开发工作流

构建现代化的Nuxt3开发工作流,掌握企业级开发工具链、团队协作和持续集成最佳实践

🎯 现代化开发工作流概览

高效的开发工作流是企业级项目成功的关键。本指南将帮你构建一套完整的Nuxt3开发工作流,包括代码质量保障、自动化测试、持续集成部署等关键环节。

🛠️ 开发环境配置

IDE 配置 (VS Code)

.vscode/settings.json
.vscode/extensions.json
.vscode/launch.json
{
  // 基础设置
  "editor.formatOnSave": true,
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true,
    "source.organizeImports": true
  },
  "editor.defaultFormatter": "esbenp.prettier-vscode",

  // TypeScript 设置
  "typescript.preferences.importModuleSpecifier": "relative",
  "typescript.suggest.autoImports": true,
  "typescript.updateImportsOnFileMove.enabled": "always",

  // Vue 设置
  "vue.codeActions.enabled": true,
  "vue.complete.normalizeComponentImportName": true,

  // Tailwind CSS 设置
  "tailwindCSS.experimental.classRegex": [
    ["clsx\\(([^)]*)\\)", "(?:'|\"|`)([^']*)(?:'|\"|`)"],
    ["cva\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"]
  ],

  // 文件关联
  "files.associations": {
    "*.vue": "vue",
    "*.md": "markdown"
  },

  // 排除文件
  "files.exclude": {
    "**/.nuxt": true,
    "**/.output": true,
    "**/node_modules": true,
    "**/dist": true
  },

  // 搜索设置
  "search.exclude": {
    "**/.nuxt": true,
    "**/.output": true,
    "**/node_modules": true,
    "**/pnpm-lock.yaml": true
  }
}

Git 配置

.gitignore
.gitmessage
.github/PULL_REQUEST_TEMPLATE.md
# Nuxt 相关
.nuxt
.output
.nitro
.cache

# 依赖
node_modules
.pnpm-store

# 日志
*.log*
logs

# 运行时
.DS_Store
Thumbs.db

# 环境变量
.env
.env.*
!.env.example

# IDE
.vscode/settings.json
.idea

# 测试
coverage
.nyc_output

# 构建产物
dist
build

# 临时文件
*.tmp
*.temp
.temp

🔧 代码质量保障

ESLint 配置

eslint.config.js
package.json - scripts
import antfu from '@antfu/eslint-config';

export default antfu(
  {
    // 基础配置
    vue: true,
    typescript: true,
    formatters: true,

    // 样式相关
    stylistic: {
      indent: 2,
      quotes: 'single',
      semi: false
    },

    // 忽略文件
    ignores: [
      '.nuxt',
      '.output',
      'dist',
      'node_modules'
    ]
  },

  // 自定义规则
  {
    rules: {
      // Vue 相关规则
      'vue/multi-word-component-names': 'off',
      'vue/no-multiple-template-root': 'off',
      'vue/component-name-in-template-casing': ['error', 'PascalCase'],
      'vue/component-definition-name-casing': ['error', 'PascalCase'],

      // TypeScript 相关规则
      '@typescript-eslint/no-unused-vars': ['error', {
        argsIgnorePattern: '^_',
        varsIgnorePattern: '^_'
      }],
      '@typescript-eslint/consistent-type-imports': ['error', {
        prefer: 'type-imports',
        disallowTypeAnnotations: false
      }],

      // 通用规则
      'no-console': ['warn', { allow: ['warn', 'error'] }],
      'prefer-const': 'error',
      'object-shorthand': 'error',
      'prefer-template': 'error'
    }
  },

  // 特定文件规则
  {
    files: ['server/**/*.ts'],
    rules: {
      'no-console': 'off' // 服务端允许使用console
    }
  },

  {
    files: ['**/*.test.ts', '**/*.spec.ts'],
    rules: {
      '@typescript-eslint/no-explicit-any': 'off' // 测试文件允许any
    }
  }
);

Prettier 配置

.prettierrc
{
  "semi": false,
  "singleQuote": true,
  "tabWidth": 2,
  "trailingComma": "es5",
  "printWidth": 100,
  "bracketSpacing": true,
  "arrowParens": "avoid",
  "vueIndentScriptAndStyle": false,
  "endOfLine": "lf",
  "plugins": ["prettier-plugin-tailwindcss"]
}

Husky 和 lint-staged

package.json - husky配置
.husky/pre-commit
.husky/commit-msg
{
  "scripts": {
    "prepare": "husky install"
  },
  "lint-staged": {
    "*.{js,jsx,ts,tsx,vue}": [
      "eslint --fix",
      "prettier --write"
    ],
    "*.{css,scss,less,html,json,md}": [
      "prettier --write"
    ]
  }
}

🧪 测试策略

单元测试 (Vitest)

vitest.config.ts
tests/setup.ts
tests/components/UserCard.test.ts
import { resolve } from 'node:path';
import { defineConfig } from 'vitest/config';

export default defineConfig({
  test: {
    environment: 'happy-dom',
    globals: true,
    setupFiles: ['./tests/setup.ts'],
    coverage: {
      provider: 'v8',
      reporter: ['text', 'json', 'html'],
      exclude: [
        'node_modules/',
        '.nuxt/',
        '.output/',
        'tests/',
        '**/*.d.ts',
        '**/*.config.*',
        '**/coverage/**'
      ],
      thresholds: {
        global: {
          branches: 80,
          functions: 80,
          lines: 80,
          statements: 80
        }
      }
    }
  },
  resolve: {
    alias: {
      '@': resolve(__dirname, '.'),
      '~': resolve(__dirname, '.')
    }
  }
});

E2E测试 (Playwright)

tests/e2e/auth.spec.ts
tests/e2e/ai-chat.spec.ts
import { expect, test } from '@playwright/test';

test.describe('用户认证', () => {
  test('用户登录流程', async ({ page }) => {
    // 访问登录页面
    await page.goto('/login');

    // 检查页面元素
    await expect(page.getByRole('heading', { name: '登录' })).toBeVisible();

    // 填写登录表单
    await page.getByLabel('邮箱').fill('test@example.com');
    await page.getByLabel('密码').fill('password123');

    // 提交表单
    await page.getByRole('button', { name: '登录' }).click();

    // 验证登录成功
    await expect(page).toHaveURL('/dashboard');
    await expect(page.getByText('欢迎回来')).toBeVisible();
  });

  test('登录失败处理', async ({ page }) => {
    await page.goto('/login');

    // 使用错误的凭证
    await page.getByLabel('邮箱').fill('invalid@example.com');
    await page.getByLabel('密码').fill('wrongpassword');
    await page.getByRole('button', { name: '登录' }).click();

    // 验证错误消息
    await expect(page.getByText('登录失败')).toBeVisible();
    await expect(page).toHaveURL('/login');
  });
});

📊 性能监控

性能预算配置

.lighthouserc.js
module.exports = {
  ci: {
    collect: {
      url: ['http://localhost:3000/', 'http://localhost:3000/about'],
      numberOfRuns: 3
    },
    assert: {
      assertions: {
        'categories:performance': ['error', { minScore: 0.9 }],
        'categories:accessibility': ['error', { minScore: 0.9 }],
        'categories:best-practices': ['error', { minScore: 0.9 }],
        'categories:seo': ['error', { minScore: 0.9 }],
        'first-contentful-paint': ['error', { maxNumericValue: 2000 }],
        'largest-contentful-paint': ['error', { maxNumericValue: 2500 }],
        'cumulative-layout-shift': ['error', { maxNumericValue: 0.1 }]
      }
    },
    upload: {
      target: 'temporary-public-storage'
    }
  }
}

Bundle 分析

nuxt.config.ts - 性能配置
export default defineNuxtConfig({
  // 构建优化
  build: {
    analyze: process.env.ANALYZE === 'true'
  },

  // Nitro 优化
  nitro: {
    compressPublicAssets: true,
    minify: true,
    experimental: {
      wasm: true
    }
  },

  // 性能监控
  hooks: {
    'build:before': () => {
      console.log('📊 开始构建性能分析...');
    },
    'build:done': (builder) => {
      console.log('✅ 构建完成,检查性能指标');
    }
  }
});

🚀 CI/CD 流水线

GitHub Actions 工作流

.github/workflows/ci.yml
.github/workflows/deploy.yml
name: CI Pipeline

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

env:
  NODE_VERSION: '18'
  PNPM_VERSION: '8'

jobs:
  # 代码质量检查
  quality:
    name: Code Quality
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}

      - name: Setup pnpm
        uses: pnpm/action-setup@v2
        with:
          version: ${{ env.PNPM_VERSION }}

      - name: Cache dependencies
        uses: actions/cache@v3
        with:
          path: ~/.pnpm-store
          key: ${{ runner.os }}-pnpm-${{ hashFiles('**/pnpm-lock.yaml') }}

      - name: Install dependencies
        run: pnpm install --frozen-lockfile

      - name: Type check
        run: pnpm type-check

      - name: Lint
        run: pnpm lint

      - name: Format check
        run: pnpm format:check

  # 单元测试
  test:
    name: Unit Tests
    runs-on: ubuntu-latest
    needs: quality

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}

      - name: Setup pnpm
        uses: pnpm/action-setup@v2
        with:
          version: ${{ env.PNPM_VERSION }}

      - name: Install dependencies
        run: pnpm install --frozen-lockfile

      - name: Run tests
        run: pnpm test --coverage

      - name: Upload coverage
        uses: codecov/codecov-action@v3
        with:
          file: ./coverage/coverage-final.json

  # E2E测试
  e2e:
    name: E2E Tests
    runs-on: ubuntu-latest
    needs: quality

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}

      - name: Setup pnpm
        uses: pnpm/action-setup@v2
        with:
          version: ${{ env.PNPM_VERSION }}

      - name: Install dependencies
        run: pnpm install --frozen-lockfile

      - name: Install Playwright
        run: pnpm dlx playwright install

      - name: Build application
        run: pnpm build

      - name: Start application
        run: pnpm preview &

      - name: Wait for app
        run: sleep 10

      - name: Run E2E tests
        run: pnpm test:e2e

      - name: Upload test results
        uses: actions/upload-artifact@v3
        if: failure()
        with:
          name: playwright-report
          path: test-results/

  # 构建测试
  build:
    name: Build Test
    runs-on: ubuntu-latest
    needs: [test, e2e]

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}

      - name: Setup pnpm
        uses: pnpm/action-setup@v2
        with:
          version: ${{ env.PNPM_VERSION }}

      - name: Install dependencies
        run: pnpm install --frozen-lockfile

      - name: Build application
        run: pnpm build

      - name: Upload build artifacts
        uses: actions/upload-artifact@v3
        with:
          name: build-files
          path: .output/

📈 监控和日志

应用监控配置

plugins/monitoring.client.ts
server/utils/logger.ts
import { defineNuxtPlugin } from '#app';

export default defineNuxtPlugin(() => {
  // 性能监控
  if (typeof window !== 'undefined') {
    // Web Vitals
    import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
      getCLS(console.log);
      getFID(console.log);
      getFCP(console.log);
      getLCP(console.log);
      getTTFB(console.log);
    });

    // 错误监控
    window.addEventListener('error', (event) => {
      console.error('Global error:', event.error);
      // 发送到监控服务
    });

    window.addEventListener('unhandledrejection', (event) => {
      console.error('Unhandled promise rejection:', event.reason);
      // 发送到监控服务
    });
  }
});

🎯 团队协作规范

代码审查清单

docs/CODE_REVIEW.md
# 代码审查清单

## 📋 审查要点

### 🎯 功能性
- [ ] 功能是否按需求正确实现?
- [ ] 边界条件是否处理得当?
- [ ] 错误处理是否完善?

### 🏗️ 架构设计
- [ ] 代码结构是否清晰合理?
- [ ] 是否遵循项目的架构模式?
- [ ] 组件职责是否单一?

### 🔒 安全性
- [ ] 用户输入是否得到验证?
- [ ] 敏感信息是否得到保护?
- [ ] API接口是否有适当的权限控制?

### 🚀 性能
- [ ] 是否存在性能瓶颈?
- [ ] 图片和资源是否优化?
- [ ] 数据库查询是否高效?

### 🧪 测试
- [ ] 是否添加了适当的测试?
- [ ] 测试覆盖率是否足够?
- [ ] 测试是否可靠且易维护?

### 📚 文档
- [ ] 复杂逻辑是否有注释说明?
- [ ] API文档是否更新?
- [ ] README是否需要更新?

### 🎨 代码风格
- [ ] 是否遵循项目的编码规范?
- [ ] 变量和函数命名是否清晰?
- [ ] 代码是否易于理解和维护?

发布流程

scripts/release.sh
#!/bin/bash

# 发布脚本
set -e

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

echo -e "${GREEN}🚀 开始发布流程...${NC}"

# 检查当前分支
current_branch=$(git branch --show-current)
if [ "$current_branch" != "main" ]; then
  echo -e "${RED}❌ 请在main分支上执行发布${NC}"
  exit 1
fi

# 检查工作区是否干净
if [ -n "$(git status --porcelain)" ]; then
  echo -e "${RED}❌ 工作区有未提交的更改${NC}"
  exit 1
fi

# 拉取最新代码
echo -e "${YELLOW}📥 拉取最新代码...${NC}"
git pull origin main

# 运行测试
echo -e "${YELLOW}🧪 运行测试套件...${NC}"
pnpm test

# 构建项目
echo -e "${YELLOW}🔨 构建项目...${NC}"
pnpm build

# 版本号提升
echo -e "${YELLOW}📝 更新版本号...${NC}"
pnpm changeset version
pnpm install

# 提交版本更改
if [ -n "$(git status --porcelain)" ]; then
  git add .
  git commit -m "chore: release version"
fi

# 创建标签并推送
echo -e "${YELLOW}🏷️ 创建发布标签...${NC}"
pnpm changeset tag
git push origin main --tags

# 发布到npm (如果是包)
# pnpm changeset publish

echo -e "${GREEN}✅ 发布完成!${NC}"

🎯 最佳实践总结

关键指标监控

utils/metrics.ts
// 关键性能指标
export interface Metrics {
  // 构建指标
  buildTime: number;
  bundleSize: number;

  // 测试指标
  testCoverage: number;
  testPassRate: number;

  // 部署指标
  deploymentFrequency: number;
  leadTime: number;
  meanTimeToRecovery: number;
  changeFailureRate: number;

  // 质量指标
  codeSmells: number;
  technicalDebt: number;
  duplicatedLines: number;
}

export function trackMetrics(metrics: Partial<Metrics>) {
  // 发送指标到监控系统
  console.log('📊 Metrics:', metrics);
}