📏 项目代码规范配置与
依赖管理方案落地指南

企业级代码质量保障与依赖管理体系完整方案 —— 从 ESLint/Prettier/CheckStyle 配置、SonarQube 集成、Commitlint 提交规范到 pnpm/npm 依赖管理、安全扫描、版本控制的全流程实操手册

📅 更新日期:2026 年 3 月 12 日 🔧 ESLint: v9.x | Prettier: v3.x ☕ CheckStyle: v10.x | SonarQube: v10.x ⏱️ 预计耗时:60-90 分钟

1. 代码规范重要性与管理策略

🎯 为什么需要代码规范

  • 提升代码可读性和可维护性
  • 减少代码审查时间和争议
  • 降低新人上手成本
  • 预防常见错误和安全隐患
  • 统一团队编码风格

📊 规范执行收益

  • 代码审查效率提升 40%+
  • Bug 率降低 30%+
  • 技术债务减少 50%+
  • 团队协作摩擦减少
  • 代码复用率提高

🛠️ 工具体系

  • 静态分析:ESLint/CheckStyle
  • 格式化:Prettier/Spotless
  • 提交规范:Commitlint/Husky
  • 质量平台:SonarQube
  • 依赖管理:pnpm/Dependabot

📈 实施策略

  • 渐进式引入,避免一刀切
  • 自动化优先,减少人工干预
  • IDE 集成,实时反馈
  • CI 卡点,强制合规
  • 定期回顾,持续优化
💡 规范分级管理:
  • Error 级别:必须修复,否则构建失败(如语法错误、安全问题)
  • Warning 级别:建议修复,不影响构建(如代码风格问题)
  • Info 级别:提示信息,供参考(如复杂度警告)
  • 策略:新项目严格模式,老项目渐进式修复

2. 前端代码规范配置(ESLint)

2.1 ESLint 基础配置

# ===== package.json 依赖 ===== { "devDependencies": { "eslint": "^9.0.0", "@eslint/js": "^9.0.0", "typescript-eslint": "^7.0.0", "eslint-plugin-react": "^7.34.0", "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-import": "^2.29.0", "eslint-plugin-jsx-a11y": "^6.8.0", "eslint-plugin-testing-library": "^6.2.0", "eslint-config-prettier": "^9.1.0" } } # ===== eslint.config.js (Flat Config - ESLint 9+) ===== import js from '@eslint/js'; import tsParser from 'typescript-eslint'; import react from 'eslint-plugin-react'; import reactHooks from 'eslint-plugin-react-hooks'; import importPlugin from 'eslint-plugin-import'; import prettierConfig from 'eslint-config-prettier'; export default tsParser.config( // 全局忽略文件 { ignores: [ '**/node_modules/**', '**/dist/**', '**/build/**', '**/coverage/**', '**/*.min.js', '**/vendor/**' ] }, // JavaScript 基础规则 { files: ['**/*.{js,jsx}'], extends: [js.configs.recommended], languageOptions: { ecmaVersion: 2024, sourceType: 'module', globals: { browser: 'readonly', node: 'readonly', process: 'readonly', console: 'readonly', Promise: 'readonly' } }, rules: { // 可能的错误 'no-unused-vars': ['warn', { argsIgnorePattern: '^_' }], 'no-console': ['warn', { allow: ['warn', 'error'] }], 'no-debugger': 'error', // 最佳实践 'eqeqeq': ['error', 'always'], 'curly': ['error', 'all'], 'default-case': 'error', 'no-eval': 'error', 'no-implied-eval': 'error', // 代码风格 'indent': ['error', 2], 'quotes': ['error', 'single', { avoidEscape: true }], 'semi': ['error', 'always'], 'comma-dangle': ['error', 'always-multiline'] } }, // TypeScript 配置 { files: ['**/*.{ts,tsx}'], extends: [ ...tsParser.configs.strictTypeChecked, ...tsParser.configs.stylisticTypeChecked ], languageOptions: { parserOptions: { projectService: true, tsconfigRootDir: import.meta.dirname } }, rules: { // TypeScript 特定规则 '@typescript-eslint/no-unused-vars': [ 'warn', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' } ], '@typescript-eslint/explicit-function-return-type': [ 'warn', { allowExpressions: true } ], '@typescript-eslint/no-explicit-any': 'warn', '@typescript-eslint/prefer-nullish-coalescing': 'error', '@typescript-eslint/prefer-optional-chain': 'error', '@typescript-eslint/strict-boolean-expressions': [ 'warn', { allowString: false, allowNumber: false } ] } }, // React 配置 { files: ['**/*.{jsx,tsx}'], plugins: { react, 'react-hooks': reactHooks }, settings: { react: { version: 'detect' } }, rules: { // React 最佳实践 'react/react-in-jsx-scope': 'off', 'react/prop-types': 'off', // 使用 TypeScript 代替 'react/jsx-no-target-blank': 'error', 'react/no-unescaped-entities': 'error', // Hooks 规则 'react-hooks/rules-of-hooks': 'error', 'react-hooks/exhaustive-deps': 'warn' } }, // 导入顺序规范 { files: ['**/*.{js,jsx,ts,tsx}'], plugins: { import: importPlugin }, rules: { 'import/order': [ 'error', { groups: [ 'builtin', 'external', 'internal', ['parent', 'sibling'], 'index', 'type' ], 'newlines-between': 'always', alphabetize: { order: 'asc', caseInsensitive: true } } ], 'import/no-duplicates': 'error', 'import/no-unresolved': 'error' } }, // 测试文件特殊规则 { files: ['**/*.test.{ts,tsx}', '**/*.spec.{ts,tsx}'], extends: ['plugin:testing-library/react'], rules: { '@typescript-eslint/no-unsafe-assignment': 'off', '@typescript-eslint/no-unsafe-call': 'off', '@typescript-eslint/no-unsafe-member-access': 'off' } }, // Prettier 冲突解决(放在最后) prettierConfig );

