# vscode 插件与 npm 包,保存时自动修复代码格式错误

# 前言

  日常开发中的绝大多数项目,都是以团队为单位进行的。而由于每个成员的代码习惯和编码差异的不同,最终将导致整个项目的代码参差不齐,出现各式各样风格的代码。

  而此差异性会严重导致团队协作效率低下,后期可维护性也会严重降低。例如代码缩进问题,大部分都是以2个或者4个空格为标准,倘若在没有格式化工具的前提下,迭代起来就会显得异常麻烦,只能逐行添加或者删除空格,不仅浪费时间也毫无意义。

  因此制定统一规范的代码风格,并以此配置出格式化工具显得尤为重要,并且最好是在开发中就将此问题解决掉,于代码运行之前就检测出错误,保证推送到远端的代码是非常规范的。

  此篇文章将以vuecli3脚手架为基础项目,以vscode为代码编辑器,从零开始逐步详细配置相关插件,最终达到保存时自动修复代码格式错误,跟随此篇文章你将了解到。

  • vscode编辑器中Vetur插件的主要功能,多种配置vue代码片段的方式
  • 解决ESLintautofixprettier格式化之间的冲突,了解eslint-config-prettiereslint-plugin-prettier之间的区别差异
  • 旧脚手架项目如何接入格式化工具
  • 代码提交时自动格式化并规范提交日志
  • git hook工具husky版本由v4迁移至v7时,如何修改相关配置项
  • 常见的格式化问题以及处理方式

  如果你仅关注如何使用,不关心配置流程和步骤,那么你可以跳过并浏览每个章节的小结部分,或者也可以访问 GitHub (opens new window) 仓库。

# 准备工作

# 工具版本

  请确保你已经安装了 vscode (opens new window) 编辑器和 node (opens new window) 环境,并且你也已经全局安装了 vuecli (opens new window) 脚手架和 git (opens new window) 工具,此处贴一下相关命令与版本。

vscode
1.61.2

node --version
v14.15.0

vue --version
@vue/cli 4.5.3

git --version
git version 2.27.0.windows.1

# Vuecli3 功能选择

  选择目录或文件夹,开始创建vuecli脚手架,细致部分参考 vuecli (opens new window),注意最好是启动Powershell来创建。

  磁盘根目录下按住Shift键再鼠标右击,选择在此处打开 Powershell 窗口

  运行命令vue create app,选择Manually select features来手动设置更多的选项。

上下键切换选项,Enter确认,空格键选中或取消

  项目功能只选择Vue版本和Babel转译器。

  ;vue版本选择2.x,且各项配置在独立文件中。

  创建成功。

# Vscode 初始插件

  ;vscode插件仅安装chineseReload两种,其中chinese语言拓展插件可安装也可不安装。

如果你还安装有其它插件,为了保证配置不出错,可以都禁用掉,不必卸载

  ;Reload插件将在vscode编辑器的右下角状态栏中添加重载按钮,用于快速重载vscode窗口,方便调试。

  键入Shift + Ctrl + P并输入settings.json打开设置,为了不影响调试效果,你的个性化等其它配置最好都注释掉。

# 修复流程

# Vetur 代码风格 / jsconfig.json

  ;vscode打开vuecli3脚手架后,能明显看到App.vue全是文本字体,没有高亮,代码行距也很紧凑,非常难看。

  因此视觉上的代码高亮问题要先解决,于是在vscode中搜索并安装 Vetur (opens new window) 插件。

  一般在安装完成后vscode右下角会收到警告提示,如果你没有收到,那请点击状态栏Reload按钮,重载后几秒之内你会收到的。

  原因在于Vetur会优先查找项目中的tsconfig.jsonjsconfig.json文件,如果没有就会查找vetur.config.js文件,如果都没有,Vetur就会抛出此警告。

  虽然说警告影响不大,但是有没有像我一样看着就来气的,真是气死强迫症。

  没有那就创建一个jsconfig.json呗。

// jsconfig.json
{
  "compilerOptions": {
    "baseUrl": "./",
    "paths": {
      "@/*": [
        "src/*"
      ]
    }
  },
  "exclude": [
    "node_modules",
    "dist"
  ]
}

  若目录中存在jsconfig.json,则表示此目录是JavaScript项目的根目录,因此包含以下文件的目录就被认为是根目录,更多 详细参考 (opens new window)

