Vue3+Vite项目,如何配置ESLint和Prettier实现代码规范化?

2,566 阅读11分钟

本文记录了最近在Vite+Vue3搭建的JavaScript项目中配置ESLintPrettier来检查代码风格和格式化代码的经验,下一篇记录为该项目添加husky+lint-staged来实现git提交时对代码进行检查和格式化。

项目介绍

该项目使用的包管理器是pnpm,使用其他工具的朋友自己修改文中pnpm相关的安装命令,

项目结构

  • public
  • src
  • index.html
  • .env
  • .gitignore
  • package.json
  • vite.config.js
  • uno.config.js
  • postcss.config.js

下面开始配置ESLint+Prettier来检查代码。

ESLint

ESLint入门

ESLint 是一个用于检测 ECMAScript/JavaScript 代码中的潜在问题和错误的工具,旨在使代码更一致并避免错误。它可以帮助开发者检测代码中的潜在问题,提高代码质量。

ESLint 是完全可插拔的。每一条规则都是一个插件,您可以在运行时添加更多。您还可以添加社区插件、配置和解析器来扩展 ESLint 的功能。

先决条件

要使用ESLint,必须安装Node.js^12.22.0、^14.17.0 或>=16.0.0)并构建SSL支持。(如果您使用的是官方的Node.js发行版,则始终内置SSL。)

安装 ESLint

方式一 (快速开始)

你可以使用以下命令安装和配置 ESLint :

pnpm create @eslint/config
# or
npm init @eslint/config

注意:运行以上命令是假设您已经有了一个package.json文件。如果没有,请确保事先运行pnpm initnpm inityarn init

按照提示步骤一步一步选择, 回车即可:

使用ESLint做什么? 我选择第三个, 检查语法, 发现问题, 强制代码风格

? How would you like to use ESLint? …
  To check syntax only
  To check syntax and find problems
❯ To check syntax, find problems, and enforce code style

项目模块类型? 我的项目使用的 import/export 选择第一个

? What type of modules does your project use? …
❯ JavaScript modules (import/export)
  CommonJS (require/exports)
  None of these

项目用的啥框架? 我用Vue.js

? Which framework does your project use? …
  React
❯ Vue.js
  None of these

项目中使用 TypeScript? 是的选择 Yes,我不是 TypeScript 选择 No

? Does your project use TypeScript? › No / Yes

代码运行环境? 我在项目中使用了 node 中的 process, 全选上

? Where does your code run? …  (Press <space> to select, <a> to toggle all, <i> to invert selection)
✔ Browser
✔ Node

选择代码风格? 我看了一下 popular style,里边没有 prettier ,想用 prettier 检查并格式化代码, 我建议使用回答问题来自定义代码风格

? How would you like to define a style for your project? …
  Use a popular style guide
❯ Answer questions about your style

ESLint 的配置文件格式? 我选择 JavaScript, 理由是可以在 js 文件中写条件判断语句来根据开发或生产环境开关 ESLint 规则

? What format do you want your config file to be in? …
❯ JavaScript
  YAML
  JSON

用啥缩进? 我选择Spaces , 默认它是4个空格,我们喜欢用2个空格, 后边生成的配置中我手动给改成2个空格

? What style of indentation do you use? …
  Tabs
❯ Spaces

字符串使用双引号还是单引号? 我们项目的小伙伴儿想用双引号, 选择Double

? What quotes do you use for strings? …
❯ Double
  Single

用哪种结束符? WindowsCRLF, UnixLF, 我选Unix

? What line endings do you use? …
❯ Unix
  Windows

用分号吗? 我们习惯使用分号;,选择 Yes ,不喜欢写分号的朋友,请选择 No

? Do you require semicolons? › No / Yes

检查到我没有安装ESLint, 是否马上安装? 安装 eslinteslint-plugin-vue, 选择 Yes

Local ESLint installation not found.
The config that you've selected requires the following dependencies:

eslint-plugin-vue@latest eslint@latest
? Would you like to install them now? › No / Yes

选择您使用的包管理器? 我是 pnpm

? Which package manager do you want to use? …
  npm
  yarn
❯ pnpm

回车确认, 开始安装...