2.2 共享 ESLint 配置包(Monorepo)

# ===== packages/eslint-config/package.json ===== { "name": "@company/eslint-config", "version": "1.0.0", "type": "module", "exports": { "./base": "./base.js", "./react": "./react.js", "./typescript": "./typescript.js", "./prettier": "./prettier.js" }, "peerDependencies": { "eslint": "^9.0.0", "typescript": "^5.0.0" }, "dependencies": { "@eslint/js": "^9.0.0", "typescript-eslint": "^7.0.0", "eslint-plugin-react": "^7.34.0", "eslint-config-prettier": "^9.1.0" } } # ===== packages/eslint-config/react.js ===== import baseConfig from './base.js'; import react from 'eslint-plugin-react'; export default [ ...baseConfig, { files: ['**/*.{jsx,tsx}'], plugins: { react }, settings: { react: { version: 'detect' } }, rules: { 'react/react-in-jsx-scope': 'off', 'react/prop-types': 'off', 'react/jsx-no-target-blank': 'error', 'react/self-closing-comp': 'error', 'react/jsx-sort-props': ['warn', { callbacksLast: true, shorthandFirst: true, reservedFirst: true }] } } ]; # ===== 在项目中使用共享配置 ===== // apps/web-admin/eslint.config.js import companyConfig from '@company/eslint-config/react'; export default [ ...companyConfig, { rules: { // 项目特定覆盖 'no-console': 'error', '@typescript-eslint/no-explicit-any': 'error' } } ];

3. 代码格式化配置(Prettier)

3.1 Prettier 基础配置

# ===== .prettierrc / prettier.config.js ===== export default { // 每行最大字符数 printWidth: 100, // 缩进空格数 tabWidth: 2, // 使用空格而非 Tab useTabs: false, // 语句末尾加分号 semi: true, // 使用单引号 singleQuote: true, // 对象属性引号(仅在需要时添加) quoteProps: 'as-needed', // JSX 中使用单引号 jsxSingleQuote: false, // 尾随逗号(多行时添加) trailingComma: 'es5', // 对象字面量括号间加空格 bracketSpacing: true, // JSX 标签的 > 不另起一行 bracketSameLine: false, // 箭头函数单个参数不加括号 arrowParens: 'avoid', // 每个文件格式化的范围是整个文件 rangeStart: 0, rangeEnd: Infinity, // 不需要 @prettier 注释即可格式化 requirePragma: false, // 不在文件顶部插入 @format 注释 insertPragma: false, // Markdown 文本换行 proseWrap: 'preserve', // HTML 空格敏感性 htmlWhitespaceSensitivity: 'css', // Vue 文件中 <script> 和 <style> 标签内的代码缩进 vueIndentScriptAndStyle: false, // 换行符(根据系统自动检测) endOfLine: 'lf', // 格式化嵌入的代码(如 Markdown 中的代码块) embeddedLanguageFormatting: 'auto', // 单引号 HTML 属性 singleAttributePerLine: false }; # ===== .prettierignore ===== # 依赖目录 node_modules/ .pnp/ # 构建输出 dist/ build/ out/ .next/ .nuxt/ # 缓存文件 .cache/ .parcel-cache/ # 覆盖率报告 coverage/ # 锁定文件 package-lock.json yarn.lock pnpm-lock.yaml # 编译产物 **/*.min.js **/*.bundle.js # 第三方代码 vendor/ public/vendor/ # 配置文件(已格式化的除外) CHANGELOG.md

