我正在参加「掘金·启航计划」
从零搭建pnpm + monorepo + vuepress2.x + vue3的组件库(二)之配置eslint+prettier+husky+lint-staged(pnpm版)
背景
本文是以在vue搭建的组件库中使用eslint
和prettier
解决代码格式校验和格式化代码风格的使用指南,但是不限于是组件库项目,只要是vue
项目全部通用。你可以按步骤一步步配置,可以说是手把手教你配置eslint
和prettier
了,以及怎么通过husky
+lint-staged
去帮你做git提交前的代码校验和格式化。
注意⚠️:本文的使用的包管理工具是pnpm,如果你项目中用的是npm,只需要把文中的安装命令pnpm改为npm,并且去掉
-w
简写符号;如果你使用的是yarn,那么只需要把pnpm i
改为yarn add
,并且去掉-w
简写符号。
安装eslint
eslint是一个代码检查工具,通过配置一个个规则来限制代码的合法性和风格。在根目录安装:
pnpm i eslint -D -w
eslint 主要解决的是代码质量问题(意味着程序存在潜在bug),prettier解决的是代码风格问题
安装prettier并配置eslint校验
安装eslint-plugin-prettier
插件,把 Prettier 推荐的格式问题的配置以 ESLint rules 的方式写入,这样做可以统一代码问题的来源,报错的来源依旧是 ESLint 。
pnpm i prettier -D -w
pnpm i eslint-config-prettier -D -w //用于解决和 Prettier 冲突的 ESLint 的配置
pnpm i eslint-plugin-prettier -D -w //启用 eslint-plugin-prettier
在根目录增加.eslintrc.js
文件,用于配置校验规则
module.exports = {
root: true,
env: {
es6: true,
browser: true,
node: true,
},
parser: 'vue-eslint-parser',
plugins: ['vue', '@typescript-eslint', 'prettier'],
extends: [
'eslint:recommended',
'plugin:import/recommended',
'plugin:vue/vue3-recommended',
'plugin:@typescript-eslint/recommended',
'plugin:prettier/recommended',
'prettier',
],
parserOptions: {
ecmaVersion: 12,
parser: '@typescript-eslint/parser',
sourceType: 'module',
ecmaFeatures: {
jsx: true,
},
},
rules: {
// js/ts
camelcase: ['error', { properties: 'never' }],
'no-console': ['warn', { allow: ['error'] }],
'no-debugger': 'warn',
'no-constant-condition': ['error', { checkLoops: false }],
'no-restricted-syntax': ['error', 'LabeledStatement', 'WithStatement'],
'no-return-await': 'error',
'no-var': 'error',
'no-empty': ['error', { allowEmptyCatch: true }],
'prefer-const': [
'warn',
{ destructuring: 'all', ignoreReadBeforeAssign: true },
],
'prefer-arrow-callback': [
'error',
{ allowNamedFunctions: false, allowUnboundThis: true },
],
'object-shorthand': [
'error',
'always',
{ ignoreConstructors: false, avoidQuotes: true },
],
'prefer-rest-params': 'error',
'prefer-spread': 'error',
'prefer-template': 'error',
'no-redeclare': 'off',
'@typescript-eslint/no-redeclare': 'error',
// best-practice
'array-callback-return': 'error',
'block-scoped-var': 'error',
'no-alert': 'warn',
'no-case-declarations': 'error',
'no-multi-str': 'error',
'no-with': 'error',
'no-void': 'error',
'sort-imports': [
'warn',
{
ignoreCase: false,
ignoreDeclarationSort: true,
ignoreMemberSort: false,
memberSyntaxSortOrder: ['none', 'all', 'multiple', 'single'],
allowSeparatedGroups: false,
},
],
// ts
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/no-non-null-asserted-optional-chain': 'off',
'@typescript-eslint/consistent-type-imports': [
'error',
{ disallowTypeAnnotations: false },
],
'@typescript-eslint/ban-ts-comment': ['off', { 'ts-ignore': false }],
// vue
'vue/no-v-html': 'off',
'vue/require-default-prop': 'off',
'vue/require-explicit-emits': 'off',
'vue/multi-word-component-names': 'off',
'vue/prefer-import-from-vue': 'off',
'vue/no-v-text-v-html-on-component': 'off',
'vue/html-self-closing': [
'error',
{
html: {
void: 'always',
normal: 'always',
component: 'always',
},
svg: 'always',
math: 'always',
},
],
// prettier
'prettier/prettier': 'error',
// import
'import/first': 'error',
'import/no-duplicates': 'error',
'import/no-unresolved': 'off',
'import/namespace': 'off',
'import/default': 'off',
'import/no-named-as-default': 'off',
'import/no-named-as-default-member': 'off',
'import/named': 'off',
},
}
在根目录增加.prettierrc
文件,用于配置代码风格
{
"semi": false,
"singleQuote": true,
"overrides": [
{
"files": ".prettierrc",
"options": {
"parser": "json"
}
}
]
}
安装husky+lint-staged对本地代码进行拦截检查
husky
:操作git钩子的工具,
lint-staged
:本地暂存代码检查工具
通过这两个工具配合操作,使用husky
拦截git的一系列操作(本文只涉及拦截git commit
操作),监听到提交命令之后,然后交给lint-staged
对本地提交的代码进行格式检查,检查通过则正常提交,不通过则提示错误信息,取消代码暂存。
- 安装这两个工具
pnpm i lint-staged -D -w
pnpm i husky -D -w
// 可以使用下面的命令统一安装
pnpm i lint-staged husky -D -w
2. 初始化husky,同时会在根目录创建.husky
文件夹
// 在package.json中添加脚本(该命令需要npm版本为7.24.2以上的版本才支持set-script)
npm set-script prepare "husky install"
// 初始化husky,将 git hooks 钩子交由,husky执行
pnpm run prepare
// 在.husky文件夹下添加pre-commit文件,命令为:pnpm exec lint-staged
npx husky add .husky/pre-commit "pnpm exec lint-staged"
注意⚠️:千万不用自己手动创建pre-commit文件,这样会不生效,只能通过命令创建
- 在
package.json
文件中配置lint-staged
,或者在根目录创建 **.lintstagedrc.json
**配置检查机制,内容如下:
"lint-staged": {
"*.{vue,js,ts,jsx,tsx,json}": "eslint --fix",
"*.md": [
"prettier --write"
]
},
本地操作提交,验证配置是否生效。
Q&A
- 本地执行eslint提交校验的时候,提示:"
<script setup>
cannot contain ES module exports vue/no-export-in-script-setup"
问题原因: .vue
文件中,使用<script setup>
的同时,还出现了export
。
由于注册组件这里使用的是 Table.name
进行注册,export
是为了导出组件名称,看起来又必不可少。
解决方案1:eslint提示了啥,我们就关闭这个提示,即在eslintrc.js
的rules
添加'vue/no-export-in-script-setup': 'off'
这样就关闭了这个校验规则
解决方案2:使用插件unplugin-vue-define-options
,通过使用 defineOptions
宏帮你设置name
属性,而不需要单独写一个<script></script>
来定义名称。参考链接
pnpm i unplugin-vue-define-options -D -w
在vuepress2.x
版本中配置vite插件需要配置Vite 打包工具(v2.vuepress.vuejs.org/zh/referenc…)
pnpm i -D @vuepress/bundler-vite@next -w
在 docs/.vuepress/config.ts
文件中引入
import DefineOptions from 'unplugin-vue-define-options/vite'
import { viteBundler } from '@vuepress/bundler-vite'
export default {
....
bundler: viteBundler({
viteOptions: {
plugins: [DefineOptions()],
},
}),
}
在组件中使用defineOptions
<script setup lang="ts">
defineOptions({
name: 'BaseTable',
})
</script>
解决方案3:跟方案2类似,使用vite-plugin-vue-setup-extend
插件,可以直接将name
属性写在script标签上
pnpm i vite-plugin-vue-setup-extend -D -w
// 同样需要安装vite打包工具
pnpm i -D @vuepress/bundler-vite@next -w
在 docs/.vuepress/config.ts
文件中引入
import VueSetupExtend from 'vite-plugin-vue-setup-extend'
import { viteBundler } from '@vuepress/bundler-vite'
export default {
....
bundler: viteBundler({
viteOptions: {
plugins: [VueSetupExtend()],
},
}),
}
在组件中使用defineOptions
<script setup lang="ts" name="BaseTable">
...
</script>