前言本
本人现为一个学生身份, 美梦是作为基础建设的架构师, 本文意为编写一个通用的前端工程的模板, 没有经过一个长久的实践, 本文可能写的比较粗糙, 有错误和改进请友善提出, 编写与审核均为本人, 可能有文字描述错误, 不清晰等问题
更新历史
- 2024/03/19 03:03: 重新编写ESLint部分, 并添加多个扩展与配置文件的更新, 优化部分文字描述
- 2024/03/18 21:34: 添加StyleLint部分
- 2024/03/18: 添加配置文件与补充说明和部分文字描述修改
说明
使用Husky + Oxlint + ESLint + StyleLint + Prettier + Commitlint 作为基础设施库
包含本文内容的仓库URL
- Husky: Git hooks工具,通过配置一系列钩子,可以在git操作的不同阶段执行相应的命令, 这里使用它在代码提交到仓库前的检查, 使用使用Oxlint快速检索错误,然后执行ESLint检查代码规范与Prettier进行代码格式化输出, 统一代码规范
- Oxlint: 现阶段只有Lint功能开发比较能用, 对于大型项目, 在CI时使用它会运行的比较快
- ESLint: TS/TSX/Vue等代码的代码样式限制与格式化与修复
- Prettier: TS/TSX/Vue/Markdown等文件的代码样式格式化
- StyleLint: CSS/SCSS/Less等文件的排序,格式化
- Commitlint: git commit时的规则校验
本文均使用pnpm包管理器, 但是部分包含npm的使用方法, 在这里它们的区别可能就在于指令的用法不同
Husky
作用
Git hooks工具,通过配置一系列钩子,可以在git操作的不同阶段执行相应的命令
安装
如果.git目录不是在前端项目里,如:
.
├── .git/
├── backend/ # No package.json
└── frontend/ # Package.json with husky
则需要修改prepare的内容, 不使用pnpm exec husky init, 需要手动在package.json修改为:
"prepare": "cd .. && husky frontend/.husky"
如果手动修改了scripts的prepare,需要重新执行一次
pnpm prepare
注意, 如果
.git目录不是在前端项目里, 那么pre-commit也要修改进入到对应的目录, 例如:
有这样的目录结构:
.
├── .git/
├── backend/ # No package.json
└── frontend/ # Package.json with husky
那么, 对应的pre-commit文件内容就应该这样写:
cd frontend
pnpm test
Oxlint
定义
检查文件是否按照定义的规则进行编写
在工程化的作用(扮演的角色)
它现阶段不能直接代替ESLint, 它没有修复代码的功能, 只是它使用了Rust编写的工具, 运行很快, 现阶段, 作者推荐在CI阶段时运行在ESLint之前,这样,大部分常见问题还没走到 Eslint 这一步就被 Oxlint拦截, 大大减少大型项目的CI流水线的运行时间
oxc-project.github.io/docs/guide/…
pnpm add -D oxlint
Usages 用法
npx oxlint@latest --rules以获取规则列表。npx oxlint@latest --help以获取配置说明
有用的选项和示例
--deny-warnings将警告转换为错误,对于退出代码为 1 的 CI 失败很有用。-D all拒绝(打开)所有规则。-A all -D eqeqeq运行单个规则。-D correctness -D perf -A debugger -A eqeqeq拒绝(打开)和规则,并允许(关闭)correctnessdebugger和eqeqeqperf规则。- -c ./eslintrc.json
使用该rules字段配置规则,如 ESLint 中所述。仅json` 支持格式
在package.json添加:
pnpm pkg set scripts.lint-check="oxlint"
如下效果:
{
...
"scripts": {
...
"lint-check": "oxlint",
...
},
...
}
在.husky/pre-commit添加
cat >> .husky/pre-commit <<EOF
pnpm lint-check
EOF
检查:
pnpm lint-check
lint-staged
作用
在提交代码前进行lint检查时,可以让lint只检查git暂存区(staged)的文件,而不会检查所有文件
pnpm add --save-dev lint-staged
package.json
{
"lint-staged": {
"src/**/*.{ts,tsx,js,jsx}": [
"oxlint"
]
},
}
ESLint
安装
pnpm create @eslint/config
or
npm init @eslint/config
配置
选项
--cache:该参数启用了 ESLint 的缓存功能,以提高重复运行 ESLint 时的性能。ESLint 将会缓存 lint 结果和文件状态,从而避免不必要的重新检查。--max-warnings 0:此参数规定了允许的最大警告数量。在这个例子中,设置为 0 表示如果有任何警告产生,将被视为错误而导致命令失败。src:指定需要进行 ESLint 检查的目录或文件。在这里,它表示对 "src" 目录进行检查。--ext ts,tsx:这个参数指定了 ESLint 将要检查的文件扩展名。在这里,它表示 ESLint 将检查扩展名为 ".ts" 和 ".tsx" 的文件。--fix:该参数告诉 ESLint 尝试自动修复发现的问题。如果某些问题可以被自动修复,ESLint 将会尝试修改源代码以修复这些问题。
pnpm pkg set scripts.eslint="eslint src/**/**{.ts,.tsx}"
pnpm pkg set scripts.eslint:fix="eslint --cache --max-warnings 0 src --ext ts,tsx --fix"
忽略文件
添加忽略格式化的目录
echo node_modules > .eslintignore
检查
是否正常运行
pnpm eslint
pnpm eslint:fix
扩展
添加扩展插件, 对库进行更严格的限制, 本文以React演示, 这里使用了
- xo : 一个通用的规则
- plugin:react/recommended
- eslint:recommended :ESLint推荐的规则
- eslint:all:ESLint 附带的所有规则
- eslint-plugin-react
- eslint-plugin-jsdoc: jsdoc的格式化扩展
- eslint-plugin-markdown: Markdown 中的 Lint JS、JSX、TypeScript 等。
如果使用了
eslint-plugin-react, 则需要再在eslintrc的配置文件, 它支持多个后缀(js,json,yml,toml,...), 取决于你的实际生成配置文件类型,然后指定自动检测选择当前安装的版本:
settings:
react:
pragma: 'React'
version: 'detect'
eslintrc的配置文件如下所示, 以yml为例:
# Source: .eslintrc.yml
env:
browser: true
es2021: true
extends:
- xo
- plugin:react/recommended
- prettier
overrides:
- extends:
- xo-typescript
files:
- '**/*.js'
- '**/*.ts'
- '**/*.tsx'
- '**/*.vue'
parserOptions:
ecmaVersion: latest
sourceType: module
plugins:
- react
- prettier
- eslint-plugin-jsdoc
- eslint-plugin-markdown
rules:
prettier/prettier: error
settings:
react:
pragma: 'React'
version: 'detect'
Prettier
--save-exact标志用于确保安装的包版本是精确匹配的
pnpm install -D --save-exact prettier
- 创建配置文件
创建一个
prettier配置文件,并写入基本的配置:
cat > .prettierrc.json << EOF
{
"semi": true,
"tabWidth": 2,
"singleQuote": true,
"printWidth": 80,
"trailingComma": "all",
"endOfLine": "lf"
}
EOF
- 创建
prettier忽略文件(eslint 默认会忽略 node_modules):
echo node_modules > .prettierignore
- 解决prettier规则与ESLint规则的冲突
pnpm add -D eslint-config-prettier
因为ESLint支持多种配置文件, 本文使用yml形式来保存配置,
编辑.eslintrc.yml: 在extends添加prettier和plugins对象添加prettier以启用prettier
extends:
- prettier
plugins:
- prettier
安装和配置eslint-plugin-prettier插件以便将Prettier作为ESLint规则运行,并将差异报告为单个ESLint问题:
pnpm add -D eslint-plugin-prettier
在.eslintrc.yml文件中添加配置:
rules: {
prettier/prettier: error
}
- 在
package.json的lint-staged选择一个规则进行添加:
"**/*": "prettier --write --ignore-unknown": 让可识别的文件都使用prettier进行格式化"*.{ts,tsx,js,jsx,cjs,mjs,vue,css,scss,less,md}": "prettier --write": 针对特定的文件类型进行格式化
示例:
pnpm pkg set lint-staged."**/*"="prettier --write --ignore-unknown"
如下效果:
{
"lint-staged": {
"*.{ts,tsx,js,jsx,cjs,mjs,vue,css,scss,less,md}": "prettier --write --ignore-unknown",
"**/*": "prettier --write --ignore-unknown"
},
}
StyleLint
安装
- pnpm
pnpm create stylelint
- npm
npm init stylelint
配置
在package.json的script添加:
pnpm pkg set scripts.stylelint="stylelint src/**/**.{css,scss,sass}"
pnpm pkg set scripts.stylelint:fix="stylelint src/**/**.{css,scss,sass} --fix"
运行测试:
pnpm stylelint:fix
pnpm stylelint
如果样式文件有错误的地方, 那么会报错: ![[img/Pasted image 20240318235553.png]]
如何样式文件正常, 那么不会报错: ![[img/Pasted image 20240318235616.png]]
ESModule
如果使用Node.js的默认模块系统配置(package.json), 如果使用"type": "module", 那么文件名必须是 stylelint.config.mjs 或 .stylelintrc.mjs
本文选择ESModule, 文件为.stylelintrc.mjs
package.json:
{
"type": "module"
}
.stylelintrc.mjs, 可直接使用本人的rules规则(在文章后面)或者进行个性化的定制, 参考官网rules:
@typeJSDoc 注解使 Typescript 能够自动完成和类型检查。
// Rules: https://stylelint.io/user-guide/rules
/** @type {import('stylelint').Config} */
export default {
'extends': [
'stylelint-config-standard',
'stylelint-config-standard-scss',
'stylelint-config-recess-order',
],
'rules': {},
}
CommonJS
package.json:
{
"type": "commonjs"
}
CommonJS 示例:
module.exports = {
'extends': [
'stylelint-config-standard'
],
'rules': {}
};
扩展
- SCSS/SASS
如果你在项目使用
SASS库, 那么还可以安装配套的库
pnpm i -D stylelint-config-standard-scss
- stylelint-config-recess-order 一个 Stylelint 配置,它以 Recess 和 Bootstrap 的方式对 CSS 属性进行排序
pnpm i -D stylelint-config-recess-order
然后再stylelint的配置文件:
stylelint.config.mjs或.stylelintrc.mjs文件使用export default(ES 模块)stylelint.config.cjs或.stylelintrc.cjs文件使用module.exports(CommonJS) 的文件 上进行添加
stylelint.config.mjs 或 .stylelintrc.mjs 文件:
export default {
'extends': [
'stylelint-config-standard',
'stylelint-config-standard-scss',
'stylelint-config-recess-order',
],
}
stylelint.config.cjs 或 .stylelintrc.cjs 文件:
module.exports = {
'extends': [
'stylelint-config-standard',
'stylelint-config-standard-scss',
'stylelint-config-recess-order',
],
}
Commitlint
- 安装
- mac:
pnpm add -D @commitlint/{cli,config-conventional}
- windows
npm install --save-dev @commitlint/config-conventional @commitlint/cli
- 创建配置
- 官方默认配置:
echo "export default { extends: ['@commitlint/config-conventional'] };" > commitlint.config.js
- 本人使用的配置:
cat > commitlint.config.js <<EOF
export default {
extends: ['@commitlint/config-conventional'],
'type-enum': [
2,
'always',
[
'feat',
'fix',
'perf',
'style',
'docs',
'test',
'refactor',
'build',
'ci',
'chore',
'revert',
'wip',
'workflow',
'types',
'release'
],
],
}
EOF
commitlint.config.js文件内容如下:
export default {
extends: ['@commitlint/config-conventional'],
'type-enum': [
2,
'always',
[
'feat',
'fix',
'perf',
'style',
'docs',
'test',
'refactor',
'build',
'ci',
'chore',
'revert',
'wip',
'workflow',
'types',
'release'
],
],
}
- 添加
git commithook钩子
注意, 如果
.git目录不是在前端项目里, 那么commit-msg也要修改进入到对应的目录, 例如:
有这样的目录结构:
.
├── .git/
├── backend/ # No package.json
└── frontend/ # Package.json with husky
那么, 对应的commit-msg文件内容就应该这样写:
cd frontend
pnpm commitlint ${1}
- pnpm:
echo "cd frontend && pnpm commitlint --edit \$1" > .husky/commit-msg
- npm:
echo "cd frontend && npx --no -- commitlint --edit \$1" > .husky/commit-msg
或者: 作为替代方法,在package.json 创建脚本
npm pkg set scripts.commitlint="commitlint --edit"
echo "pnpm commitlint \${1}" > .husky/commit-msg
还是那句话, 如果
.git目录不是在前端项目里, 那么commit-msg也要修改进入到对应的目录
默认生成的.husky/commit-msg文件是这样:
pnpm commitlint ${1}
你需要添加:
cd frontend
...
- 测试
测试失败示例:
git commit -m "foo: add commit-msg hook"
预期会输出错误:
> frontend@0.0.0 commitlint /Users/lisa/Public/Golang/src/2024/edu-system/frontend
> commitlint --edit ".git/COMMIT_EDITMSG"
⧗ input: foo: add commit-msg hook
✖ type must be one of [build, chore, ci, docs, feat, fix, perf, refactor, revert, style, test] [type-enum]
✖ found 1 problems, 0 warnings
ⓘ Get help: https://github.com/conventional-changelog/commitlint/#what-is-commitlint
ELIFECYCLE Command failed with exit code 1.
husky - commit-msg script failed (code 1)
测试成功示例:
git commit -m "feat: add commit-msg hook"
配置参考
以Vite React TS为示例:
package
pnpm add -D husky
pnpm add -D lint-staged
pnpm add -D oxlint
pnpm add -D eslint typescript @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-plugin-react eslint-config-alloy eslint-plugin-jsdoc eslint-plugin-markdown
pnpm add -D eslint-config-prettier eslint-plugin-prettier
pnpm add -D --save-exact prettier
pnpm add -D @commitlint/{cli,config-conventional}
tsconfig.json
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": [
"DOM",
"DOM.Iterable",
"ESNext"
],
"allowJs": true,
"alwaysStrict": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"forceConsistentCasingInFileNames": true,
"experimentalDecorators": true,
"module": "ESNext",
"moduleResolution": "Node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
"sourceMap": true,
"noImplicitAny": true,
"noImplicitThis": true,
"strictNullChecks": true,
"types": [
"node",
"./src/types"
],
"baseUrl": "./",
"paths": {
"@/*": [
"src/*"
]
}
},
"include": [
"src/**/*.ts",
"src/**/*.tsx"
],
"exclude": [
"node_modules",
"dist"
],
"references": [
{
"path": "./tsconfig.node.json"
}
]
}
package.json
package.json:
{
"lint-staged": {
"*.{ts,tsx,js,jsx,cjs,mjs,vue}": "eslint --fix",
"**/*": "prettier --write --ignore-unknown"
},
"scripts": {
"prepare": "cd .. && husky frontend/.husky",
"prettier:check": "prettier --check src/**/**{.cjs,.mjs,.ts,.tsx,.html,.md}",
"prettier:write": "prettier --write src/**/**{.cjs,.mjs,.ts,.tsx,.html,.md}",
"lint": "eslint src/**/**{.ts,.tsx}",
"lint:fix": "eslint --cache --max-warnings 0 src --ext ts,tsx --fix",
"lint:check": "oxlint",
"lint-staged": "lint-staged",
"commitlint": "commitlint --edit"
},
}
ESLint
旧配置文件
在ESLint初始化时, 我选择了alloy的react ts配置
- 安装依赖
pnpm add -D eslint typescript @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-plugin-react eslint-config-alloy
- md扩展
p i -D eslint-plugin-markdown
- jsdoc扩展
p i -D eslint-plugin-jsdoc
.eslintrc.yml:
root: true
env:
browser: true
es2021: true
node: true
# mocha: true,
# jest: true,
# jquery: true
#globals:
# Your global variables (setting to false means its not allowed to be reassigned)
#
# myGlobal: false
extends:
- alloy
- alloy/react
- alloy/typescript
- plugin:react/recommended
- plugin:react/jsx-runtime
- plugin:markdown/recommended-legacy
- plugin:jsdoc/recommended-typescript-error
#overrides:
# #- extends:
# #- xo-typescript
# files:
# - **/*.js
# - **/*.ts
# - **/*.tsx
# - **/*.md
parserOptions:
ecmaVersion: latest
sourceType: module
ecmaFeatures:
jsx: true
plugins:
- react
- prettier
- jsdoc
rules:
prettier/prettier: error
settings:
react:
pragma: React
version: detect
新配置文件
TODO
import jsdoc from 'eslint-plugin-jsdoc'
import js from '@eslint/js'
import markdown from 'eslint-plugin-markdown'
import prettier from 'eslint-config-prettier'
export default [
// 包含在插件中的配置
// jsdoc.configs.recommended,
// {
// // ...js.configs.recommended,
// ...js.configs.all,
// },
// {
// ...prettier,
// },
{
files: [
'**/*.js',
'**/*.jsx',
'**/*.ts',
'**/*.tsx',
'**/*.vue',
'**/*.md',
],
plugins: {
markdown,
jsdoc,
},
processor: 'markdown/markdown',
settings: {
sharedData: 'Hello',
},
rules: {
// 关闭分号
semi: ['error', 'never'],
quotes: ['error', 'single'],
'prefer-const': 'error',
'jsdoc/check-values': 'error',
'jsdoc/require-description': 'warn',
},
languageOptions: {
//评估你的 JavaScript(ECMAScript)的版本,可以设置为版本号(6)、年份(2022)或 "latest"
ecmaVersion: 'latest',
// ECMAScript 模块(ESM) - 代码有模块作用域,并以严格模式运行。
// CommonJS - 代码有顶层函数作用域,并在非严格模式下运行。
// Script - 代码有共享的全局作用域,并在非严格模式下运行。
// 通过指定 sourceType 属性来指定你的代码要在哪种模式下运行。
// 这个属性可以被设置为 "module"、"commonjs" 或 "script"。默认情况下,.js 和 .mjs 文件的 sourceType 是 "module",而 .cjs 文件则是 "commonjs"
sourceType: 'script',
//npm i @babel/eslint-parser, 可以使用还在实验性的JS, 使用 Babel 解析器,而不是使用默认解析器,来解析所有以 .js 和 .mjs 结尾的文件
// parser: 'babelParser',
},
ignores: ['node_modules/*'],
},
// applies only to code blocks
// 对 markdown 文件中以 .js 结尾的命名代码块禁用 strict 规则。
{
files: ['**/*.md/*.js'],
rules: {
strict: 'off',
},
},
]
StyleLint规则
花了2h+的时间来从官网进行每一条规则的校验和验证, 并编写了符合本人的审美标准的StyleLint规则
// Rules: https://stylelint.io/user-guide/rules
/** @type {import('stylelint').Config} */
export default {
'extends': [
'stylelint-config-standard',
'stylelint-config-standard-scss',
'stylelint-config-recess-order',
],
'rules': {
// 重复
// 块不允许重复的自定义属性
'declaration-block-no-duplicate-custom-properties': true,
// 块不允许重复的属性
'declaration-block-no-duplicate-properties': true,
// 禁止字体系列中的重复名称
'font-family-no-duplicate-names': true,
// 禁止在关键帧块中使用重复的选择器
'keyframe-block-no-duplicate-selectors': true,
// 禁止重复的@import
'no-duplicate-at-import-rules': true,
// 禁止重复的选择器
'no-duplicate-selectors': true,
// 空
// 禁止空块
'block-no-empty': true,
// 禁止空注释
// 'comment-no-empty': true,
// 禁止空源, \t\t 与 \n 都被认为是错误
'no-empty-source': true,
// Invalid 无效
// 不允许无效的十六进制颜色
'color-no-invalid-hex': true,
// 禁止函数中使用 calc 无效的无空格运算符
'function-calc-no-unspaced-operator': true,
// 禁止 !important 关键帧内无效声明
'keyframe-declaration-no-important': true,
// 禁止无效的媒体查询
'media-query-no-invalid': true,
//禁止无效的命名网格区域
'named-grid-areas-no-invalid': true,
// 禁止无效的双斜杠注释
'no-invalid-double-slash-comments': true,
//不允许无效的仓 @import 位规则
'no-invalid-position-at-import-rule': true,
// 禁止字符串中使用无效换行符
'string-no-newline': true,
// Irregular 规则
// 不允许使用不规则的空格
'no-irregular-whitespace': true,
// Missing 缺斤少两
// 禁止自定义属性缺少 var 函数
'custom-property-no-missing-var-function': true,
//禁止字体系列中缺少通用系列关键字a { font: 1em/1.3 Times; } 是错误
'font-family-no-missing-generic-family-keyword': true,
// Non-standard 非标准性
// 不允许线性梯度函数使用非标准方向值
// 类似 .foo { background: linear-gradient(top, #fff, #000); } 是错误
'function-linear-gradient-no-nonstandard-direction': true,
// Overrides 重写
// 不允许覆盖相关手写属性的速记属性
// 错误示例:
// a {
// padding-left: 10px;
// padding: 20px;
// }
'declaration-block-no-shorthand-property-overrides': true,
// Unmatchable 不匹配的操作
// 禁止使用不匹配的 An+B 选择器
'selector-anb-no-unmatchable': true,
// Unknown 未知: true,
// '不允许未知批注': true,
'annotation-no-unknown': true,
//禁止未知的 at 规则
'at-rule-no-unknown': true,
// 不允许声明中属性的未知值
'declaration-property-value-no-unknown': true,
//禁止未知函数
'function-no-unknown': true,
//不允许未知的媒体功能名称
'media-feature-name-no-unknown': true,
//不允许媒体功能的未知值
'media-feature-name-value-no-unknown': true,
//禁止未知动画
'no-unknown-animations': true,
//禁止未知的自定义属性
'no-unknown-custom-properties': true,
//禁止未知属性
'property-no-unknown': true,
//不允许未知的伪类选择器
'selector-pseudo-class-no-unknown': true,
//禁止未知的伪元素选择器
'selector-pseudo-element-no-unknown': true,
//禁止未知类型选择器
'selector-type-no-unknown': true,
// 不允许未知单位
'unit-no-unknown': true,
// Enforce conventions 强制执行约定
// 禁止供应商前缀?
'property-no-vendor-prefix': null,
'no-descending-specificity': null,
// Length 长度
// 不允许使用长度为零的单位
// 'length-zero-no-unit': true,
// Case 大小写
// CSS的函数的关键名字要求为特定的大小写, 可选值, lower: 小写, upper: 大写
'function-name-case': 'lower',
// 为类型选择器指定小写或大写
'selector-type-case': 'lower',
// 为关键字值指定小写或大写
'value-keyword-case': 'lower',
// Empty lines 空行
// 要求或禁止在 @ 规则之前使用空行
// 错误示例:
// 1. a {} @media {}
// 2. 中间没有空行:
// a {}
// @media {}
'at-rule-empty-line-before': 'always',
// 要求或禁止在注释前使用空行 可选值: never: 注释前不允许空行, always: 注释前必须有空行
'comment-empty-line-before': [
'always',
{
'except': ['first-nested'],
},
],
// 要求或禁止在自定义属性之前使用空行
'custom-property-empty-line-before': 'always',
// 要求或禁止在声明前, 例如 --bar: pink 使用空行可选值: always: 回车区分, never: 不回车区分
'declaration-empty-line-before': 'never',
// 要求或禁止在规则前使用空行
'rule-empty-line-before': 'never',
// Max & min 最大值和最小值
// 限制单行声明块中的字段数量
// a { color: pink; top: 3px; } 是错误, 因为超过了1个属性
'declaration-block-single-line-max-declarations': 1,
// 限制声明中属性列表的值数
// 'declaration-property-max-values':
// 样式嵌套最大层数
// https://stylelint.io/user-guide/rules/max-nesting-depth/
'max-nesting-depth': [
4,
{
'ignore': ['blockless-at-rules', 'pseudo-classes'],
},
],
// 限制数字中允许的小数位数
'number-max-precision': 2,
// 限制选择器中属性选择器的数量
'selector-max-attribute': 3,
//限制选择器中的类数
'selector-max-class': 3,
// 限制选择器中的运算器数量
'selector-max-combinators': 1,
// 限制选择器中的选择器数量
// 'selector-max-compound-selectors': 1,
// 限制选择器中 ID 选择器的数量
'selector-max-id': 1,
// 限制选择器中的伪类数
'selector-max-pseudo-class': 1,
// 限制选择器的特异性
// 'selector-max-specificity': 2,
// 限制选择器中的类型选择器数量
'selector-max-type': 2,
// 限制选择器中通用选择器的数量
'selector-max-universal': 1,
// 限制时间值的最小毫秒数
'time-min-milliseconds': 1,
// Notation 表示形式
// 指定 alpha 值的百分比或数字表示法, 可选值: "number"|"percentage", 不选则允许数字与百分比的表示
// 'alpha-value-notation': 'percentage',
//指定 color-functions 的现代或传统表示法, 可选值: "modern": 需要逗号, "legacy": 不需要逗号, 以空格区分
'color-function-notation': 'modern',
//指定十六进制颜色的短表示法或长表示法, 可选值: "short"|"long"
// 'color-hex-length': 'short',
// 指定字体粗细的数字或命名表示法
// 'font-weight-notation': '',
//指定度数色调的数字或角度表示法
// 'hue-degree-notation': '',
//指定规则的 @import 字符串或 URL 表示法, "string": 以引号表示, "url": 以url(xx)表示
'import-notation': 'url',
//指定关键帧选择器的关键字或百分比表示法
'keyframe-selector-notation': 'percentage-unless-within-keyword-only-block',
// 指定亮度的数字或百分比表示法
// 指定媒体功能范围的上下文或前缀表示法, 可选择: "percentage"|"number"
// 'lightness-notation': '',
// 正确示例:
// @media (width >= 1px) {}
// @media (1px <= width <= 2px) {}
'media-feature-range-notation': 'context',
// 为 :not() 伪类选择器指定简单或复杂表示法, 可选值: "simple"|"complex"
// 'selector-not-notation': '',
// 为适用的伪元素选择器指定单冒号或双冒号表示
'selector-pseudo-element-colon-notation': 'double',
// Pattern 模式
// 指定注释的模式
// 'comment-pattern': '',
// 为自定义媒体查询名称指定模式
// 'custom-media-pattern': '',
// 指定自定义属性的模式
// 'custom-property-pattern': '',
// 指定关键帧名称的模式
// 'keyframes-name-pattern': '',
// 为类选择器指定模式允许类名以大写字母或者小写字母开头,并且可以包含连字符 -
'selector-class-pattern': '^([a-z][a-z0-9]*)(-[a-z][a-z]*)*$',
// 指定 ID 选择器的模式
'selector-id-pattern': '^([a-z][a-z0-9]*)(-[a-z][a-z]*)*$',
// 为嵌套在规则中的规则选择器指定模式
// 'selector-nested-pattern': '',
// Quotes 引号
// 要求或禁止字体系列名称使用引号, 期望每个不是关键字的字体系列名称周围都有引号
'font-family-name-quotes': 'always-unless-keyword',
// 要求或禁止 url 使用引号
'function-url-quotes': 'never',
// 要求或禁止属性值使用引号, always: 必须加引号, never: 不需要加引号
'selector-attribute-quotes': 'always',
// Redundant 冗余
// 禁止在声明块中使用冗余的 longhand 属性
// 'declaration-block-no-redundant-longhand-properties': [
// 'true',
// {
// ["padding", "/border/"],
// },
// ],
// 不允许在速记属性中使用冗余值
// 'shorthand-property-no-redundant-values': '',
// Whitespace inside 内部空白
// 要求或禁止在注释标记的内部使用空格。
'comment-whitespace-inside':'always',
},
}
Git 提交前的操作
这里为提交之前的格式化代码
.husky/pre-commit:
cd frontend
pnpm lint-staged
Git Commit Hook校验
这里使用特定的提交格式
.commitlint.config.js:
export default {
extends: ['@commitlint/config-conventional'],
'type-enum': [
2,
'always',
[
'feat',
'fix',
'perf',
'style',
'docs',
'test',
'refactor',
'build',
'ci',
'chore',
'revert',
'wip',
'workflow',
'types',
'release',
],
],
}
.husky/commit-msg:
cd frontend
pnpm commitlint ${1}
IDE支持
VSCode
为了简化代码格式化操作,需要在VSCode保存时自动格式化代码,可以在.vscode/settings.json文件添加如下配置
{
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"editor.formatOnSaveMode": "file",
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"files.eol": "\n",
"editor.tabSize": 2,
"[jsonc]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
}