3.2 ESLint 与 Prettier 集成

# ===== 方案 1:使用 eslint-config-prettier(推荐)===== // eslint.config.js import prettierConfig from 'eslint-config-prettier'; export default [ // ... 其他配置 // 必须放在最后,禁用所有与 Prettier 冲突的规则 prettierConfig ]; # ===== 方案 2:使用 eslint-plugin-prettier ===== // 将 Prettier 作为 ESLint 规则运行 import prettierPlugin from 'eslint-plugin-prettier'; export default [ { plugins: { prettier: prettierPlugin }, rules: { 'prettier/prettier': 'error' } } ]; # ===== VS Code 设置(.vscode/settings.json)===== { "editor.formatOnSave": true, "editor.defaultFormatter": "esbenp.prettier-vscode", "editor.codeActionsOnSave": { "source.fixAll.eslint": "explicit" }, "eslint.validate": [ "javascript", "javascriptreact", "typescript", "typescriptreact" ], "[typescript]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, "[typescriptreact]": { "editor.defaultFormatter": "esbenp.prettier-vscode" } }

3.3 Husky + lint-staged 自动化

# ===== 安装依赖 ===== npm install --save-dev husky lint-staged npx husky init # ===== package.json 配置 ===== { "scripts": { "prepare": "husky", "lint": "eslint . --ext .ts,.tsx,.js,.jsx", "lint:fix": "eslint . --ext .ts,.tsx,.js,.jsx --fix", "format": "prettier --write \"**/*.{ts,tsx,js,jsx,json,md}\"", "format:check": "prettier --check \"**/*.{ts,tsx,js,jsx,json,md}\"" }, "lint-staged": { "*.{ts,tsx,js,jsx}": [ "eslint --fix", "prettier --write" ], "*.{json,md,yml,yaml}": [ "prettier --write" ] } } # ===== .husky/pre-commit ===== #!/usr/bin/env sh . "/usr/local/share/nvm/nvm.sh" nvm use default npx lint-staged # ===== .husky/commit-msg ===== #!/usr/bin/env sh . "/usr/local/share/nvm/nvm.sh" nvm use default npx commitlint --edit $1

4. 后端代码规范配置(CheckStyle)

4.1 Maven 项目 CheckStyle 配置

