构建现代前端开发基石:在 Vue3/UniApp 项目中集成 ESLint 9 + Prettier + Husk...

在现代前端工程化实践中,一套健壮的代码质量与风格保障体系是团队协作和项目长期维护的基石。无论是开发 Vue3 单页应用,还是使用 UniApp 构建跨端项目,集成 ESLint(代码检查)、Prettier(代码格式化)、Husky(Git 钩子)和 Lint-Staged(增量检查)已成为提升开发效率和代码一致性的标准配置。本文将手把手带你完成从零到一的完整配置,涵盖最新的 ESLint 9 扁平化配置,并深入解析每个工具的作用与最佳实践,助你打造一个高效、规范的开发工作流。

一、项目初始化与 ESLint 9 的现代化配置

首先,你需要创建一个项目。根据你的需求,可以选择创建 UniApp 项目或标准的 Vue3 项目。

创建 UniApp 项目:

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

或者,创建 Vue3 + TypeScript 项目:

pnpm create vite

项目创建完毕后,我们进入核心环节:配置 ESLint 9。ESLint 9 采用了全新的扁平化配置系统(eslint.config.js/mjs),与旧版 .eslintrc 有较大不同。首先,通过包管理器初始化 ESLint:

pnpm create @eslint/config@latest

在初始化过程中,你需要回答几个关键问题:

  • 模块系统:现代前端项目通常选择 JavaScript modules (import/export) (ESM)。
  • 运行环境:根据项目类型勾选 browser(浏览器)和/或 node(Node.js),这决定了 ESLint 识别的全局变量。
  • 配置文件格式:选择 JavaScript 即可,它足够灵活。

初始化完成后,安装生成的依赖包:

此时,项目根目录会生成一个 eslint.config.js 文件(也可能是 .mjs 或 .cjs)。文件扩展名决定了模块系统:

  • .mjs: 强制使用 ESM (import/export)。
  • .cjs: 强制使用 CommonJS (require/module.exports)。
  • .js: 依赖 package.json 中的 "type" 字段决定。

eslint.config.ts、eslint.config.mts、eslint.config.cts同理,只是ts版

而且需要额外配置

https://eslint.org/docs/latest/use/configure/configuration-files

自动生成的配置文件基础结构如下:

import js from "@eslint/js" // 导入推荐的js规范
import globals from "globals" // 导入各环境全局变量定义
import tseslint from "typescript-eslint" // 导入ts规范和解析器
import pluginVue from "eslint-plugin-vue"  // 导入vue的eslint插件(包含.vue文件解析和vue规范)
import { defineConfig } from "eslint/config" // 导入eslint9的配置辅助函数
// 导出一组配置对象
export default defineConfig([
  {
    // mjs/mts,js/ts版的esmodule文件
    // cjs/cts,js/ts版的commonjs文件
    files: ["**/*.{js,mjs,cjs,ts,mts,cts,vue}"],
    plugins: { js }, // 指定插件
    extends: ["js/recommended"], // 加载来自@eslint/js的recommended的配置
    languageOptions: {
      // 使用全局变量
      globals: globals.browser
    }
  },
  // typescript-eslint配置
  tseslint.configs.recommended,
  // eslint-plugin-vue配置
  pluginVue.configs["flat/essential"],
  {
    // 在vue文件中使用ts
    files: ["**/*.vue"],
    languageOptions: {
      // 配置ts的解析器
      parserOptions: {
        parser: tseslint.parser
      }
    }
  },
])

对于 Vue3 + TypeScript 项目,我们需要扩展更多插件。首先,确保安装了必要的依赖:@typescript-eslint/eslint-plugin, @typescript-eslint/parser, eslint-plugin-vue。然后,配置它们:

// 导出一组配置对象
export default defineConfig([
  // ...
  // eslint-plugin-vue配置
  pluginVue.configs['flat/essential'],
  // 放在eslint-plugin-vue的配置之后,用来覆盖规则
  {
    rules: {
      'vue/multi-word-component-names': 'off'
    }
  },
  // ...
])

这里,我们集成了 TypeScript 和 Vue3 的推荐规则。你可能需要根据团队规范调整某些规则,例如关闭 Vue 组件名必须为多字的规则。

