Skip to content

Vue 整合 ESLint、Prettier

项目初始化

shell
pnpm create vite

初始化 ESLint

1、作用: ESLint 是一个用于检测 JavaScript 代码问题的工具,帮我们发现并修复 JavaScript 代码中的问题。

2、安装:

shell
pnpm create @eslint/config
shell
 How would you like to use ESLint? · problems
 What type of modules does your project use? · esm
 Which framework does your project use? · vue
 Does your project use TypeScript? · javascript
 Where does your code run? · browser
The config that you've selected requires the following dependencies:

eslint, globals, @eslint/js, eslint-plugin-vue
√ Would you like to install them now? · No / Yes
√ Which package manager do you want to use? · pnpm

此时根目录会生成 eslint.config.js 文件, 内容如下:

javascript
import globals from "globals";
import pluginJs from "@eslint/js";
import pluginVue from "eslint-plugin-vue";


export default [
    {languageOptions: {globals: globals.browser}},
    pluginJs.configs.recommended,
    ...pluginVue.configs["flat/essential"],
];

注意:此时我们安装的是Eslint的版本为:9.0.0,这是 Eslint 更新的变动比较大的版本,具体跟新内容请查阅官网。

3、使用 eslint 进行格式化

先修改 app.vue

vue

<script setup>
  const number = 10  // 没有使用的变量
</script>

<template>
  <div>hello ESLint !</div>
</template>

<style scoped>

</style>

然后使用指令进行格式化

shell
npx eslint

然后可以看到错误

shell
D:\zhengxin\vite-project\src\App.vue
  4:7  error  'number' is assigned a value but never used  no-unused-vars

 1 problem (1 error, 0 warnings)

3、配置:

根目录修改文件 eslint.config.js 配置如下:

javascript
import globals from "globals";
import pluginJs from "@eslint/js";
import pluginVue from "eslint-plugin-vue";


export default [
    // eslint 默认推荐规则
    pluginJs.configs.recommended,
    // vue3 基础推荐规则
    ...pluginVue.configs["flat/essential"],
    {languageOptions: {globals: globals.browser}},

    {                                   
        rules: {                        
            "no-unused-vars": "warn",   // 没有使用变为警告
            "no-undef": "warn"
        }                               
    }                                   
];
shell
$ npx eslint .

D:\code_demo\untitled3\vite-project\src\App.vue
  2:7  warning  'number' is assigned a value but never used  no-unused-vars

 1 problem (0 errors, 1 warning)

添加 lint 命令

json5
{
  "scripts": {
    // eslint . 为指定lint当前项目中的文件
    // --ext 为指定lint哪些后缀的文件
    // --fix 开启自动修复
    "lint:eslint": "eslint --fix"
  }
}

Prettier

1、安装 Prettier

shell
pnpm install --save-dev --save-exact prettier # (--save-exact 准确安装版本)

2、使用 prettier 测试

shell
$ npx prettier src/App.vue 
<script setup>
const number = 10; // 没有使用的变量
</script>

<template>
  <div>hello ESLint !</div>
</template>

<style scoped></style>

可以发现在第三行后面加了分号,样式之间的空格也被消除了。因为只是使用命令行进行测试,所以并没有修改原始文件。

3、手动添加配置

新建 Prettier 规则文件 prettier.config.js 内容如下

javascript
export default {
    singleQuote: false, // 不使用单引号
};

修改 App.vue 文件如下

vue

<script setup>
  const number = 10  // 没有使用的变量
  const msg = 'hello world !'
</script>

<template>
  <div>hello ESLint !</div>
</template>

<style scoped>

</style>

然后使用命令行测试,可以发现变化如下

shell
$ npx prettier src/App.vue 
<script setup>
const number = 10  // 没有使用的变量
const number = 10; // 没有使用的变量
const msg = 'hello world !'
const msg = "hello world !"; 
</script>

<template>
  <div>hello ESLint !</div>
</template>

<style scoped></style>

4、编辑器格式化使用 prettier 规则