# ===== pom.xml 配置 ===== <project> <build> <plugins> <!-- CheckStyle 插件 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-checkstyle-plugin</artifactId> <version>3.3.1</version> <configuration> <configLocation>checkstyle/checkstyle.xml</configLocation> <encoding>UTF-8</encoding> <consoleOutput>true</consoleOutput> <failsOnError>true</failsOnError> <failOnViolation>true</failOnViolation> <violationSeverity>warning</violationSeverity> <includeTestSourceDirectory>true</includeTestSourceDirectory> <linkXRef>false</linkXRef> </configuration> <executions> <execution> <id>validate</id> <phase>validate</phase> <goals> <goal>check</goal> </goals> </execution> </executions> <dependencies> <dependency> <groupId>com.puppycrawl.tools</groupId> <artifactId>checkstyle</artifactId> <version>10.14.0</version> </dependency> </dependencies> </plugin> </plugins> </build> </project> # ===== checkstyle/checkstyle.xml ===== <?xml version="1.0"?> <!DOCTYPE module PUBLIC "-//Checkstyle//DTD Checkstyle Configuration 1.3//EN" "https://checkstyle.org/dtds/configuration_1_3.dtd"> <module name="Checker"> <property name="charset" value="UTF-8"/> <property name="severity" value="warning"/> <property name="fileExtensions" value="java, properties, xml"/> <!-- 文件头检查 --> <module name="RegexpHeader"> <property name="headerFile" value="${checkstyle.header.file}"/> <property name="fileExtensions" value="java"/> </module> <!-- 文件大小检查 --> <module name="FileLength"> <property name="max" value="2000"/> </module> <!-- 行长度检查 --> <module name="LineLength"> <property name="max" value="120"/> <property name="ignorePattern" value="^package.*|^import.*|a href|href|http://|https://|ftp://"/> </module> <!-- 禁止 Tab --> <module name="FileTabCharacter"> <property name="eachLine" value="true"/> </module> <!-- 文件末尾换行 --> <module name="NewlineAtEndOfFile"/> <module name="TreeWalker"> <!-- 代码规范 --> <module name="OuterTypeFilename"/> <module name="IllegalTokenText"> <property name="tokens" value="STRING_LITERAL, CHAR_LITERAL"/> <property name="format" value="\\\\u00(09|0(a|A)|0(c|C)|0(d|D)|22|27|5(C|c))|\\\\(0(10|11|12|14|15|42|47)|134)"> <property name="message" value="Consider using special escape sequence instead of octal value or Unicode escaped value."/> </module> <!-- 避免转义字符 --> <module name="AvoidEscapedUnicodeCharacters"> <property name="allowEscapesForControlCharacters" value="true"/> <property name="allowByTailComment" value="true"/> <property name="allowNonPrintableEscapes" value="true"/> </module> <!-- 行尾通配符导入 --> <module name="AvoidStarImport"/> <!-- 类导入顺序 --> <module name="CustomImportOrder"> <property name="sortImportsInGroupAlphabetically" value="true"/> <property name="separateLineBetweenGroups" value="true"/> <property name="customImportOrderRules" value="STATIC###THIRD_PARTY_PACKAGE"/> </module> <!-- 方法参数数量限制 --> <module name="ParameterNumber"> <property name="max" value="8"/> <property name="tokens" value="METHOD_DEF"/> </module> <!-- 方法复杂度限制 --> <module name="CyclomaticComplexity"> <property name="max" value="15"/> </module> <!-- 嵌套深度限制 --> <module name="NestedForDepth"> <property name="max" value="2"/> </module> <module name="NestedIfDepth"> <property name="max" value="3"/> </module> <!-- 命名规范 --> <module name="PackageName"> <property name="format" value="^[a-z]+(\.[a-z][a-z0-9]*)*$"/> </module> <module name="TypeName"> <property name="format" value="^[A-Z][a-zA-Z0-9]*$"/> </module> <module name="MethodName"> <property name="format" value="^[a-z][a-z0-9][a-zA-Z0-9_]*$"/> </module> <module name="ParameterName"> <property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/> </module> <module name="LambdaParameterName"> <property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/> </module> <module name="CatchParameterName"> <property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/> </module> <module name="LocalVariableName"> <property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/> </module> <module name="ClassTypeParameterName"> <property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/> </module> <module name="MethodTypeParameterName"> <property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/> </module> <!-- 空代码块检查 --> <module name="EmptyBlock"> <property name="option" value="TEXT"/> <property name="tokens" value="LITERAL_TRY, LITERAL_FINALLY, LITERAL_IF, LITERAL_ELSE, LITERAL_SWITCH"/> </module> <!-- 右花括号位置 --> <module name="RightCurly"> <property name="id" value="RightCurlySame"/> <property name="tokens" value="LITERAL_TRY, LITERAL_CATCH, LITERAL_FINALLY, LITERAL_IF, LITERAL_ELSE"/> </module> <module name="RightCurly"> <property name="id" value="RightCurlyAlone"/> <property name="option" value="alone"/> <property name="tokens" value="CLASS_DEF, METHOD_DEF, CTOR_DEF, LITERAL_FOR, LITERAL_WHILE, STATIC_INIT, INSTANCE_INIT"/> </module> <!-- 空白行规范 --> <module name="WhitespaceAfter"> <property name="tokens" value="COMMA, SEMI, TYPECAST"/> </module> <module name="NoWhitespaceBefore"> <property name="tokens" value="COMMA, SEMI, POST_INC, POST_DEC, DOT"/> </module> <!-- 操作符换行 --> <module name="OperatorWrap"> <property name="option" value="NL"/> <property name="tokens" value="BAND, BOR, BSR, BXOR, DIV, EQUAL, GE, GT, LAND, LE, LITERAL_INSTANCEOF, LOR, LT, MINUS, MOD, NOT_EQUAL, PLUS, QUESTION, SL, SR, STAR, METHOD_REF"/> </module> <!-- 注解位置 --> <module name="AnnotationLocation"> <property name="id" value="AnnotationLocationMostCases"/> <property name="tokens" value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, METHOD_DEF, CTOR_DEF"/> </module> <module name="AnnotationLocation"> <property name="id" value="AnnotationLocationVariables"/> <property name="tokens" value="VARIABLE_DEF"/> <property name="allowSamelineMultipleAnnotations" value="true"/> </module> <!-- Javadoc 规范 --> <module name="MissingJavadocMethod"> <property name="scope" value="public"/> <property name="minLineCount" value="2"/> <property name="allowedAnnotations" value="Override, Test"/> </module> <module name="MissingJavadocType"> <property name="scope" value="protected"/> <property name="tokens" value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, RECORD_DEF, ANNOTATION_DEF"/> <property name="excludeScope" value="nothing"/> </module> </module> </module>

