构建现代Vue3项目的代码规范体系:从零到一的完整实践指南

最近在重构一个遗留的Vue项目时,我遇到了一个令人头疼的问题:团队中每个人的代码风格都不一样,有的用单引号,有的用双引号;有的缩进用2个空格,有的用4个空格;更糟糕的是,有些明显的语法错误直到运行时才被发现。这让我意识到,一个统一的代码规范体系对于团队协作和项目维护有多么重要。

在当今的前端开发中,Vue3、Vite和TypeScript已经成为构建现代Web应用的主流技术栈。然而,仅仅使用这些技术还不够,如何确保代码质量、保持团队一致性、减少低级错误,才是决定项目长期健康度的关键因素。今天,我将分享如何从零开始,为Vue3 + Vite + TypeScript项目构建一套完整的代码规范体系,这套方案不仅适用于个人项目,更能满足团队协作的严格要求。

1. 项目初始化与环境准备

1.1 创建Vue3 + TypeScript项目

让我们从最基础的步骤开始。虽然市面上有很多现成的模板,但我更倾向于从零开始配置,这样能更好地理解每个环节的作用。

首先,使用Vite创建项目:

npm create vue@latest my-vue-project

在交互式命令行中,根据项目需求选择配置:

  • TypeScript支持:选择Yes,现代Vue项目强烈推荐使用TypeScript
  • JSX支持:根据项目需求选择,如果使用JSX语法就选Yes
  • Vue Router:对于单页应用建议选择Yes
  • Pinia状态管理:推荐选择Yes,这是Vue官方推荐的状态管理库
  • 测试工具:根据项目需求选择Vitest或其它测试框架
  • ESLint:选择Yes,这是我们今天要重点配置的工具
  • Prettier:选择Yes,用于代码格式化

创建完成后,进入项目目录并安装依赖:

cd my-vue-project
npm install

1.2 理解项目结构

让我们先看看Vite创建的项目结构:

my-vue-project/
├── src/
│   ├── components/
│   ├── views/
│   ├── App.vue
│   └── main.ts
├── index.html
├── package.json
├── tsconfig.json
├── vite.config.ts
└── README.md

这个结构已经为我们提供了一个良好的起点,但缺少了代码规范相关的配置文件。接下来,我们将逐步添加这些配置。

2. ESLint深度配置与最佳实践

2.1 ESLint基础配置

ESLint是JavaScript和TypeScript的静态代码分析工具,它能帮助我们识别出代码中的潜在问题。Vite创建的项目已经包含了ESLint,但我们需要根据项目需求进行定制化配置。

首先,检查项目中的.eslintrc.cjs文件(如果是TypeScript项目可能是.eslintrc.js):

// .eslintrc.cjs
module.exports = {
  root: true,
  env: {
    node: true,
    browser: true,
    es2021: true
  },
  extends: [
    'eslint:recommended',
    'plugin:@typescript-eslint/recommended',
    'plugin:vue/vue3-recommended'
  ],
  parser: 'vue-eslint-parser',
  parserOptions: {
    parser: '@typescript-eslint/parser',
    ecmaVersion: 'latest',
    sourceType: 'module'
  },
  plugins: ['@typescript-eslint', 'vue'],
  rules: {
    // 这里可以添加自定义规则
  }
}

注意:在Vue3项目中,必须使用vue-eslint-parser作为主解析器,然后在parserOptions中指定TypeScript解析器。这是很多配置错误的根源。

2.2 针对Vue3的特殊规则配置

Vue3引入了一些新的特性和语法,我们需要相应调整ESLint规则。以下是我在实际项目中总结的一些关键配置:

rules: {
  // Vue3相关规则
  'vue/multi-word-component-names': 'off', // 允许单单词组件名
  'vue/no-v-html': 'warn', // 谨慎使用v-html,有XSS风险
  'vue/require-default-prop': 'warn', // 建议为props提供默认值
  'vue/require-prop-types': 'warn', // 建议为props定义类型
  
  // TypeScript相关规则
  '@typescript-eslint/no-explicit-any': 'warn', // 尽量避免使用any类型
  '@typescript-eslint/no-unused-vars': ['error', { 
    argsIgnorePattern: '^_',
    varsIgnorePattern: '^_' 
  }], // 忽略以下划线开头的未使用变量
  
  // 通用JavaScript规则
  'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'warn',
  'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'warn',
  'eqeqeq': ['error', 'always'], // 强制使用===和!==
  'curly': ['error', 'all'], // 强制所有控制语句使用大括号
}

