Vue3+Vite+TS: 配置 ESLint、Prettier、Stylelint、Husky、Lint-staged、Commitlint、Commitiz

1,452 阅读11分钟

本文介绍Uniapp或者Vue3+vite+ts配置eslint+prettier+stylelint代码规范检查以及Husky+Lint-staged+Commitlint+Commitizen+cz-git Git 代码提交规范

一、使用vue-cli命令行创建项目

npx degit dcloudio/uni-preset-vue#vite-ts my-vue3-project

uni-app cli项目@uniapp-cli | uni-app官网​uniapp.dcloud.net.cn/worktile/auto/uniapp-cli-project.html#uniapp-cli

二、ESLint 安装与配置

ESLint 是一个用于识别和报告在 ECMAScript/JavaScript 代码中发现的模式的工具,其目标是使代码更加一致并避免错误。

ESLint 中文网​eslint.nodejs.cn/

1、安装

按照ESLint官网的步骤,第一步初始化eslint,在你的项目根目录执行以下命令:

npm init @eslint/config@latest
或
pnpm create @eslint/config@latest

按照提示,选择你需要的配置,完成所有步骤后,项目下会自动生成eslint的配置文件,安装需要的依赖包。

2、添加.eslintignore忽略文件

Configuration Migration Guide - ESLint - Pluggable JavaScript Linter​eslint.org/docs/latest/use/configure/migration-guide#ignoring-files

参考上面链接,在中添加export default []中添加{ ignores: ["**/temp.js", "config/*"]}

export default [
    // ...other config
    {
        ignores: [
         "config/*",
         ".husky",
         ".local",
         "public/*",
         ".vscode",
         "node_modules"
       ]
    }
];

3、vscode安装ESLint插件

要让vscode通过eslint检查代码,还得在vscode中安装eslint插件。

ESLint - Visual Studio Marketplace​marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint

完成这步后,最好是重启下vscode,不出意外这个时候,你代码中如果有语法错误的地方,应该就会爆红了。

但是代码规范问题依旧不会爆红,如单引号与双引号,末尾是否有分号等。这就是prettier该干的事情了。

4、在 package.json 中添加 Eslint 脚本

在你的 package.json 文件中添加一个脚本来运行 Eslint :

{
  "scripts": {
    "lint:eslint": "eslint --cache --max-warnings 0  "{src,mock}/**/*.{vue,ts,tsx}" --fix",
  }
}

三、Prettier 安装与配置

Prettier 是一个代码格式化程序

Prettier 中文网​prettier.nodejs.cn/

1、安装

首先,在本地安装 Prettier:

pnpm add --save-dev --save-exact prettier

2、配置

通过如下命令在项目根目录下创建一个空的prettier.config.mjs配置文件,也可以手动添加

node --eval "fs.writeFileSync('prettier.config.mjs','export default{}\n')"

在prettier.config.mjs配置文件中添加如下内容:

export default {
  printWidth: 80, // 一行最多80个字符
  tabWidth: 2, // 设置工具每一个水平缩进的空格数
  useTabs: false, //不使用缩进,而使用空格
  semi: true, // 句末是否加分号
  vueIndentScriptAndStyle: true, //Vue文件中<script>和<style>是否缩进
  singleQuote: false, // 用单引号
  trailingComma: "none", // 最后一个对象元素符加逗号
  bracketSpacing: true, // 箭头函数,只有一个参数的时候,也需要括号
  arrowParens: "always", // 不需要写文件开头的 @prettier
  insertPragma: false, // 不需要自动在文件开头加入 @prettier
  endOfLine: "auto", // 换行符使用 auto 有些地方说的是推荐使用lf
};

这里只是一部分配置,如需要更多配置,可以去prettier官网查看

3、添加.prettierignore忽略文件

通过如下命令在项目根目录下创建.prettierignore文件,也可手动添加

node --eval "fs.writeFileSync('.prettierignore','')"

内容如下,根据自己项目实际情况调整

dist
.local
.output.js
node_modules

**/*.svg
**/*.sh