├── node_modules
├── ...
├── jsconfig.json
├── ...
├── package.json
├── README.md

  其中exclude用于告知vscode哪些文件不属于源代码,使其IntelliSense(智能感知,即代码自动补全提示等)保持在高性能水平。baseUrl用于指定基础目录,paths表示相对于baseUrl选项计算的路径映射。

  因此@/*即映射到当前目录app下的src目录下的文件或文件夹。如果还是没懂可以看如下图片,输入@/后随即智能提示出了src目录下的文件或文件夹。而此智能提示就是刚才配置jsconfig.json的劳动成果。

可以尝试注释jsconfig.jsonReload重载窗口,再次输入@/查看是否有无智能提示

  代码有高亮看着舒服多了,但是稍显紧凑,因此来修改下行距和Tab空格数。

  根目录下创建.vscode文件夹,新增settings.jsonlineHeight用于指定行高,tabSize用于指定一个Tab键表示几个空格,但是可能会被覆盖。

  原因是因为editor.detectIndentation默认为开启状态,表示根据文件内容自动检测出editor.tabSize,若检测出editor.tabSize则将自动覆盖设置项。因此若要强制一个Tab键为几个空格,可以将editor.detecIndentation设置为false

// .vscode/settings.json
{
  "editor.tabSize": 2,
  "editor.lineHeight": 24
  // "editor.detectIndentation": false
}

  修改后App.vue的风格样式。

# ESLint 错误检查

  ;Veturvue<template><style><script>都进行了错误检查,内部默认捆绑了 eslint-plugin-vue (opens new window) 用于模板错误检查。默认情况下Vetur加载 vue/essential (opens new window) 规则集用于vue2项目。

  但是由于essential规则集有限,现在选择官方推荐的 vue/recommended (opens new window) 规则集来校验代码,因此将自定义Vetur的规则集,下面来自定义错误检查。

  首先关闭Vetur的模板验证。

// .vscode/settings.json
{
  ...
  "vetur.validation.template": false
}

  模板验证已经关闭。

  然后安装vscodeESLint (opens new window) 插件,让ESLint插件来检查错误,而不是Vetur

  ;ESLint插件将使用项目中的eslint依赖包,若项目内未提供,则ESLint插件会全局查找,因此项目需安装eslint依赖包。而针对vue项目,必然要一套检查vue代码的规则集,而此规则集可由eslint-plugin-vue提供。

npm i eslint eslint-plugin-vue -D

  ;eslint-plugin-vue有很多种规则集,而ESLint也不知道具体采用何种规则集,因此还要告知ESLint运用哪一套规则集去检查代码,所以根目录下新建.eslintrc.js文件。

// .eslintrc.js
module.exports = {
  root: true,
  extends: ['plugin:vue/recommended'],
  rules: {
    quotes: ['error', 'single'],
  },
}

  ;ESLint检测配置文件的步骤如下,更多 详细参考 (opens new window)

  • 项目内查找.eslintrc.*package.json文件(package.json内也可配置相关属性)
  • 若未找到,则在父级目录中查找,一直查找至磁盘根目录
  • 若在以上两步中发现root: true,则停止往父级目录中查找

  另外extends表示启用 vue/recommended (opens new window) 规则集,rules中可自定义检查规则,['error', 'single']表示字符串仅能使用单引号,若非单引号则将以错误下划线高亮。

['warn', 'single']将以警告下划线高亮

  新增了配置点击状态栏Reload重载窗口,查看App.vue文件,自定义错误检查已生效。

# Autofix

  现在已经可以对代码进行检查了,手动尝试下修复代码。

  但是你可以打开component/HelloWorld.vue浏览看看,通篇的警告就问你慌不慌。像App.vue代码较少,尚可以手动修复,但是HelloWorld.vue难道要一行一行修改不成。

  有没有可能ESLint检测出代码,并且还能修复呢,嘿嘿,还真有,即ESLintautofix功能。

  将App.vue还是恢复为以下状态。

  ;vscode命令行执行以下命令,即修复App.vue

npx eslint src/App.vue --fix

  修复后的App.vue

  此时控制台输出2个错误,大致描述就是v-for的元素需指定key,而item也声明但是未被使用。你要知道的是ESLint仅仅能修复简单的错误,像v-forkey值问题等还是需要你手动修复的。

  可能你会问,是不是每次代码写完还要针对某个文件执行一次npx eslint ...,如果是那样就真的尴了个大尬。

  在settings.json添加如下命令,即在每次文件被保存时,自动执行fix修复。

可能你会在其它文章中看到source.fixAll,两者区别在于source.fixAll表示针对所有插件开启自动修复,source.fixAll.eslint表示只在ESLint中开启

// .vscode/settings.json
{
  ...
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true
  }
}

  ;App.vue保存时。

# Prettier 格式化

  于是问题都解决了吗?其实并没有哦,看看如下情况。

  由于eslint-plugin-vue中提供的规则集vue/recommended中的规则 vue/html-indent (opens new window),此规则对标签强制使用了一致的缩进,因此保存时<template>自动修复了缩进。

  但是<script>中却没有修复,因为vue/recommended规则集没有提供用于<script>标签缩进的规则,所以修复时<script>内也就没效果,第一种解决方式很简单,就是添加用于vue文件的<script>缩进的规则 vue/script-indent (opens new window) 即可。

// .eslintrc.js
module.exports = {
  ...
  rules: {
    ...
    'vue/script-indent': ['error', 2, {
      'baseIndent': 0,
      'switchCase': 0,
      'ignores': []
    }]
  },
  'overrides': [
    {
      'files': ['*.vue'],
      'rules': {
        'indent': 'off'
      }
    }
  ]
}

  但是此方式不推荐,因为不仅耗时、规则覆盖不全面(可能会少某几条)而且也没必要。其中配置项各参数释义不赘述,更多 详细参考 (opens new window)

  来看一个有趣的操作,你可以在App.vue右键选择格式化文档(也可键入Shift + Alt + F),紧接着再保存(Ctrl + S),你会发现<template><script>中的代码都被修复了。

  为什么会被修复呢?原因在于 格式化文档 (opens new window) 是由Vetur提供的,Vetur默认捆绑了多个格式化程序(例如 prettier (opens new window) 等)用来格式化代码。

  你应该了解的是 代码规则 (opens new window) 分为两类,代码质量规则和代码风格规则。代码质量出现问题,意味着项目可能没法运转,也可能存在潜在的缺陷。而代码风格不一样,代码风格出现问题,仅仅是代码丑陋,你看着不爽。

  代码质量规则。

  代码风格规则。

  而刚才已经知晓了当前eslint使用的vue/recommended规则集,仅仅包括了<template>中的代码质量(v-forkey值问题等)和代码风格(少部分,包括缩进规则等,例如不包括单行的最大长度等)的检测,但是缺少<script>中的代码风格校验(缩进规则等)。

  对于<template><script>两部分的代码缩进,vue/recommend规则集已经可以修复<temnplate>的缩进,而<script>的缩进现在让Vetur来做。

  ;Vetur是开启了vetur.useWorkspaceDependenciestrue,即它可以优先使用根目录下的 prettier (opens new window) 格式化依赖包,因此来自定义Vetur的格式化功能。

npm i prettier -D

  添加.prettierrc.js,加上几条简单的 规则 (opens new window)printWidth(每行最多多少字符换行)、semi(语句末尾分号)、arrowParensavoid表示箭头函数是单个参数时,参数周围省略括号)。

// .prettierrc.js
module.exports = {
  semi: false,
  printWidth: 110,
  arrowParens: 'avoid'
}

  格式化文档后并保存,可以看到<script>中的缩进已经修复。

# FormatOnSave

  频繁右键格式化麻烦不,有没有可能像ESLint一样保存时自动修复呢,答案肯定是有的。

// .vscode/settings.json
{
  ...
  "editor.formatOnSave": true,
}

  现在代码还原尝试下保存呢(Crtl + S)。

  但是意料之外的情况发生了,保存时,起初运行的是ESLintautofix,紧接着运行了Vetur的格式化,即autofix介于Vetur格式化之前了。

  最后导致风格样式按照prettier来了(例如字符串为双引号),显然不符合ESLint的规则。因此格式是修复了,但是却被ESLint检测出错误了。

  以至于频繁保存会频繁闪烁。

# 解决 eslint 与 prettier 冲突

# eslint-config-prettier

  频繁闪烁的根本原因在于eslintprettier一起使用产生了冲突。eslint认为字符串应为单引号,而prettier默认格式化为双引号,所以先来统一单双引号问题,在.prettierrc.js中添加如下规则。

// .prettierrc.js
module.exports = {
  ...
  singleQuote: true
}

  现在还存在换行冲突,prettier认为单行最大长度达到110就可以换行,而eslint认为只要是标签属性都应另起一行。

  注意实际代码格式问题已经解决了(例如缩进问题、单行最大长度等),你会想要是禁用掉eslintvue/max-attributes-per-line (opens new window) 规则,不要它去检查警告,是不是问题就迎刃而解了。

  嘿嘿,没错,你猜对了,还真是这样。

  但是不用我们去做了,eslint-config-prettier (opens new window) 已经做了,看名字大概也能猜到,config位于eslintprettier中间,即用于平衡eslintprettier之间的配置。

npm i eslint-config-prettier -D

  但是是用于平衡哪些配置呢,官方文档给出了答案,即关闭了eslint中所有不必要的或者可能与prettier冲突的那些规则,实际也就是代码风格规则。

  ;.eslintrc.js中添加prettier表示启用eslint-config-prettier,注意一定要在最后,确保覆盖之前的同类规则,否则可能不生效。

// .eslintrc.js
module.exports = {
  ...
  extends: [
    'plugin:vue/recommended',
    'prettier'
  ]
}

  保存时效果,也能看到eslint相关的代码质量规则未被禁用。

# eslint-plugin-prettier

  还记得最开始时,<template>中标签缩进错误时,会高亮黄色警告下划波浪线吗。

  如果还是想包含此功能,可以安装一个推荐的可选插件 eslint-plugin-prettier (opens new window)

  由于插件eslint-config-prettier的原因,代码格式问题已经交给prettier负责,而eslint代码格式相关的检测规则也被禁用了,因此即使代码中出现了格式问题,eslint是不会报错的。

  而eslint-plugin-prettier做了一件什么事呢?它将prettier格式问题的相关规则,转换成了对应的eslint规则,并注入到了eslint中,由此代码中的格式问题,eslint也会报错。

npm i eslint-plugin-prettier -D

  修改.eslintrc.js,其中plugins表示将prettier注册为插件,prettier/pretiier表示将prettier插件提供的规则注入eslint,并且使其在eslint中运行prettier

module.exports = {
  root: true,
  extends: ['plugin:vue/recommended', 'prettier'],
  plugins: ['prettier'],
  rules: {
    quotes: ['error', 'single'],
    'prettier/prettier': 'error',
  },
}

  有两个不适用的规则。

const foo = () => { return 0 }    // OK

const foo = () => 0    // ERROR
foo(arg => {})    // OK

foo(function(arg) {})    // ERROR

  很明显都不是很合理,arrow-body-style规则代码也将不是很优雅,修改.eslintrc.js

// .eslintrc.js
module.exports = {
  root: true,
  extends: ['plugin:vue/recommended', 'prettier'],
  plugins: ['prettier'],
  rules: {
    quotes: ['error', 'single'],
    'prettier/prettier': 'error',
    'arrow-body-style': 'off',
    'prefer-arrow-callback': 'off',
  },
}

  而以上配置可以更为便捷地合并为以下,了解更多可参考 官方文档 (opens new window)

// .eslintrc.js
module.exports = {
  root: true,
  extends: ['plugin:vue/recommended', 'plugin:prettier/recommended'],
  rules: {
    quotes: ['error', 'single'],
  },
}

  以上配置完成后,不出意外,你的App.vueHelloWord.vue等都将会有很多错误提示。

  是由于行尾换行符造成的,不要紧,.prettierrc.js添加如下规则,更多 详细参考 (opens new window)

// .prettierrc.js
module.exports = {
  ...
  endOfLine: 'crlf'
}

  至此格式化相关的步骤就都完成了。

# 区别差异

  ;eslint-config-prettier不仅提供了prettier的格式化规则,同时也禁用了eslint中所有不必要的或者可能与prettier冲突的那些规则。

  代码质量检测均由eslint负责,没有代码格式检测。代码质量修复依赖于eslintautofix,代码格式的修复依赖于prettier

  所以仅安装eslint-config-prettier时,eslintautofixprettier的保存格式化两者一定要同时开启,而且根据上文我们也知道eslintautofix是介于prettier的格式化之前运行的。

// .vscode/settings.json
{
  ...
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true
  },
  "editor.formatOnSave": true,
}

  仅开启eslintautofix,能明显看到仅仅修复了代码质量,代码格式并未修复。

  仅开启prettier的格式化,代码质量未被修复,代码格式均被修复。

  ;eslint-plugin-prettier则是将prettier格式问题的相关规则,转换成了对应的eslint规则,并注入到了eslint中。

  代码质量检测均由eslint负责,注意代码质量的规则由eslinteslint-plugin-vue两者提供,代码格式检测也是由eslint负责,代码格式的规则是由prettier提供,且依赖于eslint-plugin-prettier转换并注入到eslint中。

  ;eslint-plugin-prettier还做了另外一件事,即在eslintautofix后,紧接着继续运行prettier,因此仅开启eslintautofix就能完成质量和格式的修复。

  但是要明确的是,代码质量修复还是依赖于eslintautofix,代码格式的修复还是依赖于prettier,只是eslint-plugin-prettierautofix后帮你自动运行了prettier

  仅开启eslintautofix,代码质量和格式均高亮,且保存时都被修复。

  仅开启prettier的格式化,代码质量和格式均高亮,但是只修复了格式问题。

# 小结

  初始脚手架代码都是文本字体,引入Vetur高亮代码。

  ;Vetur会查找项目中jsconfig.json等文件并抛出警告,新建jsconfig.json

// jsconfig.json
{
  "compilerOptions": {
    "baseUrl": "./",
    "paths": {
      "@/*": [
        "src/*"
      ]
    }
  },
  "exclude": [
    "node_modules",
    "dist"
  ]
}

  ;vscode引入ESLint插件,安装eslint错误检查包和格式化依赖包,其中eslinteslint-plugin-vue用于错误检查,prettier用于格式化代码,eslint-config-prettier用于解决eslintprettier之间的冲突,可选插件eslint-plugin-prettier用于注入prettier格式化规则到eslint

npm i eslint eslint-plugin-vue prettier eslint-config-prettier eslint-plugin-prettier -D

  新建.eslintrc.js,启用eslint-plugin-vuevue规则集,同时启用eslint-config-prettier,并且启用eslint-config-prettier注入规则。

// .eslintrc.js
module.exports = {
  root: true,
  extends: ['plugin:vue/recommended', 'plugin:prettier/recommended'],
  rules: {
    quotes: ['error', 'single'],
  },
}

  新建.prettierrc.js,统一部分格式化规则和换行符等。

// .prettierrc.js
module.exports = {
  semi: false,
  printWidth: 110,
  arrowParens: 'avoid',
  singleQuote: true,
  endOfLine: 'crlf'
}

  新建settings.json,保存时自动运行eslintautofixprettier格式化。

// .vscode/settings.json
{
  "editor.tabSize": 2,
  "editor.lineHeight": 24,
  "vetur.validation.template": false,
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true
  },
  "editor.formatOnSave": true,
}

  以上插件和依赖的作用。

# Git hook

  引入诸多插件都是为了在开发阶段规范或者修复代码,但是都是以vscode编辑器为前提的,倘若其它成员使用的是webstorm等其它编辑器,那么之前做的事情就都白费了。

  还好远端是利用git在管理代码,大家提交代码的方式是一致的,编辑器不能做到完全规范代码,但是可以在提交时统一代码。

  来了解一下git hookgit hookgit钩子,git在特定事件发生时会触发对应的脚本(类似于vue的生命周期),git init初始化后的仓库中,.git/hooks目录下默认包括很多示例脚本(都是以.sample结尾),删除掉.sample后缀可启用。

  常用的钩子包括pre-commitcommit-msg等。

  • pre-commit:暂存中的文件被提交前触发,或者说在你git commit ...之前触发。若此钩子以非零值退出,git将放弃此次提交(可利用git commit --no-verify跳过),一般可利用此钩子来检查代码风格等
  • commit-msg:输入提交说明后且于pre-commit后触发。若此钩子以非零值退出,git也将放弃提交,一般用于校验提交说明是否符合规范

# Husky(v4) 与 lint-staged 规范代码

  思路应该是很清晰了,即在代码提交时,触发对应的钩子来检测并规范代码,因此先初始化一个git仓库。

git init

  然后再来了解一下 husky (opens new window)husky是一个为git客户端添加hook的工具,安装v4版本(v4.3.8及之前的版本)后,husky默认会在.git/hooks目录下生成所有类型的git hook。然后在git工作的每个阶段都会调用husky所生成的脚本,在脚本中husky会检查用户是否配置有此钩子,如果有就运行用户配置的命令,没有就继续往后执行。

npm i husky@4.3.8 -D

  安装完成后,目录.git/hooks下生成了很多的hook

  来测试一下husky,新建.huskyrc.json,其中pre-commit钩子触发将运行echo hello husky

// .huskyrc.json
{
  "hooks": {
    "pre-commit": "echo hello husky"
  }
}

  修改代码并提交。

  已经可以在提交时触发钩子了,现在来考虑一个问题,是在提交前规范目录中所有代码,还是仅仅规范暂存中的代码呢。显然只规范暂存中的代码就可以了,不仅避免检查整个项目,提高运行效率,也避免了修改到其它文件。

  而插件 lint-staged (opens new window) 就是对暂存中的文件执行检查的。

npm i lint-staged -D

  新建.lintstagedrc.json,注意源码一般位于src目录下,因此仅对src目录下的jsvue文件执行eslint --fix即可,格式修复完成后再执行git add暂存。

// .lintstagedrc.json
{
  "src/**/*.{js,vue}": [
    "eslint --fix",
    "git add"
  ]
}

  修改.huskyrc.json,即pre-commit钩子触发时,将运行.lintstagedrc.json中的命令。