4.2 Spotless 代码格式化(Gradle)

# ===== build.gradle 配置 ===== plugins { id 'java' id 'com.diffplug.spotless' version '6.25.0' } spotless { java { // 使用 Google Java Format googleJavaFormat('1.22.0') // 移除未使用的 import removeUnusedImports() // 格式化 import 顺序 importOrder('java', 'javax', 'org', 'com') // 许可证头 licenseHeaderFile rootProject.file('spotless/license.java') // 排除文件 targetExclude '**/generated/**' } format 'misc' { target '**/*.md', '**/*.gradle', '**/*.gitignore' trimTrailingWhitespace() leadingTabsToSpaces(2) endWithNewline() } } // 在构建前执行格式化检查 tasks.named('build') { dependsOn tasks.named('spotlessCheck') } # ===== spotless/license.java ===== /* * Copyright © ${YEAR} Your Company. All rights reserved. * Licensed under the Apache License, Version 2.0 */

5. SonarQube 代码质量平台

5.1 SonarQube 配置

# ===== sonar-project.properties (前端) ===== # 项目基本信息 sonar.projectKey=myapp-frontend sonar.projectName=MyApp Frontend sonar.projectVersion=1.0.0 # 源代码位置 sonar.sources=src sonar.tests=tests sonar.exclusions=**/node_modules/**,**/dist/**,**/build/**,**/coverage/** # TypeScript 配置 sonar.language=ts,tsx sonar.typescript.tsconfigPath=tsconfig.json # 测试覆盖率 sonar.javascript.lcov.reportPaths=coverage/lcov.info sonar.coverage.exclusions=**/*.test.ts,**/*.spec.ts,**/__tests__/**,**/mocks/** # 代码重复检测 sonar.cpd.exclusions=**/*.test.ts,**/*.spec.ts # 质量问题门禁 sonar.qualitygate.wait=true sonar.qualitygate.timeout=300 # ===== pom.xml 配置(后端 Java)===== <properties> <sonar.host.url>http://sonarqube.yourcompany.com:9000</sonar.host.url> <sonar.login>${SONAR_TOKEN}</sonar.login> <sonar.projectKey>myapp-backend</sonar.projectKey> <sonar.projectName>MyApp Backend</sonar.projectName> <sonar.sources>src/main/java</sonar.sources> <sonar.tests>src/test/java</sonar.tests> <sonar.java.binaries>target/classes</sonar.java.binaries> <sonar.junit.reportsPath>target/surefire-reports</sonar.junit.reportsPath> <sonar.jacoco.reportPath>target/jacoco.exec</sonar.jacoco.reportPath> <sonar.coverage.exclusions>**/test/**,**/*Test.java</sonar.coverage.exclusions> </properties> <build> <plugins> <!-- JaCoCo 代码覆盖率 --> <plugin> <groupId>org.jacoco</groupId> <artifactId>jacoco-maven-plugin</artifactId> <version>0.8.11</version> <executions> <execution> <goals> <goal>prepare-agent</goal> </goals> </execution> <execution> <id>report</id> <phase>test</phase> <goals> <goal>report</goal> </goals> </execution> </executions> </plugin> </plugins> </build> # ===== Jenkins Pipeline 集成 ===== stage('SonarQube Analysis') { steps { withSonarQubeEnv('sonarqube-prod') { sh ''' mvn clean verify sonar:sonar \\ -Dsonar.projectKey=${PROJECT_KEY} \\ -Dsonar.host.url=${SONAR_HOST_URL} \\ -Dsonar.login=${SONAR_TOKEN} ''' } } } stage('Quality Gate') { steps { timeout(time: 1, unit: 'HOURS') { waitForQualityGate abortPipeline: true } } }

5.2 质量门禁标准

指标 新代码 整体代码 严重级别
Bugs 0 < 10 🔴 Error
Vulnerabilities 0 0 🔴 Error
Security Hotspots Reviewed < 5 🟡 Warning
Code Smells < 15 < 200 🟡 Warning
测试覆盖率 > 80% > 70% 🟡 Warning
重复代码 < 3% < 5% 🟡 Warning
认知复杂度 < 15/方法 - 🔵 Info
技术债务比率 < 5% < 10% 🟡 Warning

6. Git 提交信息规范(Commitlint)

6.1 Commitlint 配置