vscode 与 webstorm 都可以使用 prettier 的规则格式化代码。

VS Code 需要在设置的 settings.json 中,添加下面两行 json 代码

json5
{
  // 开启保存自动格式化
  "editor.formatOnSave": true,
  // 设置 prettier 为默认格式化工具
  "editor.defaultFormatter": "esbenp.prettier-vscode"
}

webstorm 则是在 File -> Settings -> Languages & Frameworks -> JavaScript -> Prettier 中进行设置

5、完善 prettier.config.js 规则

javascript
export default {
    tabWidth: 2, // 缩进
    useTabs: true, // 缩进方式
    semi: false, // 语句结尾是否加分号
    singleQuote: false, // 单引号
    printWidth: 120, // 换行长度
    arrowParens: "always", // 箭头函数参数
    bracketSpacing: true, // 对象花括号内是否加空格
    endOfLine: "auto", // 换行符
    vueIndentScriptAndStyle: false, // vue 文件内 script 和 style 标签缩进
};

添加格式化指令

json5
{
  "scripts": {
    "lint:format": "prettier --write --log-level warn \"src/**/*.{js,ts,json,tsx,css,less,vue,html,md}\"",
  }
}

解决 eslint 与 prettier 的冲突

https://github.com/prettier/eslint-config-prettier

1、安装配置文件

shell
pnpm install --save-dev eslint-config-prettier

2、在 eslint.config.js 添加配置

javascript
import someConfig from "some-other-config-you-use";
import eslintConfigPrettier from "eslint-config-prettier"; 

export default [
    someConfig,
    eslintConfigPrettier,   
];

stylelint

安装依赖

shell
pnpm create stylelint -D

安装好之后默认会添加两个依赖

json
{
  "devDependencies": {
    "stylelint": "^16.3.1",  
    "stylelint-config-standard": "^36.0.0",  
  }
}

并且会生成一个 .stylelintrc.json 文件,里面是默认的配置文件,内容如下

json5
{
  "extends": [
    "stylelint-config-standard"
  ]
}

建议将 .stylelintrc.json 改名为 stylelint.config.js,内容如下

javascript
export default {extends: ["stylelint-config-standard"]};

简单测试

修改 src/style.css 内容如下

css
div {
}

div {
    height: 200px;
    width: 200px;
    color: red;
}

然后运行指令进行检测

shell
$ npx stylelint src/style.css 

src/style.css
  1:5  Unexpected empty block                                     block-no-empty
  4:1  Unexpected duplicate selector "div", first used at line 1  no-duplicate-selectors

 2 problems (2 errors, 0 warnings)

可以看出来有两个规则不符合要求

shell
pnpm add stylelint-config-recommended-vue -D
pnpm add stylelint-config-standard-vue -D
pnpm add stylelint-config-html -D

修改 stylelint.config.js 配置文件

javascript
export default {
    extends: [
        "stylelint-config-standard",
        "stylelint-config-html/vue",        
        "stylelint-config-standard-vue",    
        "stylelint-config-standard-vue",    
    ],
};

修改 App.vue

vue
<script setup>
const number = 10; // 没有使用的变量
const msg = "hello world !";
</script>

<template>
  <div>hello ESLint !</div>
</template>

<style scoped>
div {}
div {height: 200px;width: 200px;color: red;}
</style>

运行指令之后可以发现不符合规则的内容被排查出来了

shell
$ npx stylelint src/App.vue 

src/App.vue
  11:5  Unexpected empty block                                      block-no-empty
  14:1  Unexpected duplicate selector "div", first used at line 11  no-duplicate-selectors

 2 problems (2 errors, 0 warnings)

如果将问题修正,则可以正常运行

样式排序

shell
pnpm add stylelint-order -D

添加配置规则