// .huskyrc.json
{
  "hooks": {
    "pre-commit": "lint-staged"
  }
}

  关闭eslintautofixprettier的格式化,打乱App.vue中代码样式,暂存并提交,可以看到在pre-commitlint-stagedApp.vue进行了检测和修复。

# Commitlint 规范提交说明

  安装 commitlint/cli (opens new window) 和常规配置。

npm i @commitlint/cli @commitlint/config-conventional -D

  新增commitlint.config.js引入提交规范集。

// commitlint.config.js
module.exports = {
  extends: ['@commitlint/config-conventional']
}

  修改.huskyrc.json,即commit-msg钩子触发时,将运行对应的命令。

// .huskyrc.json
{
  "hooks": {
    "pre-commit": "lint-staged",
    "commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
  }
}

  再次暂存并提交,可以看到commit-msg钩子触发时commitlint对提交说明进行了验证。

# Husky v4 迁移 v7

  先来说说husky为什么由v4破坏性地更新到v7了,v4版本的husky会生成所有类型的git hook,其好处就是无论用户设置任何类型的git hookhusky都能保证其正常运行,但是坏处也很明显,即用户不设置任何git hookhusky也向git添加了所有类型的git hook

  ;v4版本缺陷的根本原因在于,任何一个完整的git hook功能,一是要在.git/hooks添加相应的hook,二是要在根目录添加.huskyrc.json文件或package.json中配置此hook要执行的命令,但是作者没有很好的办法来同步它们。

  还好git 2.9版本引入了core.hooksPath,此属性可指定git hook所在目录。husky启用git钩子后,将会把git hook的目录指定为.husky,此方式好处就在于,需要什么hook,就在.husky文件夹添加什么hook,不需要什么都不用添加,更多 详细参考 (opens new window)

  现在由v4版本迁移至v7版本,请卸载目录下husky(v4)

