统一前端工程规范:
宗旨:团队要规范,开发有效率
项目规范必要的插件(vue为例):
- Eslint (检查代码规范)
- Prettier (检查代码风格)
- husky (配置 husky 使用 git hook)
- lint-staged (增量式检查)
- commitlint (检查提交信息)
- commitizen (规范 Git 提交说明)
- editorConfig (统一编辑器(可不用))
- stylelint (配置 stylelint 检查 CSS 规范(可不用))
- 配置 node 版本限制提示
前端工程搭建:
编译器规范
- 前端编译器统一vscode
- vscode安装插件:eslint,prettier,stylelint
配置 node 版本限制提示
-
package.json中配置
"engines": { "node": ">=16.0.0" }
配置 eslint 检查代码规范
eslint处理代码规范,prettier 处理代码风格,eslint 选择只检查错误不处理风格,这样 eslint 就不会和 prettier冲突
-
安装插件: npm i eslint -D
-
生成配置文件(或者手动创建):eslint --init (如果没有eslint,可以全局安装一个然后使用 npx eslint --init)依次选择
To check syntax and find problems //这个选项是eslint默认选项,这样就不会和pretter起风格冲突 JavaScript modules (import/export) vue YES Browser JSON Yes npm
-
配置eslintrc.json/eslintrc.js/eslintrc.cjs 具体配置参考以下
module.exports = { root: true, env: { browser: true, node: true, // 因为比如配置vite的时候会使用到 es6: true }, // 指定如何解析语法 parser: 'vue-eslint-parser', // 优先级低于 parse 的语法解析配置 parserOptions: { parser: '@typescript-eslint/parser', ecmaVersion: 2020, sourceType: 'module', jsxPragma: 'React', ecmaFeatures:{ jsx: true }, }, // 继承某些已有的规则 extends: ['plugin:vue/vue3-recommended', 'plugin:@typescript-eslint/recommended', 'plugin:prettier/recommended'], /** * "off" 或 0 ==> 关闭规则 * "warn" 或 1 ==> 打开的规则作为警告(不影响代码执行) * "error" 或 2 ==> 规则作为一个错误(代码不能执行,界面报错) */ rules: { // eslint (http://eslint.cn/docs/rules) 'no-var': 'error', // 要求使用 let 或 const 而不是 var 'no-multiple-empty-lines': ['error', { max: 1 }], // 不允许多个空行 'prefer-const': 'off', // 使用 let 关键字声明但在初始分配后从未重新分配的变量,要求使用 const 'no-use-before-define': 'off', // 禁止在 函数/类/变量 定义之前使用它们 'no-irregular-whitespace': 'off', // 禁止不规则的空白 // typeScript (https://typescript-eslint.io/rules) '@typescript-eslint/no-unused-vars': 'error', // 禁止定义未使用的变量 '@typescript-eslint/prefer-ts-expect-error': 'error', // 禁止使用 @ts-ignore '@typescript-eslint/no-inferrable-types': 'off', // 可以轻松推断的显式类型可能会增加不必要的冗长 '@typescript-eslint/no-namespace': 'off', // 禁止使用自定义 TypeScript 模块和命名空间。 '@typescript-eslint/no-explicit-any': 'off', // 禁止使用 any 类型 '@typescript-eslint/ban-types': 'off', // 禁止使用特定类型 '@typescript-eslint/explicit-function-return-type': 'off', // 不允许对初始化为数字、字符串或布尔值的变量或参数进行显式类型声明 '@typescript-eslint/no-var-requires': 'off', // 不允许在 import 语句中使用 require 语句 '@typescript-eslint/no-empty-function': 'off', // 禁止空函数 '@typescript-eslint/no-use-before-define': 'off', // 禁止在变量定义之前使用它们 '@typescript-eslint/ban-ts-comment': 'off', // 禁止 @ts-<directive> 使用注释或要求在指令后进行描述 '@typescript-eslint/no-non-null-assertion': 'off', // 不允许使用后缀运算符的非空断言(!) '@typescript-eslint/explicit-module-boundary-types': 'off', // 要求导出函数和类的公共类方法的显式返回和参数类型 // vue (https://eslint.vuejs.org/rules) 'vue/script-setup-uses-vars': 'error', // 防止<script setup>使用的变量<template>被标记为未使用,此规则仅在启用该no-unused-vars规则时有效。 'vue/v-slot-style': 'error', // 强制执行 v-slot 指令样式 'vue/no-mutating-props': 'off', // 不允许组件 prop的改变 'vue/no-v-html': 'off', // 禁止使用 v-html 'vue/custom-event-name-casing': 'off', // 为自定义事件名称强制使用特定大小写 'vue/attributes-order': 'off', // vue api使用顺序,强制执行属性顺序 'vue/one-component-per-file': 'off', // 强制每个组件都应该在自己的文件中 'vue/html-closing-bracket-newline': 'off', // 在标签的右括号之前要求或禁止换行 'vue/max-attributes-per-line': 'off', // 强制每行的最大属性数 'vue/multiline-html-element-content-newline': 'off', // 在多行元素的内容之前和之后需要换行符 'vue/singleline-html-element-content-newline': 'off', // 在单行元素的内容之前和之后需要换行符 'vue/attribute-hyphenation': 'off', // 对模板中的自定义组件强制执行属性命名样式 'vue/require-default-prop': 'off', // 此规则要求为每个 prop 为必填时,必须提供默认值 'vue/multi-word-component-names': 'off' // 要求组件名称始终为 “-” 链接的单词 } }
-
工作区配置项目中.vscode>settings.json, 配置后vscode保存时会自动格式化代码风格
{ //自动格式化 "editor.formatOnSave": true, "editor.codeActionsOnSave": { // 每次保存的时候将代码按照 eslint 格式进行修复 "source.fixAll.stylelint": true } }
-
工作区配置.eslintignore 在工程中创建.eslintignore文件,配置eslint过滤文件 (参考)
*.sh node_modules *.md *.woff *.ttf .vscode .idea dist /public /docs .husky .local /bin /src/mock/* stats.html
-
在package.json中配置eslint脚本
"lint:eslint": "eslint --fix --ext .js,.ts,.vue ./src"
配置 prettier 检查代码风格
-
安装插件 npm install -D prettier eslint-config-prettier eslint-plugin-prettier
-
创建并配置.prettierrc.js/.prettierrc.json/.prettierrc.cjs(cjs此类型文件package.json type必须设置为module)文件 (主要是一些格式配置)(如下)
module.exports = { // 指定最大换行长度 printWidth: 130, // 缩进制表符宽度 | 空格数 tabWidth: 2, // 使用制表符而不是空格缩进行 (true:制表符,false:空格) useTabs: false, // 结尾不用分号 (true:有,false:没有) semi: true, // 使用单引号 (true:单引号,false:双引号) singleQuote: true, // 在对象字面量中决定是否将属性名用引号括起来 可选值 "<as-needed|consistent|preserve>" quoteProps: "as-needed", // 在JSX中使用单引号而不是双引号 (true:单引号,false:双引号) jsxSingleQuote: false, // 多行时尽可能打印尾随逗号 可选值"<none|es5|all>" trailingComma: "none", // 在对象,数组括号与文字之间加空格 "{ foo: bar }" (true:有,false:没有) bracketSpacing: true, // 将 > 多行元素放在最后一行的末尾,而不是单独放在下一行 (true:放末尾,false:单独一行) bracketSameLine: false, // (x) => {} 箭头函数参数只有一个时是否要有小括号 (avoid:省略括号,always:不省略括号) arrowParens: "avoid", // 指定要使用的解析器,不需要写文件开头的 @prettier requirePragma: false, // 可以在文件顶部插入一个特殊标记,指定该文件已使用 Prettier 格式化 insertPragma: false, // 用于控制文本是否应该被换行以及如何进行换行 proseWrap: "preserve", // 在html中空格是否是敏感的 "css" - 遵守 CSS 显示属性的默认值, "strict" - 空格被认为是敏感的 ,"ignore" - 空格被认为是不敏感的 htmlWhitespaceSensitivity: "css", // 控制在 Vue 单文件组件中 <script> 和 <style> 标签内的代码缩进方式 vueIndentScriptAndStyle: false, // 换行符使用 lf 结尾是 可选值 "<auto|lf|crlf|cr>" endOfLine: "auto", // 这两个选项可用于格式化以给定字符偏移量(分别包括和不包括)开始和结束的代码 (rangeStart:开始,rangeEnd:结束) rangeStart: 0, rangeEnd: Infinity }
-
配置.prettierignore忽略文件会自动忽略node_modules
/dist/* .local /node_modules/** **/*.svg **/*.sh /public/* stats.html
-
配置.vscode> settings.josn 配置后vscode保存时会自动格式化代码风格
{ "editor.codeActionsOnSave": { // 每次保存的时候将代码按照 eslint 格式进行修复 "source.fixAll.eslint": true }, //自动格式化 "editor.formatOnSave": true, //风格用prettier "editor.defaultFormatter": "esbenp.prettier-vscode" }
-
在package.json中添加格式化命令
"lint:prettier": "prettier --write \"src/**/*.{js,ts,json,tsx,css,less,scss,vue,html,md}\"",
Git 提交规范使用husky控制git hook
-
安装插件:npm install --save-dev @commitlint/config-conventional @commitlint/cli
-
在项目根目录创建commitlint.config.js/commitlint.config.cjs(cjs此类型文件package.json type必须设置为module)文件 (配置如下(可以参考插件文档))
module.exports = { // 继承的规则 extends: ['@commitlint/config-conventional'], // 定义规则类型 rules: { // @see: https://commitlint.js.org/#/reference-rules // type 类型定义,表示 git 提交的 type 必须在以下类型范围内 'type-enum': [ 2, 'always', [ 'feat', // 新功能 feature 'fix', // 修复 bug 'docs', // 项目文档或注释变更 'style', // 仅仅修改了空格、格式缩进、逗号等等,不改变代码逻辑 'refactor', // 代码重构,没有加新功能或者修复bug 'perf', // 优化相关,比如提升性能、体验 'test', // 增加测试 'chore', // 改变构建流程、或者增加依赖库、工具等 'revert', // 回滚到上一个版本 'build', // 部署版本 'ci' // 修改 CI 配置、脚本 ] ], // subject 大小写不做校验 'subject-case': [0] }, prompt: { messages: { type: '选择你要提交的类型 :', scope: '选择一个提交范围(可选):', customScope: '请输入自定义的提交范围 :', subject: '填写简短精炼的变更描述 :\n', body: '填写更加详细的变更描述(可选)。使用 "|" 换行 :\n', breaking: '列举非兼容性重大的变更(可选)。使用 "|" 换行 :\n', footerPrefixsSelect: '选择关联issue前缀(可选):', customFooterPrefixs: '输入自定义issue前缀 :', footer: '列举关联issue (可选) 例如: #31, #I3244 :\n', confirmCommit: '是否提交或修改commit ?' // 英文版本 // type: "Select the type of change that you're committing:", // scope: "Denote the SCOPE of this change (optional):", // customScope: "Denote the SCOPE of this change:", // subject: "Write a SHORT, IMPERATIVE tense description of the change:\n", // body: 'Provide a LONGER description of the change (optional). Use "|" to break new line:\n', // breaking: 'List any BREAKING CHANGES (optional). Use "|" to break new line:\n', // footerPrefixsSelect: "Select the ISSUES type of changeList by this change (optional):", // customFooterPrefixs: "Input ISSUES prefix:", // footer: "List any ISSUES by this change. E.g.: #31, #34:\n", // confirmCommit: "Are you sure you want to proceed with the commit above?" }, types: [ { value: 'feat', name: '特性: 🚀 新增功能', emoji: '🚀' }, { value: 'fix', name: '修复: 🧩 修复缺陷', emoji: '🧩' }, { value: 'docs', name: '文档: 📚 文档变更', emoji: '📚' }, { value: 'style', name: '格式: 🎨 代码格式(不影响功能,例如空格、分号等格式修正)', emoji: '🎨' }, { value: 'refactor', name: '重构: ♻️ 代码重构(不包括 bug 修复、功能新增)', emoji: '♻️' }, { value: 'perf', name: '性能: ⚡️ 性能优化', emoji: '⚡️' }, { value: 'test', name: '测试: ✅ 添加疏漏测试或已有测试改动', emoji: '✅' }, { value: 'build', name: '构建: 📦️ 构建流程、外部依赖变更(如升级 npm 包、修改 webpack 配置等)', emoji: '📦️' }, { value: 'ci', name: '集成: 🎡 修改 CI 配置、脚本', emoji: '🎡' }, { value: 'chore', name: '回退: ⏪️ 回滚 commit', emoji: '⏪️' }, { value: 'revert', name: '其他: 🔨 对构建过程或辅助工具和库的更改(不影响源文件、测试用例)', emoji: '🔨' }, { value: 'wip', name: '开发: 🕔 正在开发中', emoji: '🕔' }, { value: 'workflow', name: '工作流: 📋 工作流程改进', emoji: '📋' }, { value: 'types', name: '类型: 🔰 类型定义文件修改', emoji: '🔰' } ], useEmoji: true, customScopesAlign: 'bottom', emptyScopesAlias: 'empty', customScopesAlias: 'custom', allowBreakingChanges: ['feat', 'fix'] } };
-
安装husky:npm install husky --save-dev
-
启动hooks:npx husky install 启动后将会自动生成.husky文件夹
-
在package.json中配置指令脚本
"prepare": "husky install",
-
运行指令:npm run prepare
-
添加commitlint的hook到husky中 执行以下命令
npx husky add .husky/commit-msg 'npx --no-install commitlint --edit "$1"'
Lint-staged增量式检查
- 安装npm i -D lint-staged
- 配置package.json
"lint:lint-staged": "lint-staged",
- 在根目录创建并且配置lint-staged.config.cjs/lint-staged.config.js/lint-staged.config.josn
module.exports = { '*.{js,jsx,ts,tsx}': ['eslint --fix', 'prettier --write'], '{!(package)*.json,*.code-snippets,.!(browserslist)*rc}': ['prettier --write--parser json'], 'package.json': ['prettier --write'], '*.vue': ['eslint --fix', 'prettier --write', 'stylelint --fix'], '*.{scss,less,styl,html}': ['stylelint --fix', 'prettier --write'], '*.md': ['prettier --write'] };
- 在 .husky 文件夹下的 pre-commit 中添加
#!/usr/bin/env sh . "$(dirname -- "$0")/_/husky.sh" npm run lint:lint-staged
editorconfig统一不同编辑器的编码风格
-
跟目录新建.editorconfig文件
-
在文件中配置相关风格(我的配置如下)
# @see: http://editorconfig.org root = true [*] # 表示所有文件适用 charset = utf-8 # 设置文件字符集为 utf-8 end_of_line = lf # 控制换行类型(lf | cr | crlf) insert_final_newline = true # 始终在文件末尾插入一个新行 indent_style = space # 缩进风格(tab | space) indent_size = 2 # 缩进大小 max_line_length = 130 # 最大行长度 [*.md] # 表示仅对 md 文件适用以下规则 max_line_length = off # 关闭最大行长度限制 trim_trailing_whitespace = false # 关闭末尾空格修剪