# ===== 安装依赖 ===== npm install --save-dev @commitlint/cli @commitlint/config-conventional # ===== commitlint.config.js ===== export default { extends: ['@commitlint/config-conventional'], rules: { // type 枚举值 'type-enum': [ 2, 'always', [ 'feat', // 新功能 'fix', // Bug 修复 'docs', // 文档更新 'style', // 代码样式(不影响功能) 'refactor', // 重构 'perf', // 性能优化 'test', // 测试用例 'chore', // 构建/工具变动 'revert', // 回退 'merge', // 合并分支 'ci', // CI 配置 'build' // 构建系统 ] ], // type 大小写 'type-case': [2, 'always', 'lower-case'], // type 不能为空 'type-empty': [2, 'never'], // scope 不能为空(可选) 'scope-empty': [1, 'never'], // scope 枚举值 'scope-enum': [ 1, 'always', [ 'auth', 'user', 'order', 'payment', 'api', 'ui', 'db', 'config', 'deps', 'release' ] ], // subject 大小写 'subject-case': [ 2, 'never', ['sentence-case', 'start-case', 'pascal-case', 'upper-case'] ], // subject 不能为空 'subject-empty': [2, 'never'], // subject 结尾无句号 'subject-full-stop': [2, 'never', '.'], // header 最大长度 'header-max-length': [2, 'always', 100], // body 最大长度 'body-max-line-length': [2, 'always', 100], // footer 前缀 'footer-leading-blank': [2, 'always'], 'footer-max-line-length': [2, 'always', 100] }, // 提示消息 prompt: { questions: { type: { description: '选择变更类型', enum: { feat: { description: '新功能', title: 'Features', emoji: '✨' }, fix: { description: 'Bug 修复', title: 'Bug Fixes', emoji: '🐛' }, docs: { description: '文档更新', title: 'Documentation', emoji: '📝' }, style: { description: '代码样式', title: 'Styles', emoji: '💄' }, refactor: { description: '代码重构', title: 'Code Refactoring', emoji: '♻️' }, perf: { description: '性能优化', title: 'Performance Improvements', emoji: '⚡️' }, test: { description: '测试用例', title: 'Tests', emoji: '✅' }, chore: { description: '其他改动', title: 'Chores', emoji: '🔧' } } } } } }; # ===== 提交示例 ===== # ✅ 正确的提交信息 feat(auth): add JWT token authentication fix(user): resolve login timeout issue docs(api): update REST API documentation refactor(order): simplify order processing logic perf(db): optimize database query performance test(payment): add unit tests for payment service chore(deps): upgrade React to v18.3.0 ci(jenkins): add deployment pipeline configuration # ❌ 错误的提交信息 update code # type 缺失 FIX: bug fix # type 应小写 feat:no space after colon # 冒号后需空格 feat(auth):add feature. # subject 不应以句号结尾

6.2 Commitizen 交互式提交

# ===== 安装依赖 ===== npm install --save-dev commitizen cz-conventional-changelog # ===== package.json 配置 ===== { "config": { "commitizen": { "path": "./node_modules/cz-conventional-changelog" } }, "scripts": { "commit": "cz" } } # ===== 使用方式 ===== npm run commit # 或 npx cz # 交互式问答: ? Select the type of change you are committing: (Use arrow keys) ❯ feat: A new feature fix: A bug fix docs: Documentation only changes style: Changes that do not affect the meaning of the code refactor: A code change that neither fixes a bug nor adds a feature perf: A code change that improves performance test: Adding missing tests or correcting existing tests chore: Changes to the build process or auxiliary tools ? What is the scope of this change (e.g. component or file name): auth ? Write a short, imperative tense description of the change: add JWT token authentication with refresh mechanism ? Provide a longer description of the change: (press enter to skip) Implemented stateless JWT authentication with: - Access token (15 minutes expiry) - Refresh token (7 days expiry) - Automatic token rotation ? Are there any breaking changes? No ? Does this change affect any open issues? Yes ? Add issue references (e.g. "fix #123", "re #123".): fix #100, fix #102

7. 依赖管理方案(pnpm/npm/yarn)

7.1 pnpm 工作空间配置(推荐)