npm un husky

  然后安装最新版本的husky(目前v7.0.4)。

npm i husky -D

  启用git钩子。

npx husky install

  启用后将在根目录生成.husky文件夹,其中默认包括_文件夹、.gitignorehusky.sh

  同时.git/config文件中将添加如下属性。

// .git/config
[core]
  ...
  hooksPath = .husky

  ;.husky目录下新建pre-commit文件,其中--no-install表示强制npx使用本地模块,不下载远程模块,但是本地模块不存在时将会报错。

// .husky/pre-commit
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

echo 'husky > pre-commit'
npx --no-install lint-staged

  验证提交说明的迁移也是一样,在.husky下新建commit-msg钩子。

// .husky/commit-msg
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

echo 'husky > commit-msg'
npx --no-install commitlint --edit $1

  最后根目录下的.huskyrc.json也可以删除了,因为v7版本已经不依赖这一层映射关系了,.husky目录内hook将直接运行命令,这也就是v7版本更新后的优点,缺点也很明显,无端增加了用户的学习成本。

# 小结

# Husky v4 版本

  由于是利用git来管理代码,因此先要保证项目已经初始化为git仓库。

git init

  安装git hook工具和检查工具、提交说明检查工具和检查规则集,其中husky用于为git添加hook工具,lint-staged用于检查暂存中的文件,commitlint用于检查提交说明,config-conventional用于提供检查规则集。

