手把手带你学会如何配置工程规范

321 阅读8分钟

开发规范使用文档

特别声明

未经过本人同意,请不要随意转载文章

本项目主要介绍以下几个方面:
  1. 总体用了哪些来规范化及其作用;
  2. 如何在现有规约基础上修改;
  3. 怎么集成进新的项目;
  4. 最后介绍如何来使用;

一、用到了哪些来进行规范化?

从作为一名编码人员出发,我们开始一个项目,从技术调研->代码编写->提交代码->打包->部署这条线路来完成自己的工作任务,那么我们在约定规范的时候,自然也是在这中间去干预一些违规操作和错误操作。

按照上面路线那么这过程我们能干预的主要过程有如下:

  • 技术调研:我们可以同意编译器例如前端:vscode,那么编辑器需要去做到一些统一的配置项,例如:settings.json/extensions.json等等,这些配置我们统一放置.vscode文件夹下面
  • 代码编写:每个人编写代码习惯不同,例如有些人喜欢两个函数直接留出多个回车,那么我们可以通过配置,或者编写一些不具有结构性的代码,那么Prettier就是一个很好的工具,帮助我们形成特定结构代码,并且统一规范;当然,在编写时候如果出现问题ESLint能够快速帮你定位已知问题,很好的能够在打包时候,规避这些问题等
  • 提交代码:提交代码的时候每个人修改的部分都不同,那么在提交的时候我们可能错中复杂,当然,这样在提交的时候省去了很多事儿,但是在代码版本管理进行维护的时候,导致我们无法快速找到对应的功能版本,于是乎就出现了commitlint和git cz工具,帮助我们规范制约提交
  • 打包:在打包的时候,应该先进行项目代码检测和语法检查,遇到比如有变量未被使用的,应该及时给于报错信息,并且停止打包,这时候Prettier和ESLint有派上用场了。
  • 当然还有很多,比如在commit时候也会进行语法检查等操作,主要通过husky进行调用钩子函数lint-staged来进行语法检查等操作。
  • 总之,为了更好的规范化,大家一定要按照如下操作,后续进行开发,虽然开始比较难受,但是,习惯一段时间后,以后的维护成本将让大家舒舒服服,所谓先苦后甜。

二、如何再现有基础上来修改?

1.依赖安装
"devDependencies": {
    "@typescript-eslint/eslint-plugin": "^7.1.0",
    "@typescript-eslint/parser": "^7.1.0",
    "@vitejs/plugin-vue": "^5.0.4",
    "@vue/eslint-config-prettier": "^9.0.0",
    "@vue/eslint-config-typescript": "^12.0.0",
    "cz-git": "^1.8.0",
    "eslint": "^8.57.0",
    "eslint-plugin-prettier": "^5.1.3",
    "eslint-plugin-vue": "^9.22.0",
    "husky": "^9.0.11",
    "lint-staged": "^15.2.2",
    "prettier": "^3.2.5",
    "vue-eslint-parser": "^9.4.2",
  },

  "lint-staged": {
    "*.{vue,js,jsx,ts,tsx}": [
      "eslint --fix",
      "prettier --write"
    ],
    "*.{css,less,scss,html,md}": [
      "prettier --write"
    ],
    "package.json": [
      "prettier --write"
    ]
  },
  "config": {
    "commitizen": {
      "path": "node_modules/cz-git"
    }
  }

上述devDependencies依赖各自什么作用大家自行百度哈,另外lint-staged和config配置在后续会提到用处,可以先配上。

2.配置文件

以下都是在项目根目录下创建如下文件:

// .commitlintrc.js
/** @type {import('cz-git').UserConfig} */
module.exports = {
  rules: {
    // @see: https://commitlint.js.org/#/reference-rules
  },
  prompt: {
    alias: { fd: "docs: fix typos" },
    messages: {
      type: "选择你要提交的类型 :",
      scope: "选择一个提交范围(可选):",
      customScope: "请输入自定义的提交范围 :",
      subject: "填写简短精炼的变更描述 :\n",
      body: '填写更加详细的变更描述(可选)。使用 "|" 换行 :\n',
      breaking: '列举非兼容性重大的变更(可选)。使用 "|" 换行 :\n',
      footerPrefixesSelect: "选择关联issue前缀(可选):",
      customFooterPrefix: "输入自定义issue前缀 :",
      footer: "列举关联issue (可选) 例如: #31, #I3244 :\n",
      confirmCommit: "是否提交或修改commit ?"
    },
    types: [
      { value: "🪶 feat", name: "feat: 🪶 新增功能 | A new feature" },
      { value: "🐦 fix", name: "fix: 🐦 修复缺陷 | A bug fix" },
      { value: "📖 docs", name: "docs: 📖 文档更新 | Documentation only changes" },
      { value: "😰 style", name: "style: 😰 代码格式 | Changes that do not affect the meaning of the code" },
      {
        value: "💩 refactor",
        name: "refactor: 💩 代码重构 | A code change that neither fixes a bug nor adds a feature"
      },
      { value: "💖 perf", name: "perf: 💖 性能提升 | A code change that improves performance" },
      { value: "🙏 test", name: "test: 🙏  测试相关 | Adding missing tests or correcting existing tests" },
      { value: "🏗️ build", name: "build: 🏗️ 构建相关 | Changes that affect the build system or external dependencies" },
      { value: "🏛️ ci", name: "ci: 🏛️ 持续集成 | Changes to our CI configuration files and scripts" },
      { value: "🔙 revert", name: "revert: 🔙 回退代码 | Revert to a commit" },
      { value: "🌿 chore", name: "chore: 🌿 其他修改 | Other changes that do not modify src or test files" }
    ],
    useEmoji: true,
    emojiAlign: "center",
    useAI: false,
    aiNumber: 1,
    themeColorCode: "",
    scopes: [],
    allowCustomScopes: true,
    allowEmptyScopes: true,
    customScopesAlign: "bottom",
    customScopesAlias: "custom",
    emptyScopesAlias: "empty",
    upperCaseSubject: false,
    markBreakingChangeMode: false,
    allowBreakingChanges: ["feat", "fix"],
    breaklineNumber: 100,
    breaklineChar: "|",
    skipQuestions: [],
    issuePrefixes: [
      // 如果使用 gitee 作为开发管理
      { value: "link", name: "link:     链接 ISSUES 进行中" },
      { value: "closed", name: "closed:   标记 ISSUES 已完成" }
    ],
    customIssuePrefixAlign: "top",
    emptyIssuePrefixAlias: "skip",
    customIssuePrefixAlias: "custom",
    allowCustomIssuePrefix: true,
    allowEmptyIssuePrefix: true,
    confirmColorize: true,
    maxHeaderLength: Infinity,
    maxSubjectLength: Infinity,
    minSubjectLength: 0,
    scopeOverrides: undefined,
    defaultBody: "",
    defaultIssues: "",
    defaultScope: "",
    defaultSubject: ""
  }
}

在1中提到的package.json中的config配置需要和这边对应关联起来,具体原因可以去官网查看。以上主要跟对git cz结合commitizen的配置使用,更多信息参考:(cz-git.qbb.sh/zh/guide/)


# 配置文件.editorconfig
# 修改配置后重启编辑器
# 配置项文档:https://editorconfig.org/

# 告知 EditorConfig 插件,当前即是根文件
root = true

# 适用全部文件
[*]
## 设置字符集
charset = utf-8
## 缩进风格 space | tab,建议 space(会自动继承给 Prettier)
indent_style = space
## 缩进的空格数(会自动继承给 Prettier)
indent_size = 2
## 换行符类型 lf | cr | crlf,一般都是设置为 lf
end_of_line = lf
## 是否在文件末尾插入空白行
insert_final_newline = true
## 是否删除一行中的前后空格
trim_trailing_whitespace = true

# 适用 .md 文件
[*.md]
insert_final_newline = false
trim_trailing_whitespace = false

以上.editorconfig主要目的是为了适配vscode插件EditorConfig for VS Code读取信息