✔ How would you like to use ESLint? · style
✔ What type of modules does your project use? · esm
✔ Which framework does your project use? · vue
✔ Does your project use TypeScript? · No / Yes
✔ Where does your code run? · browser, node
✔ How would you like to define a style for your project? · prompt
✔ What format do you want your config file to be in? · JavaScript
✔ What style of indentation do you use? · 4
✔ What quotes do you use for strings? · double
✔ What line endings do you use? · unix
✔ Do you require semicolons? · No / Yes
Local ESLint installation not found.
The config that you've selected requires the following dependencies:

eslint-plugin-vue@latest eslint@latest
✔ Would you like to install them now? · No / Yes
✔ Which package manager do you want to use? · pnpm
Installing eslint-plugin-vue@latest, eslint@latest
...
...
Done in 27.9s
Successfully created .eslintrc.js file in /code/vite-vue3-project

在项目的 package.json 文件中查看 devDependencies增加了 eslinteslint-plugin-vue 在项目根目录生成了.eslintrc.js 配置文件,打开文件找到 rulesindent 规则里边的 4 改成 2, 代码缩进就是 2 个空格了

在运行以上命令之后,您的目录中会有一个.eslintrc.{js,yml,json}文件。我选择使用的是JavaScript文件, 我的文件内容是这样的:

module.exports = {
  env: {
    browser: true,
    es2021: true,
    node: true,
  },
  extends: ["eslint:recommended", "plugin:vue/vue3-essential"],
  overrides: [],
  parserOptions: {
    ecmaVersion: "latest",
    sourceType: "module",
  },
  plugins: ["vue"],
  rules: {
    indent: ["error", 2],
    "linebreak-style": ["error", "unix"],
    quotes: ["error", "double"],
    semi: ["error", "always"],
  },
};

方式二 (手动设置)

您也可以在项目中手动设置ESLint

注意: 在开始之前,您必须已经有一个package.json文件。如果没有,请确保预先运行pnpm init, npm inityarn init来创建文件。

  1. 使用以下命令手动安装ESLintVue插件
pnpm add eslint@latest eslint-plugin-vue@latest -D
# or
npm install eslint@latest eslint-plugin-vue@latest -D
  1. 项目根目录中添加一个.eslintrc.js配置文件
# Create JavaScript configuration file
touch .eslintrc.js
  1. 在编辑器中打开.eslintrc.js配置文件进行自定义配置, Configure ESLint documentation:
// .eslintrc.js
module.exports = {
  env: {
    browser: true,
    es2021: true,
    node: true,
  },
  extends: ["eslint:recommended", "plugin:vue/vue3-essential"],
  overrides: [],
  parserOptions: {
    ecmaVersion: "latest",
    sourceType: "module",
  },
  plugins: ["vue"],
  rules: {
    indent: ["error", 2],
    "linebreak-style": ["error", "unix"],
    quotes: ["error", "double"],
    semi: ["error", "always"],
  },
};

以上步骤完成 ESLint 就安装上了

然后在项目根目录添加.eslintignore文件, 忽略不想让ESLint检查的文件夹和文件

touch .eslintignore

想忽略的全往里边列就行了, 举个例子 🌰:

*.sh
*.md
*.woff
*.ttf
*.yaml
.vscode
.idea
node_modules
dist
public
docs
.husky
.eslintrc.js