2.3 ESLint配置文件对比

为了帮助大家理解不同配置方式的差异,我整理了以下对比表格:

配置方式文件格式适用场景优点缺点
传统配置.eslintrc.jsESLint 8.x及以下兼容性好,文档丰富配置相对复杂
Flat配置eslint.config.mjsESLint 9.x配置更简洁,性能更好生态兼容性还在完善中
Package.json内联package.json简单项目无需额外文件配置复杂时难以维护

对于大多数项目,我推荐使用传统的.eslintrc.js方式,因为它有最完善的生态支持。下面是一个完整的配置示例:

// .eslintrc.js
module.exports = {
  root: true,
  env: {
    browser: true,
    es2021: true,
    node: true
  },
  extends: [
    'eslint:recommended',
    'plugin:@typescript-eslint/recommended',
    'plugin:vue/vue3-recommended',
    'plugin:prettier/recommended' // 必须放在最后
  ],
  parser: 'vue-eslint-parser',
  parserOptions: {
    parser: '@typescript-eslint/parser',
    ecmaVersion: 'latest',
    sourceType: 'module',
    ecmaFeatures: {
      jsx: true // 如果使用JSX/TSX
    }
  },
  plugins: ['@typescript-eslint', 'vue'],
  rules: {
    // 自定义规则
    'vue/multi-word-component-names': 'off',
    '@typescript-eslint/no-explicit-any': 'warn',
    'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'warn'
  },
  overrides: [
    {
      files: ['*.vue'],
      rules: {
        // Vue文件特定规则
        'vue/block-order': ['error', {
          order: ['template', 'script', 'style']
        }]
      }
    },
    {
      files: ['*.ts', '*.tsx'],
      rules: {
        // TypeScript文件特定规则
        '@typescript-eslint/explicit-function-return-type': 'warn'
      }
    }
  ],
  ignorePatterns: [
    'dist/**',
    'node_modules/**',
    '*.min.js',
    'coverage/**',
    '*.config.js'
  ]
}

3. Prettier配置与ESLint集成

3.1 Prettier基础配置

Prettier是一个"有态度"的代码格式化工具,它能自动格式化代码,让我们从格式争议中解放出来。首先安装Prettier:

npm install --save-dev --save-exact prettier

创建Prettier配置文件:

// .prettierrc.json
{
  "printWidth": 100,
  "tabWidth": 2,
  "useTabs": false,
  "semi": true,
  "singleQuote": true,
  "quoteProps": "as-needed",
  "jsxSingleQuote": false,
  "trailingComma": "es5",
  "bracketSpacing": true,
  "bracketSameLine": false,
  "arrowParens": "avoid",
  "proseWrap": "preserve",
  "htmlWhitespaceSensitivity": "css",
  "vueIndentScriptAndStyle": true,
  "endOfLine": "lf",
  "embeddedLanguageFormatting": "auto"
}

提示:vueIndentScriptAndStyle选项特别重要,它控制Vue单文件组件中<script>和<style>标签的缩进。建议设置为true以保持一致的缩进风格。

3.2 解决ESLint与Prettier的规则冲突

ESLint和Prettier都有代码格式相关的规则,如果不进行适当配置,它们会产生冲突。解决方案是使用eslint-config-prettier来关闭ESLint中与Prettier冲突的规则:

npm install --save-dev eslint-config-prettier eslint-plugin-prettier

然后在ESLint配置中集成:

// .eslintrc.js
extends: [
  'eslint:recommended',
  'plugin:@typescript-eslint/recommended',
  'plugin:vue/vue3-recommended',
  'plugin:prettier/recommended' // 必须放在extends数组的最后
]

plugin:prettier/recommended实际上做了三件事:

  1. 启用eslint-plugin-prettier
  2. 设置prettier/prettier规则为error
  3. 继承eslint-config-prettier配置

3.3 高级格式化配置