npm i husky@4.3.8 lint-staged @commitlint/cli @commitlint/config-conventional -D

  新建.lintstagedrc.json,用于修复暂存中的文件。

// .lintstagedrc.json
{
  "src/**/*.{js,vue}": [
    "eslint --fix",
    "git add"
  ]
}

  新建commitlint.config.js,启用config-conventional规则集。

// commitlint.config.js
module.exports = {
  extends: ['@commitlint/config-conventional']
}

  新建.huskyrc.jsongit钩子触发时执行相应的命令。

// .huskyrc.json
{
  "hooks": {
    "pre-commit": "lint-staged",
    "commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
  }
}

# Husky v7 版本

  ;v4迁移v7请卸载husky(v4)版本。

npm un husky

  安装最新版本husky(目前v7.0.4)。

npm i husky -D

  启用git钩子。

npx husky intall

  新建pre-commitcommit-msg钩子。

// .husky/pre-commit
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

echo 'husky > pre-commit'
npx --no-install lint-staged

// .husky/commit-msg
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

echo 'husky > commit-msg'
npx --no-install commitlint --edit $1

  再删除.huskyrc.json文件即可。

# 插件

  以上插件的作用。

# 常见问题

# 如何关闭或跳过 eslint 校验规则?

  有些项目并不能很好地适用eslint的规则集,例如 vue/recommended (opens new window) 规则集中 vue/no-v-html (opens new window) 禁用了v-html指令,但是有时又不得已会使用v-html

  第一种方式可在.eslintrc.js中关闭此规则。