配置忽略文件:在 ESLint 9 中,传统的 .eslintignore 文件对于新的扁平化配置文件(如 eslint.config.js)是无效的。必须使用配置对象中的 ignores 字段来声明忽略模式。

对于 Vue 项目,常见的忽略配置如下:

// eslint.config.js
import { defineConfig, globalIgnores } from "eslint/config"
export default defineConfig([
  // 全局忽略
  globalIgnores([
    "node_modules/",
    "pnpm-lock.yaml",
    '**/*.css',
    '**/*.d.ts'
  ]),
  // 其他配置...
])

对于 UniApp 项目,还需额外忽略其特有的目录:

// eslint.config.js
import { defineConfig, globalIgnores } from "eslint/config"
export default defineConfig([
  // 全局忽略
  globalIgnores([
    "node_modules/",
    "src/uni_modules/",
    "dist/",
    "pnpm-lock.yaml",
    '**/*.css',
    '**/*.d.ts'
  ]),
  // 其他配置...
])

最后,别忘了在 VS Code 中安装 ESLint 插件,以获得实时代码检查和高亮提示。

[AFFILIATE_SLOT_1]

二、集成 Prettier:统一代码风格格式化

ESLint 主要负责代码质量和潜在错误检查,虽然也能处理一些格式问题,但 Prettier 才是专精于代码风格格式化的“专家”。它能强制统一缩进、分号、引号、换行等风格,让团队代码如出一辙。

首先,安装 Prettier。建议使用 --save-exact 标志锁定版本,确保团队环境一致。

pnpm add -D prettier

接着,创建 Prettier 配置文件 .prettierrc.js(或 .json, .yaml 等格式)。

配置文件,我不喜欢采用yaml(配置起来有缩进问题)、json(写注释有问题),比较喜欢js

我这里采用prettier.config.js,因为已经有了eslint.config.js,为了统一所以选这个

以下是一个兼顾 Vue/JS/TS 的常用配置示例,你可以根据 Prettier 官方选项文档进行调整。

const config = {
  // 行尾是否加逗号,默认none
  trailingComma: 'none',
  // 缩进大小,默认2
  tabWidth: 2,
  // 是否使用分号
  semi: false,
  // 使用使用单引号
  singleQuote: true,
  // 代码行最大长度,默认80
  printWidth: 80,
  // 换行符使用lf
  endOfLine: 'lf'
}
export default config

同时,创建 .prettierignore 文件,告诉 Prettier 哪些文件不需要格式化(通常与 .gitignore 类似)。

