代码风格遵循的配置
代码风格自动化
一、改造背景
代码风格和性格一样,每个程序员都有自己的特点 ,但对于大家协同开发的项目,还是需要力求代码风格的一致性,以减少Bug,但是目前现有项目在代码提交之前,没有进行代码规则检查能够确保进入git库的代码都是符合代码规则的。
该形式的开发模式存在以下几个缺点:
1、javascript相关文件规范依赖插件保提示或者格式,不能在提交前自动校验格式
2、styl样式文件缺少编码风格规则约束,社区相关插件比较少
3、在代码提交之前,对暂存区的文件的脚本和样式文件缺少校验与格式操作且对相关提交信息缺少约束,不利于后期排查问题
综上,当前开发对脚本、样式、提交信息的风格缺少自动化校验流程,代码风格不统一,对后期的维护迭代不利
二、改进点
针对以上问题,在项目里引入Husky、Commitlint、Lint-staged及stylelint工程化工具进行代码风格约束,以减少bug,确定提交到仓库的代码符合约定的语法规范并且对不符合规范的代码进行自动fix操作。
该方案具有以下优点:
1、代码提交钩子Husky,在代码被提交到Git仓库之前,我们可以在这里做一些预检查或者格式化,简单说就是使用Git命令会触发的函数。
2、在有了Husky赋能之后,我们有能力在Git的钩子里做一些事情,首先不得不提的是代码的提交规范和规范的校验,优雅的提交,方便团队协作和快速定位问题,首推Commitlint
3、前端文件过滤的工具Lint-staged,对于较大型的项目,文件众多,首先遇到的就是性能问题,虽然如Eslint之类的也有文件过滤配置,但毕竟还是对于匹配文件的全量遍历,如全量的.js文件,基本达不到性能要求,有时还会误格式化其他同学的代码,因此我们引入Lint-staged,一个仅仅过滤出Git代码暂存区文件(被committed的文件)的工具。
4、 StyleLint 是『一个强大的、现代化的 CSS 检测工具』, 与 ESLint 类似, 是通过定义一系列的编码风格规则帮助我们避免在样式表中出现错误。
5、ESLint 是在 ECMAScript/JavaScript 代码中识别和报告模式匹配的工具,它的目标是保证代码的一致性和避免错误。
三、具体实施
此方案主要基于node项目工程化的前端代码格式化的工具配置使用,主要包含以下组件:
- 代码提交钩子Husky;
- 代码的提交规范和规范的校验,优雅的提交Commitlint工具;
- Git代码暂存区文件过滤工具Lint-staged
- stylus-converter工具包,把现有styl后缀的文件转换成less文件
- stylelint和eslint进行样式和js语法校验和修复
具体搭建步骤:
安装npm包husky、commitlint、Lint-staged、stylus-converter、stylelint、eslint(按照如下版本安装);
yarn add husky@7.0.2 @commitlint/config-conventional@13.1.0 @commitlint/cli@13.1.0 lint-staged@11.1.2 stylus-converter@0.8.1 stylelint@13.13.1 stylelint-order stylelint-config-standard@22.0.0 eslint@7.25.0 -D
1、添加prettier优化代码
//npm npm install --save-dev --save-exact prettier
//yarn yarn add --dev --exact prettier
1.1、.prettierrc.cjs
prettierrc是一个用于格式化代码的配置文件,可以定义代码的缩进、换行符、引号等样式规范。统一代码排版格式。
module.exports = {
printWidth: 100, // 单行长度
tabWidth: 2, // 缩进长度
useTabs: false, // 使用空格代替tab缩进
semi: true, //句末使用分号
singleQuote: true, //使用单引号
quoteProps: 'as-needed', //仅在必需时为对象的key添加引号
trailingComma: 'all', //多行时尽可能打印尾随逗号
bracketSpacing: true, //在对象前后添加空格-eg: { foo: bar }
jsxBracketSameLine: true, //多属性html标签的‘>’折行放置
arrowParens: 'always', //单参数箭头函数参数周围使用圆括号-eg: (x) => x
requirePragma: false, //无需顶部注释即可格式化
insertPragma: false, //在已被preitter格式化的文件顶部加上标注
proseWrap: 'preserve', //不知道怎么翻译
htmlWhitespaceSensitivity: 'ignore', //对HTML全局空白不敏感
endOfLine: 'lf', //结束行形式
embeddedLanguageFormatting: 'auto', //对引用代码进行格式化
}
1.2、添加.prettierignore,可以根据项目需要,自行配置
node_modules
public
dist
docs
/src/utils/transForm
**/ue-streaming-editor
.vscode
# doc
.temp
.cache
1.3、lint-staged-config.js文件修改如下
module.exports = {
'*.{js,vue}': [
'vue-cli-service lint ./src --fix',
'prettier --write ./src',
'git add'
]
}
1.4、package.json添加prettier脚本
"scripts": {
"lint:fix": "prettier src/**/* --write",
}
重启项目,执行npm run lint:fix,会发现项目中有不符合规范的代码,自动被修复了,pretter只会自动修复不影响逻辑的代码,影响逻辑的代码,需要手动修复
2、添加eslint提交检测
eslint是一个用于检测和修复JavaScript代码错误和风格问题的工具。它可以通过配置文件来定义需要遵循的代码规范。
2.1、安装eslint-config-prettier、eslint-plugin-prettier、lint-staged
npm install --save-dev eslint-config-prettier eslint-plugin-prettier lint-staged
2.2、.eslintrc.cjs
/**
* @type {import('eslint').Linter.Config}
*/
module.export = {
root: true,
env: {
node: true,
'vue/setup-compiler-macros': true
},
parserOptions: {
ecmaVersion: 2022
},
plugins: ['@typescript-eslint', 'spellcheck'],
extends: [
'eslint:recommended',
'plugin:vue/vue3-recommended',
'@vue/typescript/recommended',
'plugin:prettier/recommended'
],
overrides:[
{
files: ['*.ts', '*.vue'],
rules: {
'no-undef': 'off'
}
}
],
rules: {
'@typescript-eslint/no-empty-function': 'warn',
'@typescript-eslint/no-this-alias': 'warn',
'vue/attributes-order': ['error'],
'vue/order-in-components': ['error'],
'vue/no-v-model-argument': 0,
'vue/no-v-for-template-key-on-child': 0,
'vue/multi-word-component-names': 'off',
'prefer-const': 'warn',
'no-var': 'warn',
'prefer-rest-params': 'warn',
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'prettier/prettier': [
'error',
{
semi: false,
singleQuote: true,
trailingComma: 'none',
endOfLine: 'auto',
useTabs: false
}
],
'max-lines': [
'error',
{
max: 500
}
],
'spellcheck/spell-checker': [
process.env.NODE_ENV === 'production' ? 0 : 1,
{
comments: false,
strings: false,
skipWords: [
'svg',
'lon',
'axios',
'zh'
],
skipIfMatch: [
'GeoPos',
'draw'
],
skipWordIfMatch: []
}
]
}
}
2.3、配置.eslintignore文件,这个文件是配置哪些文件不需要eslint检测的,所以可以根据自己项目自行配置此文件,配置如下:
/node_modules
/public
/dist
/mock
/src/utils/transForm
/docs
**/ue-streaming-editor/**
.vscode
# doc
/.temp
/.cache
2.4、 package.json文件配置lint脚本检测代码
"scripts": {
"lint": "eslint src/**/* --ext .js,.vue"
}
重启项目,执行npm run lint,项目就会检测哪些代码不符合要求
2.5、lint-staged.config.js
lint-staged可以将git“已暂存(staged)”的文件作为参数传入你要执行的shell script之中
module.exports = {
'*.{js,jsx,ts,tsx,cjs,mjs,vue}': ['npm run lint'],
'*.{vue,css,sass,scss,less}': ['npm run lint:style']
'*.{json,md}': ['prettier --write']
}
2.6、package.json文件配置修改,配置如下:
"husky": {
"hooks": {
"pre-commit": "lint-staged",
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
}
}
3、stylelint
.stylelintrc.js
stylelint是『一个强大的、现代化的 CSS 检测工具』, 与 ESLint
类似, 是通过定义一系列的编码风格规则帮助我们避免在样式表中出现错误.
module.exports = {
plugins: [
'stylelint-order',
'stylelint-declaration-block-no-ignored-properties'
],
extends: [
// 'stylelint-config-recommended-vue',
'stylelint-config-standard',
'stylelint-config-rational-order',
'stylelint-prettier/recommended'
],
overrides: [
{
files: ['src/**/*.{htm,html,vue}'],
customSyntax: 'postcss-html'
},
{
files: ['src/**/*.{css,scss}'],
customSyntax: 'postcss-scss'
}
],
rules: {
// 命名规范
'selector-class-pattern': [
'^(?:(?:o|c|u|t|s|is|has|_|js|qa)-)?[a-z0-9]+(?:-[a-z0-9]+)*(?:__[a-z0-9]+(?:-[a-z0-9]+)*)?(?:--[a-z0-9]+(?:-[a-z0-9]+)*)?(?:\\[.+\\])?$',
{
message: 'Expected class selector to be kebab-case',
severity: 'warning',
resolveNestedSelectors: true
}
],
'selector-pseudo-element-no-unknown': [
true,
{
ignorePseudoElements: ['v-deep', 'v-bind']
}
],
'selector-pseudo-class-no-unknown': null,
'function-no-unknown': null,
'custom-property-pattern': null,
'string-quotes': 'single', // 单引号
'at-rule-empty-line-before': null,
'at-rule-no-unknown': null,
'at-rule-name-case': 'lower', // 指定@规则名的大小写
'length-zero-no-unit': true, // 禁止零长度的单位
'shorthand-property-no-redundant-values': true, // 简写属性
'declaration-block-no-duplicate-properties': true, // 禁止声明快重复属性
'no-descending-specificity': null, // 禁止在具有较高优先级的选择器后出现被其覆盖的较低优先级的选择器。
'selector-max-id': 3, // 限制一个选择器中 ID 选择器的数量
'max-nesting-depth': 4,
'import-notation': null,
'no-duplicate-selectors': null,
'color-function-notation': null,
'alpha-value-notation': null,
'font-family-name-quotes': null,
'font-family-no-missing-generic-family-keyword': null,
indentation: null
}
}
.stylelintignore
node_modules
public
dist
docs
.vscode
# doc
.temp
.cache
4、.cz-config.js
cz-config是一个开源的 Git 提交规范配置工具,全称为 Commitizen Config。它可以帮助开发者规范化 Git 提交信息的格式,使得团队成员之间的提交信息更加一致,易于查看和理解。
// .cz-config.js
module.exports = {
types: [
{ value: 'feat', name: 'feat: 一项新功能' },
{ value: 'fix', name: 'fix: 修复一个bug' },
{ value: 'docs', name: 'docs: 文档变更' },
{ value: 'style', name: 'style: 代码风格,格式修复' },
{ value: 'refactor', name: 'refactor: 代码重构,注意和feat、fix区分开' },
{ value: 'perf', name: 'perf: 代码优化,改善性能' },
{ value: 'test', name: 'test: 测试' },
{ value: 'chore', name: 'chore: 变更构建流程或辅助工具' },
{ value: 'revert', name: 'revert: 代码回退' },
{ value: 'init', name: 'init: 项目初始化' },
{ value: 'ci', name: 'ci: 对CI配置文件和脚本的更改' },
{ value: 'build', name: 'build: 变更项目构建或外部依赖' },
{ value: 'wip', name: 'WIP: 进行中的工作' },
],
scopes: [
{ name: 'component' },
{ name: 'home' },
{ name: 'login' },
{ name: 'xbuilder' },
{ name: 'xscenario' },
{ name: 'xfsmcreator' },
{ name: 'x2dviewer' },
{ name: 'xrunmanager' },
],
// override the message, defaults are as follows
messages: {
type: '请选择提交类型(必填):',
scope: '请选择一个scope (可选):',
customScope: '请输入文件修改范围(可选):',
// use if allowCustomScopes is true
subject: '请简要描述提交(必填):',
body: '请输入详细描述,使用"|"换行(可选):\n',
breaking: '列出任务非兼容性说明(可选):\n',
footer: '请输入要关闭的issue,例如:#12,#34(可选):\n',
confirmCommit: '确定提交此说明吗?',
},
allowCustomScopes: true,
allowBreakingChanges: ['feat', 'fix']
}
5、.ls-lint.yml
ls-lint是对文件和目录名称进行的一种约束
ls:
mock:
.js: kebab-case
.ts: kebab-case
src/components:
.vue: PascalCase
src/{api, common, store, utils, views}/*:
.js: PascalCase
.ts: PascalCase
.vue: PascalCase
.d.ts: PascalCase
src/view/*/{components, mixins}:
.js: PascalCase
.ts: PascalCase
.vue: PascalCase
.d.ts: PascalCase
src/**/hooks:
.js: camelCase
.ts: camelCase
ingore:
- .git
- .vscode
- dist
- public
- node_modules
- src/components/XsimConstructor
6、commitlint.config.js
commitlint负责校验commit msg是否符合规范
6.1、安装commitlint
vue add commitlint
6.2、项目根目录自动新增commitlint.config.js文件,配置如下
module.export = {
extends: ['@commitlint/config-conventional', 'cz']
}
参考文档
vue2项目配置prettier + eslint + commitlint + stylelint_.prettierignore_沈梦研的博客-优快云博客前端代码风格自动化_lint-staged.config_小石头万有引力的博客-优快云博客