// .eslintrc.js
module.exports = {
  ...
  rules: {
    ...
    'vue/no-v-html': 'off',
  },
}

告警级别分为三种,0/off表示忽略问题,1/warn表示警告,2/error表示报错

  第二种方式是利用 vue/comment-directive (opens new window) 规则,即通过注释来跳过某一行或多行的校验。

  此规则支持的注释包括。

  • eslint-disable:关闭校验
  • eslint-enable:开启校验,配合eslint-disabled可关闭多行校验
  • eslint-disable-line:关闭当前行校验
  • eslint-disable-next-line:关闭下一行校验

  关闭多行校验,其中67行的v-html校验已跳过。

  关闭当前行的校验,其中32行中的语句末尾分号校验已跳过。

  关闭下一行校验。

  注意以上注释会关闭掉所有eslint校验规则,建议在注释后添加禁用的规则名称,更多 详细参考 (opens new window)

# 旧项目如何接入格式化工具?

  旧项目通常情况下源文件格式都会存在问题,但是不可能每个文件都去Ctrl + S手动修复格式,可在package.json中添加命令来修复src内源文件。

  但是强烈不推荐你这么做,因为格式化可能会造成潜在的问题。如果源文件较少,且能够保证做全量测试,那么你可以这样做。但是源文件较多,建议只格式化你修改的文件,其余不相关的文件还是不要动。