public
.npmrc

4、在 package.json 中添加 Prettier 脚本

在你的 package.json 文件中添加一个脚本来运行 Prettier:

{
  "scripts": {
    "format": "prettier --write ."
  }
}

5、vscode安装Prettier - Code formatter插件

Prettier - Code formatter - Visual Studio Marketplace​marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode

6、开启vscode保存自动格式化的设置

在vscode左下角点击设置按钮,点击seetings选项,找到Text Editor->Formatting-> Format on save选项,勾选此选项即可。

四、解决 Eslint 和 Prettier 的冲突

当项目同时使用 Eslint 和 Prettier 时,往往格式化时会有冲突,导致最终格式化效果不对。其实解决方案很成熟,就是用到两个插件,eslint-plugin-prettier和eslint-config-prettier

GitHub - prettier/eslint-config-prettier: Turns off all rules that are unnecessary or might conflict with Prettier.​github.com/prettier/eslint-config-prettier?tab=readme-ov-file#readme

GitHub - prettier/eslint-plugin-prettier: ESLint plugin for Prettier formatting​github.com/prettier/eslint-plugin-prettier#recommended-configuration

当你的项目已经安装了 eslint 和 prettier 后,也有了各自的配置文件后,安装以上两个插件:

pnpm add eslint-config-prettier eslint-plugin-prettier -D

然后在你的 eslint 配置文件中的 extends 中最后加上一个plugin:prettier/recommended

配置参考下面链接

Configuration Migration Guide - ESLint - Pluggable JavaScript Linter​eslint.org/docs/latest/use/configure/migration-guide#using-eslintrc-configs-in-flat-config

需要安装@eslint/eslintrc

pnpm add @eslint/eslintrc --save-dev

具体代码:

import globals from "globals";
import pluginJs from "@eslint/js";
import tseslint from "typescript-eslint";
import pluginVue from "eslint-plugin-vue";
import { FlatCompat } from "@eslint/eslintrc";
import path from "path";
import { fileURLToPath } from "url";

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

const compat = new FlatCompat({
  baseDirectory: __dirname
});

export default [
  { languageOptions: { globals: { ...globals.browser, ...globals.node } } },
  pluginJs.configs.recommended,
  ...tseslint.configs.recommended,
  ...pluginVue.configs["flat/essential"],
  ...compat.extends("plugin:prettier/recommended"),
  {
    ignores: ["**/temp.js", "config/*"]
  }
];

vscode要注意安装 Prettier - Code formatter和 ESLint这两个插件,同时加上这一段配置,可以在项目中添加配置文件.vscode/settings.json,文件内容如下:

{
  "editor.formatOnSave": true,
  "editor.codeActionsOnSave": {
    "source.fixAll": "explicit"
  },
  "editor.defaultFormatter": "esbenp.prettier-vscode"
}

此时重启编辑器,可以做到完美格式化代码。要注意的是,此时不要在 eslint 配置文件中加上代码风格相关的配置,这样可能又会跟 prettier 冲突。上面的配置可以做到让 eslint 检查代码错误,让 prettier 格式化。所以要改变代码风格,请到 prettier 中修改。修改后重启vscode编辑器

五、解决 uni 这个全局变量爆红的问题 (如果你的项目不是uniapp,或者没有报错,请忽略这一步)

在eslint中添加一个全局变量忽略配置,忽略uni全局变量的检查:

 // 全局变量忽略检测
  globals: {
    uni: "writable"
  },

或者在rules中添加"no-undef": "off"选项,将该规则关闭。

六、Stylelint 安装与配置

stylelint是一个用于检测CSS代码风格的工具。它可以帮助开发人员保持一致的代码风格,并捕获常见的错误和潜在的问题。stylelint支持自定义规则和插件,可以根据团队的需求进行配置。它可以与各种构建工具和编辑器集成,提供实时的代码检查和自动修复功能

Home | Stylelint​stylelint.io/

1、安装 stylelint 、规范集和相关插件