对于大型项目,我们可能需要更精细的格式化控制。以下是我在多个项目中总结的最佳实践配置:

// .prettierrc.json
{
  "printWidth": 100,
  "tabWidth": 2,
  "useTabs": false,
  "semi": true,
  "singleQuote": true,
  "trailingComma": "es5",
  "bracketSpacing": true,
  "arrowParens": "avoid",
  "vueIndentScriptAndStyle": true,
  "overrides": [
    {
      "files": "*.vue",
      "options": {
        "parser": "vue"
      }
    },
    {
      "files": "*.html",
      "options": {
        "parser": "html"
      }
    },
    {
      "files": "*.css",
      "options": {
        "parser": "css"
      }
    },
    {
      "files": "*.json",
      "options": {
        "parser": "json"
      }
    }
  ]
}

同时,创建.prettierignore文件来指定不需要格式化的文件:

# .prettierignore
dist
node_modules
coverage
*.min.js
*.min.css
*.svg
*.ico
*.png
*.jpg
*.jpeg
*.gif
*.webp
.DS_Store
Thumbs.db

4. 开发环境集成与自动化

4.1 VS Code配置优化

要让ESLint和Prettier在开发过程中真正发挥作用,需要正确配置编辑器。以下是针对VS Code的完整配置:

// .vscode/settings.json
{
  // 文件保存时自动格式化
  "editor.formatOnSave": true,
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": "explicit",
    "source.organizeImports": "never"
  },
  
  // 默认格式化工具
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  
  // 文件类型特定的格式化工具
  "[vue]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[typescript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[javascript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[json]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[jsonc]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  
  // ESLint配置
  "eslint.validate": [
    "javascript",
    "javascriptreact",
    "typescript",
    "typescriptreact",
    "vue"
  ],
  "eslint.workingDirectories": ["./"],
  "eslint.options": {
    "overrideConfigFile": ".eslintrc.js"
  },
  
  // Prettier配置
  "prettier.requireConfig": true,
  
  // Vue相关配置
  "vetur.validation.template": false,
  "vetur.format.enable": false,
  
  // 其他编辑器设置
  "files.autoSave": "onFocusChange",
  "files.eol": "\n",
  "files.trimTrailingWhitespace": true,
  "files.insertFinalNewline": true
}

同时,创建扩展推荐文件,确保团队成员使用相同的工具:

// .vscode/extensions.json
{
  "recommendations": [
    "Vue.volar",
    "dbaeumer.vscode-eslint",
    "esbenp.prettier-vscode",
    "bradlc.vscode-tailwindcss",
    "mikestead.dotenv"
  ]
}

4.2 构建时检查与Git钩子

为了确保代码质量,我们需要在构建时进行代码检查,并通过Git钩子在提交前自动修复问题。

首先,安装必要的工具:

npm install --save-dev lint-staged husky

配置package.json中的脚本:

{
  "scripts": {
    "dev": "vite",
    "build": "vue-tsc && vite build",
    "preview": "vite preview",
    "lint": "eslint . --ext .vue,.js,.jsx,.ts,.tsx --fix",
    "lint:no-fix": "eslint . --ext .vue,.js,.jsx,.ts,.tsx",
    "format": "prettier --write .",
    "type-check": "vue-tsc --noEmit",
    "prepare": "husky install"
  }
}

设置Git钩子:

# 初始化husky
npx husky install

# 添加pre-commit钩子
npx husky add .husky/pre-commit "npx lint-staged"

创建lint-staged配置:

// .lintstagedrc.json
{
  "*.{js,jsx,ts,tsx,vue}": [
    "eslint --fix",
    "prettier --write"
  ],
  "*.{json,md,html,css,scss,less}": [
    "prettier --write"
  ]
}

4.3 Vite插件集成

为了让ESLint错误在开发过程中更明显,我们可以使用vite-plugin-eslint:

npm install --save-dev vite-plugin-eslint

在Vite配置中启用:

// vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import eslintPlugin from 'vite-plugin-eslint'

export default defineConfig({
  plugins: [
    vue(),
    eslintPlugin({
      include: ['src/**/*.vue', 'src/**/*.ts', 'src/**/*.tsx'],
      exclude: ['node_modules', 'dist'],
      cache: true,
      fix: true,
      failOnError: false,
      failOnWarning: false
    })
  ]
})