javascript
export default {
  extends: [
    "stylelint-config-standard",
    "stylelint-config-html/vue",
    "stylelint-config-recommended-vue",
    "stylelint-config-standard-vue",
  ],
  plugins: ["stylelint-order"],
  rules: {
    // 这里是允许了空的 style 标签
    "no-empty-source": null,
    "selector-class-pattern": null,
    // 禁止空块
    "block-no-empty": true,
    // 颜色6位长度
    "color-hex-length": "long",
    // 兼容自定义标签名
    "selector-type-no-unknown": [
      true,
      {
        ignoreTypes: [],
      },
    ],
    // 忽略伪类选择器 ::v-deep
    "selector-pseudo-element-no-unknown": [
      true,
      {
        ignorePseudoElements: ["v-deep"],
      },
    ],
    // 禁止低优先级的选择器出现在高优先级的选择器之后。
    "no-descending-specificity": null,
    // 不验证@未知的名字,为了兼容scss的函数
    "at-rule-no-unknown": null,
    // 禁止空注释
    "comment-no-empty": true,
    // 禁止简写属性的冗余值
    "shorthand-property-no-redundant-values": true,
    // 禁止值的浏览器引擎前缀
    "value-no-vendor-prefix": true,
    // property-no-vendor-prefix
    "property-no-vendor-prefix": true,
    // 属性的排序
    "order/properties-order": [
      "position",
      "top",
      "right",
      "bottom",
      "left",
      "z-index",
      "display",
      "justify-content",
      "align-items",
      "float",
      "clear",
      "overflow",
      "overflow-x",
      "overflow-y",
      "margin",
      "margin-top",
      "margin-right",
      "margin-bottom",
      "margin-left",
      "border",
      "border-style",
      "border-width",
      "border-color",
      "border-top",
      "border-top-style",
      "border-top-width",
      "border-top-color",
      "border-right",
      "border-right-style",
      "border-right-width",
      "border-right-color",
      "border-bottom",
      "border-bottom-style",
      "border-bottom-width",
      "border-bottom-color",
      "border-left",
      "border-left-style",
      "border-left-width",
      "border-left-color",
      "border-radius",
      "padding",
      "padding-top",
      "padding-right",
      "padding-bottom",
      "padding-left",
      "width",
      "min-width",
      "max-width",
      "height",
      "min-height",
      "max-height",
      "font-size",
      "font-family",
      "font-weight",
      "text-align",
      "text-justify",
      "text-indent",
      "text-overflow",
      "text-decoration",
      "white-space",
      "color",
      "background",
      "background-position",
      "background-repeat",
      "background-size",
      "background-color",
      "background-clip",
      "opacity",
      "filter",
      "list-style",
      "outline",
      "visibility",
      "box-shadow",
      "text-shadow",
      "resize",
      "transition",
    ],
  },
};

然后运行测试指令

shell
$ npx stylelint src/App.vue 

src/App.vue
  13:3  Expected "width" to come before "height"  order/properties-order

 1 problem (1 error, 0 warnings)

错误原因是高不能再宽的前面,修改属性位置之后就可以通过测试。或者运行指令的时候加上 --fix 也可以自动修复。

shell
npx stylelint src/App.vue --fix

忽略格式化

根目录创建 .stylelintignore 文件,配置忽略文件如下:

dist
node_modules
public
.husky
.vscode

添加格式化指令

json5
{
  "scripts": {
    "lint:stylelint": "stylelint \"**/*.{css,scss,vue,html}\" --fix"
  }
}

husky

虽然上面已经配置好了 eslint、prettier 与 stylelint,但是还是存在以下问题。

对于没有使用 vscode 的,或者没有安装 eslint、prettier 与 stylelint 插件的用户来说,就不能实现在保存的时候自动的去修复与和格式化代码。

当在提交到 git 仓库的代码还是不符合要求的。因此需要引入强制的手段来保证提交到 git 仓库的代码时符合要求。

husky 是一个用来管理 git hook 的工具,git hook 即在使用 git 提交代码的过程中会触发的钩子。

shell
pnpm add --save-dev husky

初始化 git 项目

shell
git init

初始化 husky

shell
pnpm exec husky init

