ESLint
https://zh-hans.eslint.org/docs/latest/use/getting-started
- ESLint是一个插件化并且可配置的 JavaScript 语法规则和代码风格的检查工具
- 代码质量问题:使用方式有可能有问题
- 代码风格问题:风格不符合一定规则
初始化
npm init @eslint/config
pnpm install eslint eslint-plugin-vue @typescript-eslint/parser @typescript-eslint/eslint-plugin vue-eslint-parser eslint-define-config -D
常见的包
名称 | 说明 |
---|---|
eslint | ESLint 是一个用于识别和报告在 ECMAScript/JavaScript 代码中发现的模式的工具 |
eslint-plugin-vue | Vue 的官方 ESLint 插件 |
@typescript-eslint/parser | 一个 ESLint 解析器,它利用 TypeScript-ESTree 允许 ESLint 检查 TypeScript 源代码 |
@typescript-eslint/eslint-plugin | 一个 ESLint 插件,为 TypeScript 代码库提供 lint 规则 |
@vue/eslint-config-typescript | Vue 的 eslint-config-typescript |
案例
.eslintrc.js
const { defineConfig } = require("eslint-define-config")
module.exports = defineConfig({
root: true,
env: {
browser: true,
node: true,
es2021: true,
},
extends: [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:vue/vue3-essential",
],
parser: "vue-eslint-parser",
parserOptions: {
parser: "@typescript-eslint/parser",
ecmaVersion: "latest",
sourceType: "module",
},
plugins: ["@typescript-eslint", "vue"],
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": [
"warn",
{
endOfLine: "auto",
},
],
},
})
.eslintignore
*.sh
node_modules
*.md
*.woff
*.ttf
.vscode
.idea
dist
/public
/docs
.husky
.local
/bin
Dockerfile
components.d.ts
auto-imports.d.ts
*.min.js
package.json
{
"scripts": {
"dev": "vite",
"build": "vue-tsc --noEmit && vite build",
+ "lint:eslint": "eslint --cache --max-warnings 0 \"{src,tests,types}/**/*.{vue,js,jsx,ts,tsx}\" --fix",
},
}
Prettier
ESLint 主要解决的是代码质量问题
代码质量规则
- no-unused-vars 禁止出现未使用过的变量
- no-implicit-globals 禁止在全局范围内使用变量声明和 function 声明
- prefer-promise-reject-errors 要求使用 Error 对象作为 Promise 拒绝的原因
prettier 主要解决的是代码风格问题
- max-len 最大长度
- no-mixed-spaces-and-tabs 不允许空格和 tab 混合
- keyword-spacing 关键字的空
- comma-style 冒号风格
1 安装
npm install prettier eslint-plugin-prettier @vue/eslint-config-prettier pretty-quick -D
名称 | 说明 |
---|---|
prettier | 代码格式化 |
eslint-plugin-prettier | 作为 ESLint 规则运行得 prettier |
@vue/eslint-config-prettier | Vue 的 eslint-config-prettier |
其他 :关闭所有不必要或可能与 Prettier 冲突的规则。
stylelint-config-prettier
2. 案例
.eslintrc.cjs
module.exports = {
root: true,
env: {
browser: true,
es2021: true,
node: true
},
extends: [
"plugin:vue/vue3-recommended",
"eslint:recommended",
"@vue/typescript/recommended",
+ //添加两个插件
+ "prettier",
+ "@vue/eslint-config-prettier"
],
parserOptions: {
parser: "@typescript-eslint/parser",
ecmaVersion: 2021
},
rules: {
+ //'prettier/prettier': "off",//关闭警告
+ // 配置规则级别和改正规则
+ "prettier/prettier": [
+ "error",
+ {
+ singleQuote: true,
+ tabWidth: 2,
+ indent: 2,
+ semi: false,
+ trailingComma: "none",
+ endOfLine: "auto"
+ }
+ ],
"no-unused-vars": "off",
"vue/no-unused-vars": "off",
"@typescript-eslint/no-unused-vars": "off"
},
globals: {
defineProps: "readonly"
}
}
.prettierrc.cjs
/** 配置项文档:https://prettier.io/docs/en/configuration.html */
module.exports = {
/** 每一行的宽度 */
printWidth: 120,
/** Tab 键的空格数 */
tabWidth: 2,
/** 在对象中的括号之间是否用空格来间隔 */
bracketSpacing: true,
/** 箭头函数的参数无论有几个,都要括号包裹 */
arrowParens: "always",
/** 换行符的使用 */
endOfLine: "auto",
/** 是否采用单引号 */
singleQuote: true,
/** 对象或者数组的最后一个元素后面不要加逗号 */
trailingComma: "none",
/** 是否加分号 */
semi: false,
/** 是否使用 Tab 格式化 */
useTabs: false,
}
.prettierignore
/dist/*
.local
.output.js
/node_modules/**
**/*.svg
**/*.sh
/public/*
.npmrc
index.html
pnpm-lock.yaml
components.d.ts
auto-imports.d.ts
*.min.js
package.json
{
"lint:prettier": "prettier --write \"{src,tests,types}/**/*.{vue,js,jsx,ts,tsx,json,css,less,scss,html,md}\"",
"lint:pretty": "pretty-quick --staged"
}
3.规则
https://prettier.io/docs/en/options.html
module.exports = {
printWidth: 120, //最大列宽为 120 字符
tabWidth: 2, //使用 2 个空格缩进
useTabs: false, //不使用制表符缩进,使用空格
semi: false, //不使用分号
singleQuote: true, //使用单引号
vueIndentScriptAndStyle: false, //不要在 Vue 文件中缩进脚本和样式标签。
quoteProps: "as-needed", //仅在需要时在对象属性周围添加引号。
bracketSpacing: true, //对象文字中括号之间的空格。
trailingComma: "none", //不使用尾随逗号
jsxBracketSameLine: false, // 在 jsx 中和后面的标签处于同一行
jsxSingleQuote: false, //不在 jsx 中使用单引号
arrowParens: "always", //在唯一的箭头函数参数周围包含括号
insertPragma: false,
requirePragma: false,
proseWrap: "never",
htmlWhitespaceSensitivity: "strict",
endOfLine: "auto", // 自动选择行结束符
rangeStart: 0,
singleAttributePerLine: false, //在 HTML、Vue 和 JSX 中强制每行使用单一属性
}
editorconfig
- editorconfig帮助开发人员在不同的编辑器和 IDE 之间定义和维护一致的编码样式
- 不同的开发人员,不同的编辑器,有不同的编码风格,而 EditorConfig 就是用来协同团队开发人员之间的代码的风格及样式规范化的一个工具,而.editorconfig 正是它的默认配置文件
- EditorConfig
- vscode 这类编辑器,需要自行安装 editorconfig 插件
.editorconfig
# 配置项文档:https://editorconfig.org/
# 告知 EditorConfig 插件,当前即是根文件
root = true
# 适用全部文件
[*]
## 设置字符集
charset = utf-8
## 缩进风格 space | tab,建议 space
indent_style = space
## 缩进的空格数(修改这里的话需要将 prettier.config.js 和 .vscode -> settings.json 也同步修改)
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
.vscode/setting.json
{
"editor.tabSize": 2,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"[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"
}
}
extensions.json
{
"recommendations": [
"editorconfig.editorconfig",
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
"vue.vscode-typescript-vue-plugin",
"vue.volar",
"antfu.unocss",
"zixuanchen.vitest-explorer",
"wiensss.region-highlighter"
]
}
git hooks
- 可以在
git commit
之前检查代码,保证所有提交到版本库中的代码都是符合规范的 - 可以在
git push
之前执行单元测试,保证所有的提交的代码经过的单元测试 - husky可以让我们向项目中方便添加
git hooks
,它会自动在仓库中的.git/
目录下增加相应的钩子,比如pre-commit
钩子就会在你执行git commit
命令的时候的触发 - lint-staged用于实现每次提交只检查本次提交所修改的文件
- Commitlint 可以规范
git commit -m ""
中的描述信息
.gitignore
.DS_Store
node_modules
/screenshots
/dist
dist.zip
dist_electron
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Editor directories and files
.idea
# .vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
types/auto-imports.d.ts
types/components.d.ts
husky
安装
npm install husky -D
npm pkg set scripts.prepare="husky install"
npm run prepare
使用
Edit package.json > prepare
script and run it once:npm run prepare
npm pkg set scripts.prepare="husky install"
npm run prepare
# `npm test` will run every time you commit
LintStaged
https://github.com/okonet/lint-staged
安装
npm install lint-staged -D
npx husky add .husky/pre-commit "npx --no-install lint-staged"
Package.json
"lint-staged": {
"*.{vue,js,jsx,ts,tsx}": [
"eslint --fix",
"prettier --write"
],
"*.{css,less,scss,html,md}": [
"prettier --write"
],
"package.json": [
"prettier --write"
]
},
"scripts": {
"lint": "pnpm lint:eslint && pnpm lint:prettier && pnpm lint:styleLint",
"lint:eslint": "eslint --max-warnings 0 \"{src,tests,types}/**/*.{vue,js,jsx,ts,tsx}\" --fix --cache --cache-location node_modules/.cache/eslint/",
"lint:prettier": "prettier --write \"{src,tests,types}/**/*.{vue,js,jsx,ts,tsx,json,css,less,scss,html,md}\"",
"lint:stylelint": "stylelint --fix \"**/*.{vue,less,postcss,css,scss}\" --cache --cache-location node_modules/.cache/stylelint/",
"lint:lint-staged": "lint-staged",
"prepare": "husky install",
},
"lint-staged": {
"*.{js,jsx,ts,tsx}": [
"eslint --fix",
"prettier --write"
],
"*.json": [
"prettier --write"
],
"*.vue": [
"eslint --fix",
"prettier --write",
"stylelint --fix"
],
"*.{scss,less,styl,html}": [
"stylelint --fix",
"prettier --write"
],
"*.md": [
"prettier --write"
]
},
commitlint 配置
commitlint推荐我们使用config-conventional配置去写
commit
提交格式
git commit -m <type>[optional scope]: <description>
type
:用于表明我们这次提交的改动类型,是新增了功能?还是修改了测试代码?又或者是更新了文档?optional scope
:一个可选的修改范围。用于标识此次提交主要涉及到代码中哪个模块description
:一句话描述此次提交的主要内容,做到言简意赅
1. type
类型 | 描述 |
---|---|
build | 编译相关的修改,例如发布版本、对项目构建或者依赖的改动 |
chore | 其他修改, 比如改变构建流程、或者增加依赖库、工具等 |
ci | 持续集成修改 |
docs | 文档修改 |
feature | 新特性、新功能 |
fix | 修改 bug |
perf | 优化相关,比如提升性能、体验 |
refactor | 代码重构 |
revert | 回滚到上一个版本 |
style | 代码格式修改 |
test | 测试用例修改 |
2. 安装
https://commitlint.js.org/#/guides-local-setup?id=install-commitlint
安装 commitlint
pnpm install @commitlint/cli @commitlint/config-conventional -D
安装 husky
# Install Husky v6
npm install husky --save-dev
# or
yarn add husky --dev
# Activate hooks
npx husky install
# or
yarn husky install
Add hook
npx husky add .husky/commit-msg 'npx --no-install commitlint --edit ${1}'
3. 配置
https://commitlint.js.org/#/reference-configuration
commitlint.config.js
module.exports = {
extends: ["@commitlint/config-conventional"],
rules: {
"type-enum": [
2,
"always",
[
"build",
"chore",
"ci",
"docs",
"feature",
"fix",
"perf",
"refactor",
"revert",
"style",
"test",
],
],
},
}
4. 详细案例
module.exports = {
ignores: [(commit) => commit.includes("init")],
extends: ["@commitlint/config-conventional"],
parserPreset: {
parserOpts: {
headerPattern:
/^(\w*|[\u4e00-\u9fa5]*)(?:[\(\(](.*)[\)\)])?[\:\:] (.*)/,
headerCorrespondence: ["type", "scope", "subject"],
referenceActions: [
"close",
"closes",
"closed",
"fix",
"fixes",
"fixed",
"resolve",
"resolves",
"resolved",
],
issuePrefixes: ["#"],
noteKeywords: ["BREAKING CHANGE"],
fieldPattern: /^-(.*?)-$/,
revertPattern: /^Revert\s"([\s\S]*)"\s*This reverts commit (\w*)\./,
revertCorrespondence: ["header", "hash"],
warn() {},
mergePattern: null,
mergeCorrespondence: null,
},
},
rules: {
"body-leading-blank": [2, "always"],
"footer-leading-blank": [1, "always"],
"header-max-length": [2, "always", 108],
"subject-empty": [2, "never"],
"type-empty": [2, "never"],
"type-enum": [
2,
"always",
[
"feat", // 新特性
"fix", // 修复bug
"perf", // 优化(性能)
"style", // 样式
"docs", // 文档
"test", // 单元测试
"refactor", // 重构
"build", // 依赖打包相关
"ci", // 持续集成
"chore", // 日常
"revert", // 回滚
"wip", // 开发中
"workflow", // 工作流
"types", // 类型定义
"release", // 发布
"improvement", // 改进
],
],
},
}
5. 常见问题
问题 1
hint: The '.husky/pre-commit' hook was ignored because it's not set as executable.
hint: You can disable this warning with `git config advice.ignoredHook false`.
hint: The '.husky/commit-msg' hook was ignored because it's not set as executable.
hint: You can disable this warning with `git config advice.ignoredHook false`.
这些提示的意思是:Husky 预提交钩子和提交消息钩子没有被设置为可执行文件,所以 Git 忽略了它们。
具体原因是:使用 Husky 时,它需要在 .husky 目录下创建一些钩子脚本文件,如:
.husky/pre-commit
.husky/commit-msg
但这些文件默认情况下不是可执行的。需要使用以下命令设置为可执行:
# 设置为可执行
chmod +x .husky/pre-commit
chmod +x .husky/commit-msg
毕竟只有可执行文件才能被 Git 用作钩子执行。