使用 ESLint、Prettier 和 Stylelint
前言
无论是多人协作还是个人项目,代码规范都非常重要。遵循代码规范不仅能减少基本语法错误,同时也保证了代码的可读性。而代码风格检查则是确保代码规范一致性的重要工具之一。
ESLint
ESLint 是什么?
ESLint 是一个用于检查和修复 JavaScript 代码中问题的代码检测工具。它能够帮助你发现并修复 JavaScript 代码中的问题。
ESLint 的作用包括:
- 语言语法检查:比如检查出字符串引号不匹配或函数调用括号缺失的问题
- 编码错误检查:比如检查出在代码中使用了一个不存在的变量,或者定义了一个变量却没有使用的问题
- 代码风格检查:比如检查出开发者没有使用分号的问题
安装 ESLint
使用 Vue Cli 安装
vue add eslint
# or
vue add @vue/cli-plugin-eslint
在输入完命令后,需要回答一些问题来根据你的项目需求和个人偏好进行配置。问题如下:
-
Pick an ESLint config(选择一个 ESLint 配置预设)
- Error prevention only(只检测错误)
- Airbnb(安彼迎)
- Standard(标准)
- Prettier(Prettier)
-
Pick additional lint features(选择什么时候进行代码检查)
- Lint on save(保存时检查)
- Lint and fix on commit(提交代码时检查)
在回答完问题后,vue-cli 会自动创建一个 ESLint 配置文件 .eslintrc.js
,并自动安装以下依赖:
eslint
:ESLint 核心模块eslint-plugin-vue
:ESLint 插件,该插件用于提供针对 Vue.js 代码的规则和检查prettier
:Prettier 核心模块eslint-plugin-prettier
:ESLint 插件,该插件用于将 Prettier 的格式化规则集成到 ESLint 中@vue/eslint-config-prettier
:ESLint 插件,它将禁用与 Prettier 格式化规则冲突的 ESLint 规则
ESLint 常用配置项
root
:定义根配置env
:定义运行环境rules
:定义检查规则plugins
:规则拓展extends
:集成配置方案parser
:语法解析器配置
下面是每个配置项的详细介绍:
root
默认情况下,ESLint 会在所有父级目录中寻找配置文件,一直到根目录。这样可以让所有项目都遵循同一套规则。你也可以将 .eslintrc.js
配置文件中的 root
设置为 true,这样 ESLint 一旦发现配置文件中有 root: true
,它就会停止在父级目录中寻找。
env
这个选项用于定义项目代码运行的环境,每个环境都包含一组特定的预定义全局变量:
browser
— 浏览器全局变量node
— Node.js 全局变量和 Node.js 作用域es6
— 启用除模块之外的所有 ES6 功能
...
比如项目要启用浏览器环境和 Node.js 环境:
module.exports = {
// ...
env: {
browser: true,
node: true,
},
};
rules
规则的值有两种格式:数组和字符串/数字。如果是数组,则可以设置两个内容:
第一项内容定义规则是关闭还是打开:
off
或0
:关闭规则,ESLint 不对该规则进行检查warn
或1
:将规则作为警告打开(不影响退出代码)。在开发环境下,终端会输出警告信息,但不会影响功能页面的展示error
或2
:将规则作为错误打开(触发时退出代码为 1)。在开发环境下,终端输出错误信息,浏览器页面也会显示错误信息而不是正常的功能展示
第二项内容是为该规则提供的参数。
如果规则的值是字符串/数字,则只定义规则的关闭或打开。
以下是禁用 JavaScript
中的 console
对象的方法调用的示例,对应的 ESLint 规则名称是 no-console
:
module.exports = {
// ...
rules: {
// 表示在代码中不允许直接调用 console.log/error/warn 等方法,否则将报错
"no-console": "error",
// 表示在代码中不推荐直接调用 console.log/error/warn 等方法,否则将发出警告
"no-console": 1,
// 表示在代码中可以直接调用 console.log/error/warn 等方法,因为规则被关闭了
"no-console": "off",
// 表示在代码中不允许直接调用 console.log 方法,但允许使用 warn 和 error 方法,否则将报错
"no-console": ["error", { allow: ["warn", "error"] }],
},
};
plugins
插件(plugins)是用于扩展 ESLint 内置规则的。ESLint 主要用于对 JavaScript 代码进行语法检查,无法直接检查其他格式的文件内容。如果需要对这些文件内容进行检查,就需要使用插件配置(plugins)来扩展 ESLint 规则。例如:
eslint-plugin-vue
:可以对 Vue 文件的<template>
和<script>
内容进行检查,具体使用方法请参考文档
module.exports = {
// ...
plugins: ["eslint-plugin-vue"],
rules: {
// ... eslint-plugin-vue 的 lint 规则
},
};
需要注意的是,添加的插件(plugins)中的规则默认是未启用的,我们需要在规则(rules)中选择要使用的规则。也就是说,插件(plugins)需要与规则(rules)结合使用。
extends
可以看到,手动配置规则(rules)的工作量很大。这时 extends 发挥了作用。extends 可以理解为一个预设的插件(plugins)和规则(rules)的集合。
举例来说:eslint-plugin-vue
提供了一个名为 plugin:vue/recommended
的规则包。在 extends 中引用这个规则包相当于启用了一系列的规则:
module.exports = {
// ...
extends: ["plugin:vue/recommended"],
rules: {
// 此处无需手动一项一项配置 lint 规则,因为插件已经根据 recommended 选项自动设置了预设的规则包
},
};
parser
ESLint 默认使用 Espree 作为其解析器,它仅支持 ES5 语法,不支持实验性语法和非标准语法(如 TypeScript 类型)。但是我们可以配置解析器(parser)以使 ESLint 支持其他语法。例如:
babel-eslint
:使 ESLint 兼容 ES6 语法
module.exports = {
// ...
parserOptions: {
parser: "babel-eslint",
},
};
ESLint 常用命令
检查文件
npx eslint [文件或目录路径]
修复文件
npx eslint --fix [文件或目录路径]
指定检查的文件扩展名
默认情况下,ESLint 会检查 .js
文件,若想检查其他扩展名的文件,可以使用 --ext
命令自定义要检查的文件类型。
# 仅检查 Vue 文件
npx eslint --ext .vue [文件或目录路径]
# 同时检查 JavaScript 和 Vue 文件
npx eslint --ext .js --ext .vue [文件或目录路径]
# or
npx eslint --ext .js,.vue [文件或目录路径]
Prettier
Prettier 是什么?
Prettier 是一款代码格式化工具,用于检查代码中的格式问题。
Prettier 和 ESLint 的区别?
在代码格式化方面,Prettier 确实与 ESLint 有一些重叠,但它们的重点不同。ESLint 主要用于检查代码质量并给出提示,它在格式化方面的功能有限;而 Prettier 在代码格式化方面更加全面,因此通常将它们结合使用。
安装 Prettier
在使用 vue-cli 安装 ESLint 时,Prettier 已经被安装在项目中了
Prettier 常用配置项
在项目的根目录下,创建一个名为 .prettierrc.js
的文件,用于配置 Prettier
// .prettierrc.js
module.exports = {
printWidth: 80, // 一行的字符数,如果超过会进行换行,默认为 80
tabWidth: 4, // 一个 tab 代表几个空格数,默认为 4
useTabs: true, // 是否使用 tab 进行缩进,默认为 false,表示用空格进行缩进
singleQuote: false, // 字符串是否使用单引号,默认为 true,使用单引号
semi: true, // 行尾是否使用分号,默认为 true
trailingComma: "es5", // 是否使用尾逗号,有三个可选值"<none|es5|all>"
};
Prettier 常用命令
格式化文件
npx prettier --write [文件或目录路径]
检查文件格式
npx prettier --check [文件或目录路径]
StyleLint
StyleLint 是什么?
StyleLint 是一个用于检查和维护 CSS、SCSS 等样式表的工具。它的主要功能是确保代码风格的一致性,并检查样式表是否符合预设的规范。
安装 StyleLint
npm install stylelint --save-dev
npm install stylelint-config-standard --save-dev
npm install stylelint-config-prettier --save-dev
npm install stylelint-scss --save-dev
npm install stylelint-order --save-dev
以下是与 StyleLint 相关的插件和配置说明:
stylelint
:StyleLint 的核心模块stylelint-config-standard
:StyleLint 官方推荐的配置规则stylelint-config-prettier
:该配置用于解决 StyleLint 和 Prettier 之间的规则冲突问题。将其放在extends
数组的最后位置,可以确保覆盖 Prettier 的配置stylelint-scss
:该插件是 StyleLint 的 SCSS 扩展,增加了对 SCSS 语法的支持,允许检查和验证 SCSS 文件stylelint-order
:该插件强制按照指定的顺序编写 CSS 属性,可以避免属性顺序的混乱和不一致
StyleLint 配置
在项目根目录下创建名为 .stylelintrc.js
的文件来进行 StyleLint 的配置。更详细的使用可查看官方文档。
StyleLint 常用命令
检查文件
npx stylelint [文件或目录路径]
修复文件
npx stylelint --fix [文件或目录路径]
最终配置
ESLint
// .eslintrc.js
module.exports = {
root: true,
env: {
es6: true,
},
extends: [
"eslint:recommended", // in a configuration file enables rules that report common problems, which have a check mark √ below. https://cn.eslint.org/docs/rules
"plugin:vue/recommended", // eslint-plugin-vue/Use this if you are using Vue.js 2.x. https://github.com/vuejs/eslint-config-vue
"plugin:prettier/recommended", // eslint-plugin-prettier/eslint-config-prettier/add prettier-eslint plugin which will uses the `.prettierrc.js` config
],
parserOptions: {
parser: "babel-eslint", // 一个对Babel解析器的包装,使其能够与Eslint兼容
},
rules: {
"vue/no-v-html": "off",
"vue/html-indent": "off",
"vue/html-self-closing": "off",
"vue/max-attributes-per-line": "off",
"vue/multi-word-component-names": "off",
"vue/no-mutating-props": "off",
"vue/no-unused-vars": "off",
"no-unused-vars": "off",
"prettier/prettier": "warn",
"vue/no-unused-components": "warn",
"vue/singleline-html-element-content-newline": "off",
},
};
Prettier
// .prettierrc.js
module.exports = {
useTabs: true,
tabWidth: 4,
arrowParens: "avoid",
htmlWhitespaceSensitivity: "ignore",
trailingComma: "es5",
};
StyleLint
// .stylelintrc.js
module.exports = {
extends: ["stylelint-config-standard", "stylelint-config-prettier"],
plugins: ["stylelint-scss", "stylelint-order"],
rules: {
"order/properties-alphabetical-order": null,
"order/properties-order": [
[
{
properties: ["position", "top", "bottom", "right", "left", "z-index"],
},
{
properties: [
"display",
"align-items",
"justify-content",
"visibility",
"float",
"clear",
"overflow",
"overflow-x",
"overflow-y",
"zoom",
],
},
{
properties: [
"list-style",
"list-style-position",
"list-style-type",
"list-style-image",
],
},
{
properties: [
"margin",
"margin-top",
"margin-right",
"margin-bogttom",
"margin-left",
"box-sizing",
"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",
"border-top-left-radius",
"border-top-right-radius",
"border-bottom-right-radius",
"border-bottom-left-radius",
"border-image",
"border-image-source",
"border-image-slice",
"border-image-width",
"border-image-outset",
"border-image-repeat",
"padding",
"padding-top",
"padding-right",
"padding-bottom",
"padding-left",
"width",
"min-width",
"max-width",
"height",
"min-height",
"max-height",
],
},
{
properties: [
"font",
"font-family",
"font-size",
"font-weight",
"font-style",
"font-stretch",
"line-height",
"text-align",
"vertical-align",
"white-space",
"text-decoration",
"text-indent",
"text-justify",
"letter-spacing",
"word-spacing",
"text-transform",
"text-overflow",
"word-wrap",
"word-break",
],
},
{
properties: [
"color",
"background",
"background-color",
"background-image",
"background-repeat",
"background-attachment",
"background-position",
"background-position-x",
"background-position-y",
"background-clip",
"background-origin",
"background-size",
],
},
{
properties: [
"transition",
"transition-delay",
"transition-timing-function",
"transition-duration",
"transition-property",
"transform",
"transform-origin",
"animation",
"animation-name",
"animation-duration",
"animation-play-state",
"animation-timing-function",
"animation-delay",
"animation-iteration-count",
"animation-direction",
],
},
{
properties: [
"outline",
"outline-width",
"outline-style",
"outline-color",
"outline-offset",
"opacity",
"filter",
"box-shadow",
"text-shadow",
],
},
{
properties: [
"content",
"resize",
"cursor",
"user-select",
"pointer-events",
],
},
],
{
emptyLineBeforeUnspecified: "never",
},
],
"color-hex-case": "lower",
"color-hex-length": "short",
"color-named": "never",
"font-weight-notation": "numeric",
"number-leading-zero": "always",
"string-quotes": "double",
"value-no-vendor-prefix": [
true,
{
ignoreValues: [
"placeholder",
"input-placeholder",
"text-fill-color",
"line-clamp",
"box-orient",
"box",
],
},
],
"value-list-comma-newline-before": "never-multi-line",
"value-list-comma-newline-after": "always-multi-line",
"value-list-comma-space-before": "never",
"value-list-comma-space-after": "always",
"declaration-colon-newline-after": null,
"declaration-bang-space-before": "always",
"declaration-bang-space-after": "never",
"declaration-colon-space-before": "never",
"declaration-colon-space-after": "always",
"declaration-empty-line-before": null,
"declaration-block-semicolon-newline-before": "never-multi-line",
"at-rule-no-unknown": null,
"block-closing-brace-empty-line-before": "never", // fix:@keyframes Expected empty line before closing brace
"block-closing-brace-newline-after": "always",
"block-closing-brace-newline-before": "always",
"block-opening-brace-newline-after": "always",
"block-opening-brace-space-before": "always",
"rule-empty-line-before": [
"always",
{
ignore: ["after-comment", "first-nested"],
},
],
"block-no-empty": null,
"no-empty-source": null,
"no-descending-specificity": null,
"selector-pseudo-class-no-unknown": null,
"property-no-unknown": null,
"font-family-no-missing-generic-family-keyword": null,
"font-family-name-quotes": null,
"selector-pseudo-element-no-unknown": null,
},
};
拓展
与 VSCode 集成
安装 ESLint 插件
安装 Prettier 插件
安装 Stylelint 插件
在 VSCode 中安装 ESLint、Prettier 和 Stylelint 插件可以实现在编写代码时自动进行代码检查和格式化。
推荐设置如下:
{
// 设置全部语言在保存时自动格式化
"editor.formatOnSave": true,
// 保存时使用 StyleLint 修复可修复错误
"stylelint.autoFix": true,
// 设置全部语言的默认格式化程序为prettier
"editor.defaultFormatter": "esbenp.prettier-vscode"
}