# Allowlist 'test.js' in the '.build' folder
# But do not allow anything else in the '.build' folder to be linted
!.build
.build/*
!.build/test.js

如需最新资讯请参考ESLint官网

VS Code安装ESLint

打开VS Code, 在Extensions中搜索ESLint, 找到之后点击install, 启用ESLint后会寻找到项目根目录下的.eslintrc.js配置文件, 根据里边的规则对项目代码进行检查

eslint-extension.png

打开一个文件看看效果, 我这里有一个变量声明了却没有读取使用它, ESLint已经在编辑器中报出了红色波浪线, 证明配置已经生效了

eslint-no-use-vars.png

Prettier

Prettier 入门

  • Prettier是什么?
    • 一个“有态度”的代码格式化工具
    • 支持大量编程语言
    • 已集成到大多数编辑器中
    • 几乎不需要设置参数
  • 为什么使用Prettier?
    • 按保存键时,代码就被格式化了
    • 代码评审时无须争论代码样式
    • 节省时间和精力

安装 Prettier

首先,在本地安装Prettier

pnpm add prettier@latest -D
# or
npm install prettier@latest -D

然后,创建一个空的配置文件,让编辑器和其他工具知道您正在使用Prettier

echo {} > .prettierrc.json

在配置文件中增加如下内容:

// .prettierrc.json 规则配置, 
// 后边将配置ESLint使用Prettier规则检查代码,以及怎么解决二者规则冲突的问题
{
  "useTabs": false,
  "tabWidth": 2,
  "jsxSingleQuote": false,
  "singleQuote": false,
  "endOfLine": "lf",
  "semi": true,
  "trailingComma": "es5"
}

(可选)接下来,创建一个.prettierignore文件,让Prettier CLI和编辑器知道不格式化哪些文件。下面是一个例子:

# Ignore artifacts:
build
coverage

我没有创建.prettierignore文件, 感觉有.eslintignore就够了

提示: 以.gitignore.eslintignore 为基础(如果你有)。

现在,使用Prettier格式化所有文件:

npx prettier --write

VS Code安装Prettier

从命令行进行格式化是一个很好的入门方法,但您可以通过键盘快捷键或在保存文件时自动从编辑器中运行 Prettier,从而充分利用它。当一行在编码时变得太长,以至于不适合你的屏幕时,只需按保存快捷键,就可以看到它神奇地被包裹成多行!或者,当你粘贴一些代码时,缩进会变得一团糟,让 Prettier 在不离开编辑器的情况下为你修复它。

打开VS Code, 在Extensions中搜索Prettier, 找到之后点击install,

prettier-formatter.png

在项目根目录添加.vscode文件夹并且新建一个settings.json文件

# Create directory
mkdir .vscode
# Create settings.json file
touch .vscode/settings.json

配置保存时使用Prettier对代码进行格式化, 在settings.json文件中增加如下内容:

// settings.json
{
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.formatOnSave": true,
  "editor.codeActionsOnSave": {
    "source.organizeImports": true,
    "source.fixAll": true
  }
}

设置编辑器参考资料

配合ESLint使用, 解决二者规则冲突

ESLint 的规则和 Prettier 的规则相冲突时,就会发现一个尴尬的问题,用Prettier来格式化代码,ESLint就会报错。

ESLint配合使用,请安装eslint-config-prettier,以使ESLintPrettier彼此配合得很好。它关闭所有不必要的或可能与Prettier冲突的ESLint规则。具体步骤如下:

# Install eslint-config-prettier
pnpm add eslint-config-prettier@latest -D
# or
npm install eslint-config-prettier@latest -D

修改.eslintrc.js

module.exports = {
  // 在 extends 尾部加入 prettier 即可
  "extends": [
    "eslint:recommended",
    "plugin:vue/vue3-essential",
    "prettier"
  ]
}

但是以上做法只是关闭了与Prettier相冲突的ESLint的规则, 而我们的目标是要让ESLint使用Prettier的规则去检查代码语法和风格等问题, 有办法, prettier官方有个插件eslint-plugin-prettier, 使用这个插件一步简单的配置就搞定:

prettier官方推荐配置方法

  1. 安装eslint-plugin-prettiereslint-config-prettier
pnpm add eslint-plugin-prettier@latest eslint-config-prettier@latest -D
# or
npm install eslint-plugin-prettier@latest eslint-config-prettier@latest -D
  1. 您需要在.eslintrc.js中添加plugin:prettier/recommended作为最后一个扩展:
module.exports = {
  // 在 extends 尾部增加 plugin:prettier/recommended
  extends: [
    "eslint:recommended",
    "plugin:vue/vue3-essential",
    "plugin:prettier/recommended"
  ],
}

plugin:prettier/recommended做了什么?额,它相当于以下配置:

module.exports = {
  extends: ["prettier"],
  plugins: ["prettier"],
  rules: {
    "prettier/prettier": "error",
    "arrow-body-style": "off",
    "prefer-arrow-callback": "off"
  }
}

eslint-plugin-prettier 参考资料

总之, 我们安装了eslint-config-prettiereslint-plugin-prettier后, 修改一下.eslintrc.js就可以让ESLintPrettier配合工作了

module.exports = {
  // 在 extends 尾部增加 plugin:prettier/recommended
  extends: [
    "eslint:recommended",
    "plugin:vue/vue3-essential",
    "plugin:prettier/recommended"
  ],
}

如需最新资讯请参考Prettier官网

解决SwitchCase缩进规则冲突

二者缩进规则不一样, 发生了冲突, 使用如下配置解决

module.exports = {
  // 修改 .eslintrc.js 文件
  rules: {
    indent: ["error", 2, { SwitchCase: 1 }],
  }
}

覆盖 vue/multi-word-component-names 规则

vue-multi-word-component-names.png

这个规则要求组件名称要多个单词构成, 而我们当初写的时候没有注意这一点, 现在改成本太大了, 只能把这个规则给覆盖掉

module.exports = {
  // .eslintrc.js 文件 overrides 部分
  overrides: [
    {
      files: ["src/**/*.vue"],
      rules: { "vue/multi-word-component-names": "off" },
    },
  ],
}