// package.json
{
  ...
  "scripts": {
    ...
    "eslint:fix": "eslint src/**/*.js src/**/*.vue --fix"
  }
}

注意eslint:fix仅能修复简单的错误,其它例如组件props默认值的情况,还是需要你手动修复

# 无法格式化的文件如何修复?

  部分文件保存时无法格式化,频繁闪烁。

  此情况最好是对某个文件执行eslintfix功能,如果文件较多,建议执行npm run eslint:fix命令。

npx eslint src/main.js --fix

# 提交时如何跳过 lint 阶段?

  如果你觉得在执行git commit -m ...提交时非常耗时,你可以执行以下命令来跳过lint-stagedcommitlint两个阶段。

  但是还是建议不要这样做,因为你无法保证提交到远端的代码是非常规范的。

git commit -m 'xxx' --no-verify

# lint-staged 在 pre-commit 阶段报错

  在node版本较低的情况下,且安装了lint-stagedv12版本(目前v12.3.4)。

  ;node版本为v12.14.1时,提交时抛出以下错误。

  ;node版本为v14.10.1时,提交时抛出以下错误。

  ;官方 (opens new window)明确了所支持的node版本。

  两种解决方式,方式一可升级node版本,方式二则可安装lint-stagedv11.2.6及以下版本,推荐方式二。

# 维护配置文件到 package.json

  诸如.eslintrc.js.prettierrc.js等配置文件,都维护在开发目录下,显得多而复杂,另外后期此类文件都是不用修改的,还有另外一种配置方式,就是维护至package.json下。

  ;eslint