运行之后会在项目的根目录下生成 .husky 文件夹

并且会在 package.json 中的 script 中添加一条脚本命令

json5
{
  "scripts": {
    "prepare": "husky"
  },
}

然后在 .husky/pre-commit 文件中添加 pre-commit 钩子

pnpm lint:eslint
pnpm lint:format
pnpm lint:stylelint

当 pre-commit 里面的指令全部校验通过时,才会被提交。

lint-staged

lint-staged 可以在 git staged 阶段的文件上执行代码检查(Linters),包括 ESLint 和 Stylelint 等。 简单说就是,当开发者运行 ESLint 或 Stylelint 命令时,可以通过设置指定只检查通过 git add 添加到暂存区的文件, 避免每次检查都把整个项目的代码都检查一遍,从而提高效率。

1、执行此命令来安装 lint-staged,执行后 .husky/_ 文件夹下将自动生成 husky.sh 脚本

shell
pnpm add lint-staged -D

2、在 package.json 中添加 scripts

"pre-commit": "lint-staged"

3、新建 lint-staged.config.js 配置文件并添加以下命令

提交时执行 prettier 代码格式化,eslint 检查修复

json
{
  "src/**/*.{ts,vue}": [
    "prettier --write",
    "eslint --fix"
  ]
}

4、修改 .husky/pre-commit 文件,使提交时能执行 lint-staged 钩子

shell
npm run pre-commit

commit-msg

commitlint 检查提交消息是否符合常规提交格式,用于在每次提交时生成符合规范的 commit 消息。

1、安装 commit-msg

shell
pnpm install --save-dev @commitlint/config-conventional @commitlint/cli

2、在项目根目录下添加 commitlint.config.js 配置文件,配置文件详细说明如下:

javascript
export default {
    extends: ["@commitlint/config-conventional"],
    rules: {
        "type-enum": [
            // type枚举
            2,
            "always",
            [
                "build", // 编译相关的修改,例如发布版本、对项目构建或者依赖的改动
                "feat", // 新功能
                "fix", // 修补bug
                "docs", // 文档修改
                "style", // 代码格式修改, 注意不是 css 修改
                "refactor", // 重构
                "perf", // 优化相关,比如提升性能、体验
                "test", // 测试用例修改
                "revert", // 代码回滚
                "ci", // 持续集成修改
                "config", // 配置修改
                "chore", // 其他改动
            ],
        ],
        "type-empty": [2, "never"], // never: type不能为空; always: type必须为空
        "type-case": [0, "always", "lower-case"], // type必须小写,upper-case大写,camel-case小驼峰,kebab-case短横线,pascal-case大驼峰,等等
        "scope-empty": [0],
        "scope-case": [0],
        "subject-empty": [2, "never"], // subject不能为空
        "subject-case": [0],
        "subject-full-stop": [0, "never", "."], // subject以.为结束标记
        "header-max-length": [2, "always", 72], // header最长72
        "body-leading-blank": [0], // body换行
        "footer-leading-blank": [0, "always"], // footer以空行开头
    },
};

3、执行以下命令添加 commitlint 钩子

shell
echo "npm run commitlint" > .husky/commit-msg

4、在 package.json script 中增加

"commitlint": "commitlint --config commitlint.config.js -e -V"

按上面步骤修改完,我们在提交代码时候,如果随便写一个提交 message 将会报错,不允许提交,如下所示:

shell
$ git commit -m 'add'

...

> vite-project@0.0.0 commitlint
> commitlint --config commitlint.config.js -e -V

   input: add
   subject may not be empty [subject-empty]
   type may not be empty [type-empty]

   found 2 problems, 0 warnings
   Get help: https://github.com/conventional-changelog/commitlint/#what-is-commitlint

husky - commit-msg script failed (code 1)

如果我们修改提交语句,则能正确提交

shell
git commit -m 'fix: 测试'

参考

https://www.stylelint.cn/

https://juejin.cn/post/7239173192492957752

https://juejin.cn/post/7282744150843047991