⚙️ This rule is included in all of "plugin:vue/vue3-essential", "plugin:vue/essential", "plugin:vue/vue3-strongly-recommended", "plugin:vue/strongly-recommended", "plugin:vue/vue3-recommended" and "plugin:vue/recommended".

参考资料 vue/multi-word-component-names

关掉一些规则

module.exports = {
  rules: {
    "no-unused-vars": "off",
    "no-console": "off",
    "no-debugger": "off",
  }
}

注意: 修改prettier配置后需要重新启动VS Code编辑器ESLint才能够正常工作

使用vite-plugin-eslint插件

使用这个插件可以在启动项目和打包代码时进行代码检查, 默认配置是如果检查有error类型的问题就启动或打包失败, warn类型的问题不影响启动和打包 开始配置:

安装vite-plugin-eslint

pnpm add vite-plugin-eslint@latest -D
# or
npm install vite-plugin-eslint@latest -D

vite 的配置文件中引入插件并配置到 plugins

import { loadEnv } from "vite";
import eslint from "vite-plugin-eslint";

export default ({ command, mode }) => {
  const env = loadEnv(mode, process.cwd());

  return defineConfig({
    plugins: [
      // 其它插件
      // ...
      eslint({ lintOnStart: true, cache: false }),
    ],
    // 在.env.production文件中配置VITE_DROP_CONSOLE = true,
    // 打包时自动去除console和debugger
    esbuild: {
      drop: env?.VITE_DROP_CONSOLE === "true" ? ["console", "debugger"] : [],
    },
  });
};

总结

ESLint配置文件

// .eslintrc.js

module.exports = {
  env: {
    browser: true,
    es2021: true,
    node: true,
  },
  extends: [
    "eslint:recommended",
    "plugin:vue/vue3-essential",
    "plugin:prettier/recommended",
  ],
  overrides: [
    {
      files: ["src/**/*.vue"],
      // 关闭组件名需要多个单词组成的规则
      rules: { "vue/multi-word-component-names": "off" },
    },
  ],
  parserOptions: {
    ecmaVersion: "latest",
    sourceType: "module",
  },
  plugins: ["vue"],
  rules: {
    // 解决ESLint和Prettier的switch/case缩进冲突
    indent: ["error", 2, { SwitchCase: 1 }],
    "no-unused-vars": "off",
    // vite打包时自动去除console和debugger,所以这里直接关掉检查
    "no-console": "off",
    "no-debugger": "off",
    // 允许catch空着
    "no-empty": ["error", { allowEmptyCatch: true }],
  },
};

Prettier配置文件

// .prettierrc.json

{
  "useTabs": false,
  "tabWidth": 2,
  "jsxSingleQuote": false,
  "singleQuote": false,
  "endOfLine": "lf",
  "semi": true,
  "trailingComma": "es5"
}

安装的依赖包

// package.json 中新增了如下依赖包
{
  "devDependencies": {
    "eslint": "^8.37.0",
    "eslint-config-prettier": "^8.8.0",
    "eslint-plugin-prettier": "^4.2.1",
    "eslint-plugin-vue": "^9.10.0",
    "prettier": "^2.8.7",

    // vite插件
    "vite-plugin-eslint": "^1.8.1"
  }
}

以上实现了ESLintPrettier配合规范代码风格, 并在vite启动项目或打包时输出error警告和warn错误, 下一篇Husky 和 Lint-staged 入门指南:Git 提交时自动进行代码校验和格式化将带来使用git提交代码时, 对代码进行检查并格式化