我报名参加金石计划1期挑战——瓜分10万奖池,这是我的第1篇文章,点击查看活动详情
前言
在团队开发中,通常需要统一项目的代码规范和书写风格。这时候eslint和stylelint就派上用场了,eslint可以限制项目中vue、js、ts、tsx的代码风格;stylelint可以限制项目中样式文件和其他文件中的样式规范风格;使用commitlint可以在用户提交代码前校验代码是否符合规范(eslint、stylelintt),不规范的代码会被禁止提交到远程仓库。
开发环境
node 16.14.2npm 8.5.0
项目初始化
如果为旧项目配置则忽略此步骤
使用 vite 创建项目, 执行下面命令:
npm create vite 你的项目名称
回车后的选择(箭头上下键切换、空格选择、回车确认)
- Ok to proceed? (y)
- y
- Select a framework:
- Vue
- Select a variant:
- TypeScript
如下图所示:
配置 eslint
需要cd到项目根目录执行指令,执行命令前请确保当前目录为项目根目录
安装eslint
eslint 为不属于项目依赖,但是可以保证代码的质量,约束代码的风格,为了减少代码打包后的体积,建议安装到 devDependencies 中, 及安装时增加 -D 指令(npm 的使用这里不做介绍,不懂的可以问下度娘或者问问神奇海螺)。
npm install eslint -D
初始化 eslint
高版本的 Node 自带 npm 模块,所以可以直接使用 npx 命令。万一不能用,则需要手动安装一下。
npx eslint --init
回车后的选择(箭头上下键切换、空格选择、回车确认)
- How would you like to use ESLint? ...
- To check syntax and find problems
- What type of modules does your project use? ...
- JavaScript modules (import/export)
- Which framework does your project use? ...
- Vue.js
- Does your project use TypeScript?
- Yes
- Where does your code run? ...
- 直接回车,默认只选择: Browser
- What format do you want your config file to be in? ...
- JavaScript
- Would you like to install them now with npm?
- Yes
如下图所示:
执行完上面的操作之后会在项目的根目录生成一个 .eslintrc.js 文件,改文件为生成的 eslint 配置文件(根据刚才你的选择生成的),eslint 版本不同后缀可能略有不同,也可能为 .cjs 或 .json,但是不影响使用。文件内容如下:
# .eslintrc.js
module.exports = {
"env": {
"browser": true,
"es2021": true
},
"extends": [
"eslint:recommended",
"plugin:vue/vue3-essential",
"plugin:@typescript-eslint/recommended"
],
"parserOptions": {
"ecmaVersion": "latest",
"parser": "@typescript-eslint/parser",
"sourceType": "module"
},
"plugins": [
"vue",
"@typescript-eslint"
],
"rules": {
}
}
注意 extends 中的 "plugin:vue/vue3-essential", 如果你的是 "plugin:vue/essential" 就修改为 "plugin:vue/vue3-essential", 不然有可能会出现 vue/no-multiple-template-root 报错。
在 package.json 文件中增加 scripts 命令
- 增加
lint命令用于执行eslint校验 - 增加
lint:fix命令用于执行eslint代码格式化
{
"scripts": {
"lint": "eslint . --ext .vue,.js,.ts,.jsx,.tsx",
"lint:fix": "eslint . --ext .vue,.js,.ts,.jsx,.tsx --fix"
},
}
修改 .eslintrc.js 配置文件
- 由于项目是基于 vite 来构建的,需要使用到
node的一些语法,例如path、env等, 所以在配置文件的env中加上node: true防止报错
"env": {
"browser": true,
"es2021": true,
+ "node": true
},
- 生成的 eslint 配置默认会 vue 的部分语法不是很兼容(由于
eslint没有解析.vue后缀文件的能力,需要额外的解析器用来解析.vue后缀的文件),需要额外修改一下配置,在parserOptions前面一行加上parser: "vue-eslint-parser",用来解析.vue文件。
...
+ "parser": "vue-eslint-parser",
- 这时候执行
npm run lint命令发现还是有地方不符合规范,这时候我们需要增加忽略配置文件.eslintignore在文件中忽略对src/vite-env.d.ts文件的校验(接下来的段落eslint 忽略检查中会详细说明,文件内容也在这一段中),这时候我们发现代码通过了我们的eslint校验。
eslint 忽略检查
通常情况下对于一些不需要检查的 eslint 规则, 一般只需要在 .eslintrc.js 配置文件中的 rule 中增加自定义校验或者忽略规则即可,但是有时候我们需要忽略对某些文件或目录的 eslint 检查,则需要创建一个 .eslintignore 文件进行配置。下面是我的 .eslintignore 文件内容
node_modules
dist/
test
build/
.vscode
.github
.husky
src/vite-env.d.ts
配置 prettier
根据项目需求配置,但是一般都需要增加 prettier 配置,用来处理一下额外的配置。
安装 prettier
很多时候 prettier 可能会和 eslint 产生冲突,所以需要另外安装插件处理冲突。
npm install prettier -D
# 处理 prettier 与 eslint 冲突
npm install eslint-config-prettier eslint-plugin-prettier -D
.prettierrc.js
.prettierrc.js 是 prettier 的配置文件, 这个文件需要我们手动创建
我的文件内容如下:
module.exports = {
printWidth: 100,
tabWidth: 2,
singleQuote: true,
semi: true,
trailingComma: 'all',
endOfLine: 'auto',
bracketSpacing: true
};
配置使用 prettier
extends: [
'eslint:recommended',
'plugin:vue/vue3-essential',
'plugin:@typescript-eslint/recommended',
+ 'plugin:prettier/recommended',
],
使用 airbnb 的语法规范
根据项目需求安装。Airbnb 的这份编码规范是互联网上最受欢迎的 JavaScript 编码规范之一。 它几乎涵盖了 JavaScript 的各个方面。
安装规范配置文件
npm install eslint-config-airbnb -D
在 .eslintrc.js 中配置
"extends": [
"eslint:recommended",
"plugin:vue/vue3-essential",
"plugin:@typescript-eslint/recommended",
+ "airbnb",
],
配置 stylelint
参考其他掘金文章的配置: juejin.cn/post/711829…
依赖包安装
安装相关依赖包,如果你的项目中使用了 less 而不是 scss 则将下面命令中的 scss 全部换为 less
npm install stylelint postcss postcss-scss postcss-html stylelint-config-prettier stylelint-config-recommended-scss stylelint-config-standard stylelint-config-standard-vue stylelint-scss stylelint-order -D
各个包的说明:
- stylelint:
css样式lint工具, 用户检测样式文件(.css文件) - postcss: 转换
css代码工具 - postcss-scss: 识别 scss 语法的插件
- postcss-html: 识别
html/vue中的<style></style>标签中的样式 - stylelint-config-standard: Stylelint的标准可共享配置规则,详细可查看官方文档
- stylelint-config-prettier: 关闭所有不必要或可能与
Prettier冲突的规则 - stylelint-config-recommended-scss: scss的推荐可共享配置规则,详细可查看官方文档
- stylelint-config-standard-vue: lint.vue文件的样式配置
- stylelint-scss:
stylelint-config-recommended-scss的依赖,scss的stylelint规则集合 - stylelint-order: 指定样式书写的顺序,在
.stylelintrc.js中order/properties-order指定顺序
在 package.json 文件中增加 scripts 命令
为了区分eslint和stylelint 这里将package.json中的 script修改为下面命令:
"scripts": {
"eslint": "eslint . --ext .js,.jsx,.ts,.tsx,.vue",
"eslint:fix": "eslint . --fix --ext .js,.jsx,.ts,.tsx,.vue",
"stylelint": "stylelint \"./**/*.{css,scss,sass,vue,html}\"",
"stylelint:fix": "stylelint \"./**/*.{css,scss,sass,vue,html}\" --fix",
"lint": "npm run eslint & npm run stylelint",
"lint:fix": "npm run eslint:fix & npm run stylelint:fix"
},
说明:
- eslint 使用
eslint检测项目中的vue、js、jsx、ts、tsx代码。 - eslint:fix 脚本代码格式化,一般搭配 eslint 命令使用。
- stylelint 使用
stylelint检测项目中的样式文件和其他样式规则的书写 - stylelint:fix 样式代码格式化,一般搭配 stylelint 命令使用。
- lint 同时检测样式代码和脚本代码(相当于同时执行了eslint和stylelint)。
- lint:fix 代码格式化,一般搭配 lint 命令使用。
.stylelintrc.js 文件内容
module.exports = {
extends: [
'stylelint-config-standard',
'stylelint-config-recommended-scss',
'stylelint-config-standard-vue',
'stylelint-config-prettier',
],
plugins: ['stylelint-order'],
// 不同格式的文件指定自定义语法
overrides: [
{
files: ['**/*.(scss|css|vue|html)'],
customSyntax: 'postcss-scss',
},
{
files: ['**/*.(html|vue)'],
customSyntax: 'postcss-html',
},
],
ignoreFiles: ['**/*.js', '**/*.jsx', '**/*.tsx', '**/*.ts', '**/*.json', '**/*.md', '**/*.yaml'],
rules: {
'string-quotes': 'single',
// 禁止在具有较高优先级的选择器后出现被其覆盖的较低优先级的选择器
'no-descending-specificity': null,
'selector-pseudo-element-no-unknown': [
true,
{
ignorePseudoElements: ['v-deep'],
},
],
'selector-pseudo-class-no-unknown': [
true,
{
ignorePseudoClasses: ['deep'],
},
],
// 禁用每个选择器之前插入空行
'rule-empty-line-before': null,
// 禁止小于 1 的小数有一个前导零
// 'number-leading-zero': 'never',
// 一些特殊的scss指令
'at-rule-no-unknown': [
true,
{
ignoreAtRules: ['function', 'if', 'else', 'else-if', 'each', 'include', 'mixin'],
},
],
'at-rule-empty-line-before': [
'always',
{
except: ['blockless-after-same-name-blockless', 'first-nested'],
ignore: ['after-comment'],
ignoreAtRules: ['else', 'else-if'],
},
],
// 指定样式的排序
'order/properties-order': [
'position',
'top',
'right',
'bottom',
'left',
'z-index',
'display',
'justify-content',
'align-items',
'flex-shrink',
'float',
'clear',
'overflow',
'overflow-x',
'overflow-y',
'width',
'min-width',
'max-width',
'height',
'min-height',
'max-height',
'padding',
'padding-top',
'padding-right',
'padding-bottom',
'padding-left',
'margin',
'margin-top',
'margin-right',
'margin-bottom',
'margin-left',
'font-size',
'font-family',
'text-align',
'text-justify',
'text-indent',
'text-overflow',
'text-decoration',
'white-space',
'color',
'background',
'background-position',
'background-repeat',
'background-size',
'background-color',
'background-clip',
'border',
'border-style',
'border-width',
'border-color',
'border-top-style',
'border-top-width',
'border-top-color',
'border-right-style',
'border-right-width',
'border-right-color',
'border-bottom-style',
'border-bottom-width',
'border-bottom-color',
'border-left-style',
'border-left-width',
'border-left-color',
'border-radius',
'opacity',
'filter',
'list-style',
'outline',
'visibility',
'box-shadow',
'text-shadow',
'resize',
'transition',
'content',
],
},
};
commitlint 配置
commitlint 可用于在用户
git commit前做一系列的操作,例如代码校验和commit注释校验等。
插件安装
npm install @commitlint/cli @commitlint/config-conventional -D
初始化 commitlint 配置
- 可手动创建
commitlint.config.js文件,写入下面的内容(生成的默认配置文件内容)。 - 使用命令创建
commitlint.config.js文件:
echo "module.exports = {extends: ['@commitlint/config-conventional']}" > commitlint.config.js
生成的默认配置文件内容:
module.exports = {extends: ['@commitlint/config-conventional']}
默认的 git commit 时注释的规则如下 rules[type-enum](该内容为commitlint.config.js的内容):
// commitlint.config.js
module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
'type-enum': [
2,
'always',
[
'build', // 主要目的是修改项目构建系统(例如glup,webpack,rollup的配置等)的提交
'ci', // 修改项目的持续集成流程(Kenkins、Travis等)的提交
'chore', // 构建过程或辅助工具的变化
'docs', // 文档提交(documents)
'feat', // 新增功能(feature)
'fix', // 修复 bug
'pref', // 性能、体验相关的提交
'refactor', // 代码重构
'revert', // 回滚某个更早的提交
'style', // 不影响程序逻辑的代码修改、主要是样式方面的优化、修改
'test', // 测试相关的开发,
],
],
},
};
搭配 husky 使用
通常情况下
commitlint不会单独使用,一般要使用husky一起使用,husky是git hook的管理工具,在提交代码的时候会触发husky的回调,因此可以使用husky监听git commit事件,触发其他的操作或者指令。
安装 husky 和辅助工具 lint-staged
npm install husky -D
# lint-staged 为 husky 的辅助工具
npm install lint-staged -D
安装成功后需要在 package.json 文件中增加一条 scripts 命令,用于在 npm install 初始化 husky
prepare: 在两种情况前运行,一是npm publish命令前,二是不带参数的npm install命令;它会在prepublish之后、prepublishOnly之前执行
"scripts": {
+ "prepare": "husky install",
},
初始化 husky
首次安装成功后,需要手动初始化(因为这时候不需要执行npm install),直接在控制台输入下面命令:
npm run prepare
指令执行成功后会在项目根目录下面生成一个 .husky 目录,该目录下有一个 _ 目录。
添加 commit-msg hook
commit-msg 文件中可以配置在 git commit 时对 commit 注释的校验指令
可手动创建文件再输入文件内容,但是建议使用命令创建,命令如下:
npx husky add .husky/commit-msg 'npx --no -- commitlint --edit "$1"'
上面命令执行成功后会在 .husky 目录下生成一个 commit-msg 文件,该文件的内容如下,表示在 git commit 前执行一下 npx --no -- commitlint --edit $1 指令,对 commit 的注释进行校验。
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npx --no -- commitlint --edit $1
添加 pre-commit hook
pre-commit 文件中可以配置在 git commit 前需要执行的操作
可手动创建文件再输入文件内容,但是建议使用命令创建,命令如下,下面出现的 npm run lint-staged 指令会在接下来的内容中解释(lint-staged 为husky的辅助工具)。
npx husky add .husky/pre-commit "npm run lint-staged"
上面命令执行成功后会在 .husky 目录下生成一个 pre-commit 文件,该文件的内容如下,表示在 git commit 前执行一下 npm run lint-staged 指令,对所有代码进行 eslint校验 和 stylelint校验 ,不符合校验规则就终止commit。
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npm run lint-staged
lint-staged 辅助工具
在项目根目录创建 .lintstagedrc 文件,并写入以下内容:
{
"src/**/*.{js,ts,tsx,vue}": "npm run eslint",
"src/**/*.{vue,css,scss}": "npm run stylelint"
}
内容说明:
- 在遇到以
.js、.ts、.tsx、.vue为后缀的文件时, 使用npm run eslint指令对代码进行校验,校验失败则终止commit。 - 在遇到以
.vue、.css、.scss为后缀的文件时, 使用npm run stylelint指令对代码进行校验,校验失败则终止commit。
写在最后
以上是我前段时间在配置项目时的一些经验积累,部分内容来源网络。以下是我的 package.json 文件内容:
{
"name": "",
"private": true,
"version": "0.0.0",
"description": "",
"scripts": {
"eslint": "eslint . --ext .js,.jsx,.ts,.tsx,.vue",
"eslint:fix": "eslint . --fix --ext .js,.jsx,.ts,.tsx,.vue",
"lint": "npm run eslint & npm run stylelint",
"lint:fix": "npm run eslint:fix & npm run stylelint:fix",
"stylelint": "stylelint \"./**/*.{css,scss,sass,vue,html}\"",
"stylelint:fix": "stylelint \"./**/*.{css,scss,sass,vue,html}\" --fix",
"dev": "vite",
"build": "vue-tsc --noEmit && vite build",
"preview": "vite preview",
"prepare": "husky install",
"lint-staged": "lint-staged"
},
"dependencies": {
"@element-plus/icons-vue": "^2.0.6",
"axios": "^0.27.2",
"crypto-js": "^4.1.1",
"element-plus": "^2.2.11",
"js-pinyin": "^0.1.9",
"jsencrypt": "^3.2.1",
"nanoid": "^3.3.4",
"pinia": "^2.0.21",
"socket.io-client": "^4.5.1",
"spark-md5": "^3.0.2",
"vue": "^3.2.37",
"vue-router": "^4.1.3"
},
"devDependencies": {
"@commitlint/cli": "^17.1.2",
"@commitlint/config-conventional": "^17.1.0",
"@types/crypto-js": "^4.1.1",
"@types/node": "^17.0.30",
"@types/spark-md5": "^3.0.2",
"@typescript-eslint/eslint-plugin": "^5.38.0",
"@typescript-eslint/parser": "^5.38.0",
"@vitejs/plugin-legacy": "^2.0.0",
"@vitejs/plugin-vue": "^3.1.0",
"@vitejs/plugin-vue-jsx": "^2.0.0",
"eslint": "^8.24.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-vue": "^9.5.1",
"husky": "^8.0.1",
"lint-staged": "^13.0.3",
"postcss": "^8.4.16",
"postcss-html": "^1.5.0",
"postcss-scss": "^4.0.4",
"prettier": "^2.7.1",
"sass": "^1.51.0",
"stylelint": "^14.11.0",
"stylelint-config-prettier": "^9.0.3",
"stylelint-config-recommended-scss": "^7.0.0",
"stylelint-config-standard": "^28.0.0",
"stylelint-config-standard-vue": "^1.0.0",
"stylelint-order": "^5.0.0",
"stylelint-scss": "^4.3.0",
"terser": "^5.14.2",
"typescript": "^4.6.4",
"vite": "^3.1.0",
"vite-plugin-html": "^3.2.0",
"vite-plugin-style-import": "^2.0.0",
"vue-tsc": "^0.40.4"
}
}