# ===== 根目录 package.json ===== { "name": "enterprise-monorepo", "private": true, "packageManager": "pnpm@9.0.0", "scripts": { "install:all": "pnpm install --recursive", "build:all": "pnpm run -r build", "test:all": "pnpm run -r test", "lint:all": "pnpm run -r lint", "clean": "pnpm clean -r && rm -rf node_modules" }, "devDependencies": { "typescript": "^5.4.0", "eslint": "^9.0.0", "prettier": "^3.2.0", "vitest": "^1.3.0" } } # ===== pnpm-workspace.yaml ===== packages: # 所有包 - 'packages/*' # 所有应用 - 'apps/*' # 所有服务 - 'services/*' # 排除特定目录 - '!**/test/**' # ===== .npmrc 配置 ===== # 使用硬链接,节省磁盘空间 shamefully-hoist=false # 严格对等模式,避免幽灵依赖 strict-peer-dependencies=true # 自动安装 peer dependencies auto-install-peers=true # 使用国内镜像(可选) registry=https://registry.npmmirror.com/ # 仅当 lockfile 存在时安装 prefer-offline=true # 生产环境不安装 devDependencies # production=true # 忽略 scripts 脚本(安全考虑) # ignore-scripts=true # ===== 子项目 package.json ===== { "name": "@company/ui-components", "version": "1.0.0", "dependencies": { "react": "^18.3.0", "react-dom": "^18.3.0" }, "devDependencies": { "@company/eslint-config": "workspace:*", "@types/react": "^18.3.0", "typescript": "^5.4.0" }, "peerDependencies": { "react": "^18.0.0" } }

7.2 依赖版本管理策略

# ===== 版本号语义(SemVer)===== ^1.2.3 = >=1.2.3 < 2.0.0 # 允许 minor 和 patch 更新 ~1.2.3 = >=1.2.3 <1.3.0 # 仅允许 patch 更新 1.2.3 = 1.2.3 # 精确版本 * = >=0.0.0 # 任意版本 # ===== 推荐策略 ===== 生产依赖: 使用 ^ 符号(允许向后兼容的更新) 开发依赖: 使用 ^ 符号或精确版本 框架核心: 使用 ~ 符号(如 React/Vue,避免 major 升级) 内部包: 使用 workspace: 协议 # ===== 依赖分类管理 ===== { "dependencies": { # 运行时必需的依赖 "react": "^18.3.0", "axios": "^1.6.0" }, "devDependencies": { # 开发和构建时使用的依赖 "typescript": "^5.4.0", "vite": "^5.2.0" }, "peerDependencies": { # 宿主环境应提供的依赖(库项目使用) "react": "^18.0.0" }, "optionalDependencies": { # 可选依赖,安装失败不影响整体 "fsevents": "^2.3.0" }, "resolutions": { # 强制解析特定版本(解决依赖冲突) "**/lodash": "^4.17.21" } } # ===== 依赖更新命令 ===== # 查看可更新的依赖 pnpm outdated npm outdated yarn outdated # 更新所有依赖到最新版本 pnpm update -r npm update yarn upgrade # 交互式更新(推荐) npx npm-check-updates -i pnpm up -i # 更新特定依赖 pnpm update react react-dom npm update react # 更新到最新 major 版本 ncu -u pnpm update -r --latest

8. 依赖安全与漏洞扫描

8.1 安全扫描工具

# ===== npm audit(内置)===== # 检查漏洞 npm audit # 自动修复 npm audit fix # 强制修复(可能破坏性) npm audit fix --force # 生成详细报告 npm audit --json > audit-report.json # ===== pnpm audit ===== pnpm audit pnpm audit fix # ===== Snyk(第三方)===== npm install -g snyk snyk auth snyk test snyk monitor snyk wizard # 交互式修复 # ===== Dependabot(GitHub 自动 PR)===== # .github/dependabot.yml version: 2 updates: # npm 依赖更新 - package-ecosystem: "npm" directory: "/" schedule: interval: "weekly" day: "monday" time: "09:00" timezone: "Asia/Shanghai" open-pull-requests-limit: 10 reviewers: - "security-team" labels: - "dependencies" - "security" commit-message: prefix: "chore(deps)" groups: production-dependencies: patterns: - "*" exclude-patterns: - "*@dev*" - "*@types*" # GitHub Actions 更新 - package-ecosystem: "github-actions" directory: "/" schedule: interval: "weekly" # ===== Renovate(高级依赖管理)===== # renovate.json { "extends": [ "config:recommended", ":semanticCommits", ":automergeMinor" ], "schedule": ["every weekend"], "prHourlyLimit": 2, "prConcurrentLimit": 10, "labels": ["dependencies"], "reviewers": ["team:frontend"], "packageRules": [ { "matchUpdateTypes": ["minor", "patch"], "matchCurrentVersion": "!/^0/", "automerge": true }, { "matchDepTypes": ["devDependencies"], "automerge": true }, { "matchPackagePatterns": ["^@company/"], "enabled": false } ] }

8.2 CI/CD 安全检查