pnpm add -D  postcss postcss-html postcss-import postcss-scss stylelint stylelint-config-html stylelint-config-property-sort-order-smacss stylelint-config-rational-order stylelint-config-recommended stylelint-config-standard stylelint-order stylelint-prettier

2、配置

通过如下命令在项目根目录下创建.stylelintrc.json文件,也可手动添加

node --eval "fs.writeFileSync('.stylelintrc.json','')"

在.stylelintrc.json配置文件中添加如下内容:

{
  "extends": [
    "stylelint-config-standard",
    "stylelint-config-property-sort-order-smacss"
  ],
  "plugins": ["stylelint-order", "stylelint-prettier"],
  "overrides": [
    {
      "files": ["**/*.(css|html|vue)"],
      "customSyntax": "postcss-html"
    },
    {
      "files": ["*.less", "**/*.less"],
      "customSyntax": "postcss-less",
      "extends": [
        "stylelint-config-standard",
        "stylelint-config-recommended-vue"
      ]
    },
    {
      "files": ["*.scss", "**/*.scss"],
      "customSyntax": "postcss-scss",
      "extends": [
        "stylelint-config-standard-scss",
        "stylelint-config-recommended-vue/scss"
      ],
      "rule": {
        "scss/percent-placeholder-pattern": null
      }
    }
  ],
  "rules": {
    "selector-not-notation": null,
    "import-notation": null,
    "function-no-unknown": null,
    "selector-class-pattern": null,
    "selector-pseudo-class-no-unknown": [
      true,
      {
        "ignorePseudoClasses": ["global", "deep"]
      }
    ],
    "selector-pseudo-element-no-unknown": [
      true,
      {
        "ignorePseudoElements": ["v-deep"]
      }
    ],
    "at-rule-no-unknown": [
      true,
      {
        "ignoreAtRules": [
          "tailwind",
          "apply",
          "variants",
          "responsive",
          "screen",
          "function",
          "if",
          "each",
          "include",
          "mixin",
          "extend"
        ]
      }
    ],
    "no-empty-source": null,
    "named-grid-areas-no-invalid": null,
    "no-descending-specificity": null,
    "font-family-no-missing-generic-family-keyword": null,
    "rule-empty-line-before": [
      "always",
      {
        "ignore": ["after-comment", "first-nested"]
      }
    ],
    "unit-no-unknown": [true, { "ignoreUnits": ["rpx"] }],
    "order/order": [
      [
        "dollar-variables",
        "custom-properties",
        "at-rules",
        "declarations",
        {
          "type": "at-rule",
          "name": "supports"
        },
        {
          "type": "at-rule",
          "name": "media"
        },
        "rules"
      ],
      { "severity": "error" }
    ]
  },
  "ignoreFiles": ["**/*.js", "**/*.jsx", "**/*.tsx", "**/*.ts"]
}

添加忽略文件.stylelintignore

node --eval "fs.writeFileSync('.stylelintignore','')"

在.stylelintignore文件中添加如下内容:

dist
public
node_modules

3、配置自动格式化

在.vscode/settings.json中加入如下配置:

{
  "editor.formatOnSave": true,
  "editor.codeActionsOnSave": {
    "source.fixAll": "explicit",
    "source.stylelint": "explicit"
  },
  "stylelint.validate": ["css", "less", "postcss", "scss", "sass", "vue"],
  "editor.defaultFormatter": "esbenp.prettier-vscode"
}

4、在 package.json 中添加 Stylelint 脚本

在你的 package.json 文件中添加一个脚本来运行 Stylelint:

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

七、husky安装

Husky是一个流行的Git钩子工具,用于在不同的 Git 操作(如提交和推送)前自动运行脚本。比如代码格式化、静态检查等。这有助于保持代码库的质量和一致性。

1、安装

npm install --save-dev husky 
或
pnpm add --save-dev husky  

2、初始化

使用官方推荐的初始化命令,如果是新项目,在该命令执行前请先使用 git init 命令初始化git仓库

npx husky init
或
pnpm exec husky init