// .eslintrc.js
module.exports = {
  root: true,
  extends: ['plugin:vue/recommended', 'plugin:prettier/recommended'],
  rules: {
    quotes: ['error', 'single'],
  },
}

// package.json
{
  ...
  "eslintConfig": {
    "root": true,
    "extends": [
      "plugin:vue/recommended",
      "plugin:prettier/recommended"
    ],
    "rules": {
      "quotes": [
        "error",
        "single"
      ]
    }
  }
}

  ;prettier

// .prettierrc.js
module.exports = {
  semi: false,
  printWidth: 110,
  singleQuote: true,
  endOfLine: 'crlf',
  arrowParens: 'avoid',
}

// package.json
{
  ...
  "prettier": {
    "semi": false,
    "printWidth": 110,
    "singleQuote": true,
    "endOfLine": "crlf",
    "arrowParens": "avoid"
  }
}

  ;husky

// .huskyrc.json
{
  "hooks": {
    "pre-commit": "lint-staged",
    "commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
  }
}

// package.json
{
  ...
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged",
      "commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
    }
  }
}

  ;lint-staged

// .lintstagedrc.json
{
  "src/**/*.{js,vue}": [
    "eslint --fix",
    "git add"
  ]
}

// package.json
{
  ...
  "lint-staged": {
    "src/**/*.{js,vue}": [
      "eslint --fix",
      "git add"
    ]
  }
}

  ;commitlint

// commitlint.config.js
module.exports = {
  extends: ['@commitlint/config-conventional'],
}

// package.json
{
  ...
  "commitlint": {
    "extends": [
      "@commitlint/config-conventional"
    ]
  }
}

  ;babel

// babel.config.js
module.exports = {
  presets: ['@vue/cli-plugin-babel/preset'],
}

// package.json
{
  ...
  "babel": {
    "presets": [
      "@vue/cli-plugin-babel/preset"
    ]
  }
}

  ;browserslist

// .browserslistrc
> 1%
last 2 versions
not dead

// package.json
{
  ...
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not dead"
  ]
}

# 如何配置 vue 代码片段?

  ;vetur提供了代码片段用来提高开发效率。

# vscode 中 vue.json 文件

  ;vscode中键入Shift + Ctrl + P,输入snippets,选择配置用户代码片段。

  然后输入vue,选择vue.json

  删除掉所有注释,添加以下内容。

// vue.json
{
  "Vue Component": {
    "prefix": "cpt",
    "body": [
      "<template>",
      "  $1",
      "</template>",
      "",
      "<script>",
      "export default {",
      "",
      "}",
      "</script>",
      "",
      "<style>",
      "",
      "</style>"
    ],
    "description": "Vue 组件模板"
  }
}

  ;vue单文件内输入cpt,代码片段已生效。

  此方式配置在vscode中,在任何项目中都能生效,但是配置起来很麻烦,vue.json中要一行一行添加。

# 项目级模板

  项目根目录下.vscode目录结构如下。

├── .vscode
│   ├── settings.json
│   ├── vetur
│   │   ├── snippets
│   │   │   ├── template.vue

  可在snippets文件夹下添加template.vue文件。

// .vscode/vetur/snippets/template.vue
<template>
  <div>
    ${0}
  </div>
</template>

  此方式新增vue文件后,Reload重载后可生效,此方式相对vue.json文件,仅设置单文件即可,不需要一行一行添加。

# vscode 插件目录

  ;vscode键入Shift + Ctrl + P,输入extensions folder,选择打开拓展文件夹。

  打开octref.vetur-xx.xx.xx目录,进入server/dist/veturSnippets文件夹。

  添加自定义代码片段,也可复制default.vue然后修改。

// veturSnippets/page.vue
<template>
  ${0}
</template>

<script>
export default {
  name:''
}
</script>

<style>

</style>

  ;Reload重载后生效。

# 🎉 写在最后

🍻伙伴们,如果你已经看到了这里,觉得这篇文章有帮助到你的话不妨点赞👍或 Star (opens new window) ✨支持一下哦!

手动码字,如有错误,欢迎在评论区指正💬~

你的支持就是我更新的最大动力💪~

GitHub (opens new window) / Gitee (opens new window)GitHub Pages (opens new window)掘金 (opens new window)CSDN (opens new window) 同步更新,欢迎关注😉~

最后更新时间: 5/30/2022, 10:00:14 PM