// vue
// .prettierignore文件
node_modules/
pnpm=lock.yaml
// uniapp
// .prettierignore文件
node_modules/
pnpm=lock.yaml
src/uni_modules/*
dist/*

同样,在 VS Code 中安装 Prettier 插件,并配置为默认格式化工具,同时开启保存时自动格式化,这将极大提升开发体验。

三、解决 ESLint 与 Prettier 的规则冲突

ESLint 和 Prettier 的某些格式化规则可能存在重叠和冲突。例如,ESLint 可能要求尾随逗号,而 Prettier 的配置可能将其移除。为了解决这个问题,我们需要两个辅助包:

  • eslint-config-prettier: 关闭 ESLint 中所有与 Prettier 冲突的格式化规则。
  • eslint-plugin-prettier: 将 Prettier 的格式化规则作为 ESLint 规则来运行,让你能在 ESLint 的输出中看到 Prettier 的格式错误。

安装它们:

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

然后,在 eslint.config.js 中集成配置。注意,新版 ESLint 的配置语法与旧版不同。

// eslint.config.js
// 其他import
import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended'
export default defineConfig([
  {
  // 其他配置
  // 将 prettier 配置放在最后,确保它能覆盖其他规则
  eslintPluginPrettierRecommended
])

至此,你的代码在保存时将由 Prettier 统一格式化,而 ESLint 则专注于检查代码质量(如未使用的变量、错误的类型等),两者和谐共处。

四、利用 Husky 与 Lint-Staged 实现提交前自动化检查

仅靠编辑器插件,无法保证所有团队成员提交的代码都是规范的。我们需要在 Git 提交环节设立关卡。这就是 Huskylint-staged 的用武之地。

Husky 让你能够方便地管理 Git 钩子(Hooks)。Lint-Staged 则让你只对暂存区(git add 后的文件)的代码运行检查,避免每次提交都对整个项目进行全量扫描,效率极高。

首先,安装并初始化 Husky:

pnpm add -D husky
git init

初始化命令会创建 .husky 目录。接着,我们创建一个 pre-commit 钩子,它会在执行 git commit 命令前触发。

pnpm exec husky init

现在,安装 lint-staged:

pnpm add -D lint-staged

创建一个 lint-staged.config.js 配置文件。这里面的逻辑是:对暂存区中不同类型的文件,执行对应的格式化(Prettier)和检查(ESLint)命令,并自动将修复后的内容添加回暂存区。

import { ESLint } from 'eslint'
const removeIgnoredFiles = async (files) => {
  const eslint = new ESLint()
  // eslint.isPathIgnored(file) 返回 Promise
  // Promise.all() 将所有检查并行执行,提升性能
  const ignoredFiles = await Promise.all(
    files.map((file) => eslint.isPathIgnored(file))
  )
  // 过滤出未被忽略的文件:
  // ignoredFiles[i] 为 true 表示该文件被忽略
  // !ignoredFiles[i] 为 true 表示保留该文件
  // 使用下划线 _ 表示不使用 file 参数,仅用索引 i
  const filteredFiles = files.filter((_, i) => !ignoredFiles[i])
  // 将文件路径数组转为字符串,用空格分隔,便于拼接到命令行中
  return filteredFiles.join(' ')
}
// 导出 lint-staged 的配置对象
export default {
  // '*' 表示匹配所有文件类型(.js, .ts, .vue 等)
  // lint-staged 会将匹配到的暂存文件列表传入此函数
  '*': async (files) => {
    // 先过滤掉被 .eslintignore 忽略的文件
    const filesToLint = await removeIgnoredFiles(files)
    // 返回要执行的 shell 命令数组
    // --max-warnings=0 表示:即使只有警告(warning),也视为错误,阻止提交
    return [`eslint ${filesToLint} --max-warnings=0`]
  }
}

这个配置的关键在于:

  1. 使用 eslint --fix 自动修复可修复的问题。
  2. 使用 prettier --write 进行格式化。
  3. 将处理后的文件重新 git add,确保提交的是格式化后的代码。

最后,修改 Husky 的 pre-commit 钩子文件,让它执行 lint-staged。

pnpm exec lint-staged
[AFFILIATE_SLOT_2]

五、额外加成:EditorConfig 与工作流验证

为了在不同编辑器和 IDE 之间保持最基本的代码风格一致(如缩进、字符集),可以引入 EditorConfig。在 VS Code 中安装 EditorConfig 插件后,在项目根目录创建 .editorconfig 文件。

[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
[*.md]
trim_trailing_whitespace = false
[*.json]
indent_size = 2

现在,让我们验证整个工作流是否生效。首先,尝试运行 lint-staged 的检查(模拟提交过程):

git add .

如果一切正常,你可以进行一次真实的代码提交。当执行 git commit 时,你会看到 Husky 触发了 lint-staged,并自动对你的代码进行了格式化和检查。

git commit -m "init"

如果代码有 ESLint 错误且无法自动修复,提交会被阻止,直到你手动修复所有错误。这确保了仓库中的代码始终符合质量标准。

总结:通过集成 ESLint 9、Prettier、Husky 和 Lint-Staged,我们为 Vue3/UniApp 项目搭建了一套从编写、保存到提交的全链路代码质量守护体系。这套组合拳不仅强制统一了代码风格,消除了基础语法错误,还将规范检查流程自动化、无缝化,使开发者可以更专注于业务逻辑本身。虽然初始配置有一定学习成本,但它为团队协作和项目长期健康度带来的收益是巨大的,是现代前端工程化不可或缺的一环。

posted on 2026-02-23 17:51  blfbuaa  阅读(94)  评论(0)    收藏  举报