执行完该命令后,它在.husky/中创建一个预提交脚本,并在package.json中更新 prepare 脚本。

八、Lint-staged 安装与配置

lint-staged 是一个在 git add 到暂存区的文件运行 linters (ESLint/Prettier/StyleLint) 的工具,避免在 git commit 提交时在整个项目执行。lint-staged 可以让你当前的代码检查 只检查本次修改更新的代码,并在出现错误的时候,自动修复并且推送

GitHub - lint-staged/lint-staged: — Run linters on git staged files​github.com/lint-staged/lint-staged

1、安装

npm install --save-dev lint-staged 
或
pnpm add --save-dev lint-staged  

2、Lint-staged 配置

在package.json中添加 lint-staged 对象:

"lint-staged": {
    "*.{js,ts,vue}": [
      "eslint --fix",
      "prettier --write"
    ],
    "*.{cjs,json}": [
      "prettier --write"
    ],
    "*.{vue,html}": [
      "eslint --fix",
      "prettier --write",
      "stylelint --fix"
    ],
    "*.{scss,css}": [
       "stylelint --fix --allow-empty-input",
      "prettier --write"
    ],
    "*.md": [
      "prettier --write"
    ]
  }

在package.json 的 scripts 添加 lint-staged 指令:

  "scripts": {
    "lint:lint-staged": "lint-staged"
  }

3、修改提交前钩子命令

根目录 .husky目录下pre-commit文件中的 npm test 修改为

npm run lint:lint-staged

4、Git 提交代码检测

git add .
git commit -m "test husky lint-staged"

九、Commitlint 安装与配置

Commitlint 检查您的提交消息是否符合 Conventional commit format。

commitlint​commitlint.js.org/

1、安装

pnpm add --save-dev @commitlint/config-conventional @commitlint/cli

2、配置

通过如下命令在项目根目录下创建commitlint.config.js文件,也可手动添加

node --eval "fs.writeFileSync('commitlint.config.js','')"

在commitlint.config.js配置文件中添加如下配置:

module.exports = {
  // 继承的规则
  extends: ["@commitlint/config-conventional"],
  // @see: https://commitlint.js.org/#/reference-rules
  rules: {
    "subject-case": [0], // subject大小写不做校验

    // 类型枚举,git提交type必须是以下类型
    "type-enum": [
      2,
      "always",
      [
        "feat", // 新增功能
        "fix", // 修复缺陷
        "docs", // 文档变更
        "style", // 代码格式(不影响功能,例如空格、分号等格式修正)
        "refactor", // 代码重构(不包括 bug 修复、功能新增)
        "perf", // 性能优化
        "test", // 添加疏漏测试或已有测试改动
        "build", // 构建流程、外部依赖变更(如升级 npm 包、修改 webpack 配置等)
        "ci", // 修改 CI 配置、脚本
        "revert", // 回滚 commit
        "chore" // 对构建过程或辅助工具和库的更改(不影响源文件、测试用例)
      ]
    ]
  }
};

3、添加提交信息校验钩子

通过如下命令在创建.husky/commit-msg文件用于 git 提交信息校验,也可手动创建:

node --eval "fs.writeFileSync('.husky/commit-msg','')"

在.husky/commit-msg文件中添加如下内容:

npx --no -- commitlint --edit $1

4、commit验证

不规范的 commit msg,提交失败:

规范的 commit msg,提交成功:

十、Commitizen & cz-git 安装与配置

commitizen

基于Node.js的 git commit 命令行工具,辅助生成标准化规范化的 commit message。

github.com/commitizen/…

cz-git

一款工程性更强,轻量级,高度自定义,标准输出格式的 commitizen 适配器。

cz-git | 一款工程性更强,轻量级,高度自定义,标准输出格式的 Commitizen 适配器​cz-git.qbb.sh/zh/

1、安装

pnpm add -D commitizen cz-git

2、cz-git 配置

修改package.json,指定使用的适配器:

 "config": {
    "commitizen": {
      "path": "node_modules/cz-git"
    }
  }