5. 团队协作规范与进阶配置

5.1 代码提交规范

统一的提交信息格式对于团队协作和版本管理非常重要。我推荐使用Conventional Commits规范:

npm install --save-dev @commitlint/cli @commitlint/config-conventional

创建commitlint配置:

// commitlint.config.js
module.exports = {
  extends: ['@commitlint/config-conventional'],
  rules: {
    'type-enum': [
      2,
      'always',
      ['feat', 'fix', 'docs', 'style', 'refactor', 'test', 'chore', 'revert']
    ],
    'subject-case': [0]
  }
}

配置Git钩子:

npx husky add .husky/commit-msg 'npx --no -- commitlint --edit "$1"'

5.2 性能优化配置

对于大型项目,ESLint检查可能会影响开发体验。以下是一些优化建议:

// .eslintrc.js
module.exports = {
  // ... 其他配置
  
  // 缓存配置
  cache: true,
  cacheLocation: 'node_modules/.cache/eslint',
  
  // 忽略模式
  ignorePatterns: [
    'dist/**',
    'node_modules/**',
    'coverage/**',
    '*.min.js',
    '*.config.js',
    '*.d.ts'
  ],
  
  // 性能优化
  reportUnusedDisableDirectives: true
}

5.3 自定义规则开发

当团队有特殊的编码规范时,可以开发自定义ESLint规则。以下是一个简单的示例:

// eslint-plugin-custom-rules/index.js
module.exports = {
  rules: {
    'no-direct-vue-import': {
      create(context) {
        return {
          ImportDeclaration(node) {
            if (node.source.value === 'vue') {
              const specifiers = node.specifiers.map(s => s.imported?.name || s.local.name)
              if (specifiers.includes('ref') || specifiers.includes('computed')) {
                context.report({
                  node,
                  message: '请从@vue/reactivity导入ref和computed,而不是直接从vue导入'
                })
              }
            }
          }
        }
      }
    }
  }
}

在项目中启用自定义规则:

// .eslintrc.js
module.exports = {
  plugins: ['custom-rules'],
  rules: {
    'custom-rules/no-direct-vue-import': 'error'
  }
}

5.4 配置管理表格

为了帮助团队快速理解各项配置,我整理了以下配置参考表格:

工具配置文件主要作用团队协作重要性
ESLint.eslintrc.js代码质量检查高 - 统一代码风格
Prettier.prettierrc.json代码格式化高 - 自动格式化
TypeScripttsconfig.json类型检查高 - 类型安全
Vitevite.config.ts构建配置中 - 构建优化
Git Hooks.husky/提交前检查高 - 质量门禁
VS Code.vscode/settings.json编辑器配置中 - 开发体验

5.5 常见问题解决方案

在实际项目中,我遇到过各种配置问题。以下是一些常见问题的解决方案:

问题1:Vue文件中的TypeScript类型检查不工作

解决方案:确保安装了正确的解析器组合:

{
  "parser": "vue-eslint-parser",
  "parserOptions": {
    "parser": "@typescript-eslint/parser",
    "sourceType": "module",
    "ecmaVersion": "latest"
  }
}

问题2:Prettier格式化后ESLint报错

解决方案:确保eslint-config-prettier在extends数组的最后:

extends: [
  // 其他配置...
  'plugin:prettier/recommended' // 必须放在最后
]

问题3:保存时自动修复不工作

解决方案:检查VS Code设置,确保以下配置正确:

{
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": "explicit"
  },
  "eslint.validate": [
    "javascript",
    "typescript",
    "vue"
  ]
}

问题4:团队中不同编辑器格式不一致

解决方案:在项目中包含完整的编辑器配置,并确保所有团队成员安装推荐的扩展。

经过这些配置,你的Vue3项目将拥有完整的代码规范体系。这套方案在我负责的多个项目中都得到了验证,不仅提高了代码质量,还显著减少了团队协作中的摩擦。最重要的是,它建立了一个自动化的质量保障机制,让开发者可以更专注于业务逻辑的实现,而不是代码风格的争论。

更多推荐