// 配置文件.eslintrc.cjs
module.exports = {
  root: true,
  env: {
    browser: true,
    es6: true,
    node: true
  },
  extends: [
    "plugin:vue/vue3-essential",
    "eslint:recommended",
    "@vue/typescript/recommended",
    "@vue/prettier",
    "@vue/eslint-config-typescript"
  ],
  overrides: [
    {
      env: {
        node: true
      },
      files: [".eslintrc.{js,cjs}"],
      parserOptions: {
        sourceType: "script"
      }
    }
  ],
  parser: "vue-eslint-parser",
  parserOptions: {
    parser: "@typescript-eslint/parser",
    ecmaVersion: 2020,
    sourceType: "module",
    jsxPragma: "React",
    ecmaFeatures: {
      jsx: true,
      tsx: true
    }
  },
  rules: {
    // TS
    "@typescript-eslint/no-explicit-any": "off",
    "no-debugger": "off",
    "@typescript-eslint/explicit-module-boundary-types": "off",
    "@typescript-eslint/ban-types": "off",
    "@typescript-eslint/ban-ts-comment": "off",
    "@typescript-eslint/no-empty-function": "off",
    "@typescript-eslint/no-non-null-assertion": "off",
    "@typescript-eslint/no-unused-vars": [
      "error",
      {
        argsIgnorePattern: "^_",
        varsIgnorePattern: "^_"
      }
    ],
    "no-unused-vars": [
      "error",
      {
        argsIgnorePattern: "^_",
        varsIgnorePattern: "^_"
      }
    ],
    // Vue
    "vue/no-v-html": "off",
    "vue/require-default-prop": "off",
    "vue/require-explicit-emits": "off",
    "vue/multi-word-component-names": "off",
    "vue/html-self-closing": [
      "error",
      {
        html: {
          void: "always",
          normal: "always",
          component: "always"
        },
        svg: "always",
        math: "always"
      }
    ],
    // Prettier
    "prettier/prettier": [
      "error",
      {
        endOfLine: "auto"
      }
    ]
  }
}

以上.eslintrc.cjs主要为了配置校验语法规则,更多信息参考:(eslint.org/docs/latest…)


// 配置文件prettier.config.js
/**
 * 修改配置后重启编辑器
 * 配置项文档:https://prettier.io/docs/en/configuration.html
 * @type {import("prettier").Config}
 */

export default {
  /** 每一行的宽度 */
  printWidth: 120,
  /** 在对象中的括号之间是否用空格来间隔 */
  bracketSpacing: true,
  /** 箭头函数的参数无论有几个,都要括号包裹 */
  arrowParens: "always",
  /** 换行符的使用 */
  endOfLine: "auto",
  /** 是否采用单引号 */
  singleQuote: false,
  /** 对象或者数组的最后一个元素后面不要加逗号 */
  trailingComma: "none",
  /** 是否加分号 */
  semi: false
}

以上prettier.config.js主要为了配置校验语法规则,更多信息参考:(prettier.io/docs/en/opt…)


# .husky/pre-commit
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npx lint-staged

安装husky依赖后,package.json下的scripts对象中会有"prepare": "husky install"通过pnpm prepare执行后自动在根目录下创建.husky文件夹,在当前文件夹下面创建文件pre-commit,除此之外,在1中package.json中提到的lint-staged配置是在执行时候读取配置信息就是那儿的,具体还有其他配置,详情请参考:(github.com/lint-staged…)


// .vscode/extensions.json
{
  "recommendations": [
    "editorconfig.editorconfig",
    "dbaeumer.vscode-eslint",
    "esbenp.prettier-vscode",
    "vue.vscode-typescript-vue-plugin",
    "vue.volar",
    "wiensss.region-highlighter"
  ]
}

这是在启动项目时候检测你项目中是否安装上面的这些插件,如果没有安装,会在启动的时候右下角提示框中提示你安装这些插件


// .vscode/settings.json
{
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": "explicit"
  },
  "[vue]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[javascript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[typescript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[json]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[jsonc]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[html]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[css]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[scss]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  // 设置全部语言在保存时自动格式化
  "editor.formatOnSave": true
}

vscode在格式化的时候参考以上优先级进行保存格式化,其中格式化的语言有如上


3.其他配置文件
  • .vscode/hook.code-snippets和vue.code-snippets:是编写hook的代码快速生成模版,prefix表示提示前缀,body表示模块,description表示描述作用;
  • .eslintcache:eslint缓存文件;
  • .gitignorre:提交git忽略哪些文件上传;
  • .prettierignore:prettier进行语法检查时候忽略去检查哪些文件;
  • .npmrc:可以配置源,或者解决幽灵依赖等问题,具体可百度
4.最后

以上搭配了配置和具体配置对应下的官网链接,以上配置信息仅供参考,具体完善信息,还需要大家一起完善文档,如果大家发现新的比如检测语法的规则,加入进去,可以继续补充文档内容。或者知道某个文件里面某个配置项具体作用也可以做适当完善。毕竟一个人作用是有限的,团队的作用是无限的。

三、如何集成到新的项目?

知道上述各自文件作用和配置后,只需要复制粘贴进自己项目,对应自己的习惯进行适当修改就行

四、如何使用?

举例一个场景:

场景大致情况:我们增加了个组件B,然后进行组件B提交,其中编写了一些不规范的代码,声明一个变量a,不去使用,然后进行提交,观察报错,然后解决问题后,再次提交后,成功

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png