cz-git 与commitlint进行联动给予校验信息,所以可以编写于commitlint.config.js配置文件之中:

// commitlint.config.js

module.exports = {
  extends: ["@commitlint/config-conventional"],
  rule: {
    ...
  },
  prompt: {
  messages: {
      type: '选择你要提交的类型 :',
      scope: '选择一个提交范围(可选):',
      customScope: '请输入自定义的提交范围 :',
      subject: '填写简短精炼的变更描述 :\n',
      body: '填写更加详细的变更描述(可选)。使用 "|" 换行 :\n',
      breaking: '列举非兼容性重大的变更(可选)。使用 "|" 换行 :\n',
      footerPrefixesSelect: '选择关联issue前缀(可选):',
      customFooterPrefix: '输入自定义issue前缀 :',
      footer: '列举关联issue (可选) 例如: #31, #I3244 :\n',
      generatingByAI: '正在通过 AI 生成你的提交简短描述...',
      generatedSelectByAI: '选择一个 AI 生成的简短描述:',
      confirmCommit: '是否提交或修改commit ?',
    },
    // prettier-ignore
    types: [
      { value: "feat",     name: "特性:     ✨  新增功能", emoji: ":sparkles:" },
      { value: "fix",      name: "修复:        修复缺陷", emoji: ":bug:" },
      { value: "docs",     name: "文档:        文档变更", emoji: ":memo:" },
      { value: "style",    name: "格式:        代码格式(不影响功能,例如空格、分号等格式修正)", emoji: ":lipstick:" },
      { value: "refactor", name: "重构:     ♻️  代码重构(不包括 bug 修复、功能新增)", emoji: ":recycle:" },
      { value: "perf",     name: "性能:     ⚡️  性能优化", emoji: ":zap:" },
      { value: "test",     name: "测试:     ✅  添加疏漏测试或已有测试改动", emoji: ":white_check_mark:"},
      { value: "build",    name: "构建:      ️  构建流程、外部依赖变更(如升级 npm 包、修改 vite 配置等)", emoji: ":package:"},
      { value: "ci",       name: "集成:        修改 CI 配置、脚本",  emoji: ":ferris_wheel:"},
      { value: "revert",   name: "回退:     ⏪️  回滚 commit",emoji: ":rewind:"},
      { value: "chore",    name: "其他:        对构建过程或辅助工具和库的更改(不影响源文件、测试用例)", emoji: ":hammer:"},
    ],
    useEmoji: true,
    emojiAlign: 'center',
    useAI: false,
    aiNumber: 1,
    themeColorCode: '',
    scopes: [],
    allowCustomScopes: true,
    allowEmptyScopes: true,
    customScopesAlign: 'bottom',
    customScopesAlias: 'custom',
    emptyScopesAlias: 'empty',
    upperCaseSubject: false,
    markBreakingChangeMode: false,
    allowBreakingChanges: ['feat', 'fix'],
    breaklineNumber: 100,
    breaklineChar: '|',
    skipQuestions: [],
    issuePrefixes: [{ value: 'closed', name: 'closed:   ISSUES has been processed' }],
    customIssuePrefixAlign: 'top',
    emptyIssuePrefixAlias: 'skip',
    customIssuePrefixAlias: 'custom',
    allowCustomIssuePrefix: true,
    allowEmptyIssuePrefix: true,
    confirmColorize: true,
    maxHeaderLength: Infinity,
    maxSubjectLength: Infinity,
    minSubjectLength: 0,
    scopeOverrides: undefined,
    defaultBody: '',
    defaultIssues: '',
    defaultScope: '',
    defaultSubject: '',
  }
}

添加提交指令

package.json 添加 commit 指令

"scripts": {
     "commit": "git-cz"
 }

3、cz-git 验证

执行 commit 指令进行代码提交流程,执行前需将改动的文件通过git add添加到暂存区

pnpm  commit

执行命令之后会出现询问交互

根据提示一步步的完善 commit msg 信息

commit 之后git push推送到远程仓库

如有错误的地方,欢迎大家指正