# ===== Jenkins Pipeline 集成 ===== stage('Security Scan') { steps { script { // npm audit sh ''' cd apps/web-admin npm audit --audit-level=high ''' // Snyk 扫描 sh ''' snyk test --severity-threshold=high || true ''' } } post { failure { echo '❌ Security vulnerabilities detected!' slackSend(color: 'danger', message: "Security scan failed: ${BUILD_URL}") } } } # ===== GitHub Actions ===== name: Security Scan on: push: branches: [main, develop] pull_request: branches: [main] schedule: - cron: '0 2 * * 1' # 每周一凌晨 2 点 jobs: security: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '20' cache: 'pnpm' - name: Install dependencies run: pnpm install --frozen-lockfile - name: Run npm audit run: pnpm audit --audit-level=high - name: Run Snyk uses: snyk/actions/node@master env: SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} with: severity-threshold: high - name: Upload SARIF report uses: github/codeql-action/upload-sarif@v3 if: always() with: sarif_file: snyk.sarif

9. CI/CD 集成自动化检查

9.1 完整 CI/CD 流水线

pipeline { agent any options { buildDiscarder(logRotator(numToKeepStr: '20')) timeout(time: 1, unit: 'HOURS') timestamps() disableConcurrentBuilds() } environment { NODE_VERSION = '20' JAVA_VERSION = '21' } stages { stage('Checkout') { steps { checkout scm } } stage('Install Dependencies') { steps { sh 'pnpm install --frozen-lockfile' } } stage('Code Quality Checks') { parallel { stage('ESLint') { steps { sh 'pnpm run lint:all' } } stage('Prettier') { steps { sh 'pnpm run format:check' } } stage('CheckStyle') { steps { sh 'mvn checkstyle:check' } } stage('Type Check') { steps { sh 'pnpm run -r type-check' } } } } stage('Unit Tests') { steps { sh 'pnpm run test:all --coverage' } post { always { junit allowEmptyResults: true, testResults: '**/junit-reports/*.xml' publishHTML([ allowMissing: false, alwaysLinkToLastBuild: true, keepAll: true, reportDir: 'coverage', reportFiles: 'lcov-report/index.html', reportName: 'Coverage Report' ]) } } } stage('Build') { steps { sh 'pnpm run build:all' sh 'mvn clean package -DskipTests' } } stage('Security Scan') { steps { sh 'pnpm audit --audit-level=high || true' sh 'snyk test --severity-threshold=high || true' } } stage('SonarQube Analysis') { steps { withSonarQubeEnv('sonarqube-prod') { sh 'mvn sonar:sonar' } } } stage('Quality Gate') { steps { timeout(time: 30, unit: 'MINUTES') { waitForQualityGate abortPipeline: true } } } stage('Build Docker Image') { steps { script { def imageName = "harbor.yourcompany.com/app/backend:${BUILD_NUMBER}" sh """ docker build -t ${imageName} . docker push ${imageName} """ } } } } post { success { echo '✅ All checks passed!' slackSend(color: 'good', message: "Build #${BUILD_NUMBER} succeeded!") } failure { echo '❌ Build failed!' slackSend(color: 'danger', message: "Build #${BUILD_NUMBER} failed!") } unstable { echo '⚠️ Build is unstable!' } } }

10. 最佳实践与工具链整合

🎯 实施路线图

  • 第 1 周:基础工具安装配置
  • 第 2 周:IDE 集成与团队培训
  • 第 3 周:CI/CD 卡点实施
  • 第 4 周:遗留代码渐进修复
  • 持续:定期回顾优化

📊 度量指标

  • 代码规范违规数趋势
  • 构建成功率与时长
  • 代码覆盖率变化
  • 技术债务比率
  • 安全漏洞数量

🛠️ 工具链清单

  • ESLint 9.x + Prettier 3.x
  • CheckStyle 10.x + Spotless
  • SonarQube 10.x
  • Commitlint + Husky
  • pnpm 9.x + Snyk

✅ 成功要素

  • 管理层支持与推动
  • 全员参与和认同
  • 自动化优先原则
  • 渐进式改进策略
  • 持续优化文化
🎉 代码规范与依赖管理最佳实践总结:
  1. 工具先行:用自动化工具替代人工检查
  2. IDE 集成:实时反馈,问题早发现
  3. CI 卡点:不合格代码无法合并
  4. 渐进改进:新项目严格,老项目逐步修复
  5. 安全第一:依赖漏洞零容忍
  6. 文档同步:规范变更及时更新文档
  7. 定期审计:每季度审查规范和依赖