还在复制粘贴 eslint 配置?封装个预置函数,彻底解放你的双手

前言

大家好!我是 嘟老板 。在前端开发中,ESLint 扮演着守护代码质量的关键角色。它通过一套严格的规则,确保代码的规范性和一致性。然而若负责多个项目,就会发现重复为每个项目配置 ESLint 是多么痛苦的事情。那有没有一种高效的方法,既能保证各项目的配置统一,又能减少重复劳动呢?今天我们就来聊聊如何封装 ESLint 预置函数,让你远离反复配置的烦恼,彻底解放你的双手。

阅读本文您将收获:

  1. 了解 ESLint 预置函数的设计思路。
  2. 了解 ESLint 预置函数实现的具体过程。
  3. 了解 ESLint 预置函数在实际项目中的应用。

设计思路

预置函数基于 ESLint v9.x,若版本在此之前,请查看迁移指南

设计比较简单,ESLint 配置文件 eslint.config.js 中,直接调用预置函数 preset 并导出其返回结果。

preset 函数允许针对特定项目场景,传入自定义的配置规则,覆盖预置规则。

preset 函数中预置了一系列 ESLint 规则配置,主要分为两部分 - 默认启用配置按需启用配置

默认启用配置 包括大多数项目都需要的基础配置,诸如 javascriptTypescriptignores 等相关配置。

按需启用配置 依赖项目技术栈,将决定权交于用户,可通过设置对应的启用选项参数,按需启用,如 VueJSONMarkdownPrettier 等相关配置。

preset 函数内部将 自定义规则预置规则 进行整合,输出最终配置。

封装过程

为达到 一次封装,到处可用 的目的,我们将预置函数封装成库。

工程初始化

以下涉及的执行语句,均在终端命令行输入,回车执行

  1. 新建项目目录
bash 复制代码
mkdir eslint-config
cd eslint-config

执行成功后,会创建一个 eslint-config 空目录并跳转进入。

  1. npm 初始化
bash 复制代码
npm init -y

执行成功后,会在根目录下自动生成 package.json 文件。

  1. typescript 初始化
bash 复制代码
pnpm add typescript -D
tsc init

执行成功后,会在根目录下自动生成 tsconfig.json 文件,并带有默认配置。

  1. 创建目录结构

基础结构如下:

bash 复制代码
mkdir src
cd src
touch index.ts

eslint.config.ts 暂且先不创建,预置函数封装完成后再处理。

OK,初始项目到此结束。

定义预置函数 preset

定义预置函数前,首先要考虑两个问题:

  • 预置函数应该接收哪些 参数
  • 预置函数应该返回什么 结果

参数

从设计可知,preset 函数允许以下操作:

  • 自定义 ESLint 配置。
  • 启用特定技术栈的 ESLint 配置。

因此 preset 至少要支持两个参数:

  • config:自定义配置,优先级最高,可覆盖预置配置。
  • envOptions :环境配置选项,可包含诸如 prettiervuejsonmarkdown 等,用于启用对应技术栈的预置 ESLint 配置。

结果

从设计可知,preset 函数返回的结果,可以被 eslint.config.js 直接导出并生效,因为 Eslint V9.x 配置文件导出的是 平铺结构 ,即 数组 ,所以 preset 函数返回的结果,就是包含完整 ESLint 配置的数组。

preset 函数基础结构定义如下:

javascript 复制代码
/**
 * eslint config 预置函数
 *
 * @param config 覆盖配置
 * @param evnOptions 环境配置项,可接受单个配置对象或多个配置数组
 * @returns
 */
export function preset(config: Linter.Config | Linter.Config[] = [], envOptions: EnvOptions = {}) {
  // 预置 eslint config 集合
  const configs: Linter.Config[] = []

  // 环境配置...

  // 合并自定义配置
  const hasCustomConfig = Array.isArray(config)
    ? config.length > 0
    : Object.keys(config).length > 0
  if (hasCustomConfig) {
    configs.push(...(Array.isArray(config) ? config : [config]))
  }

  return configs
}

默认启用配置

封装配置

上文提到,默认启用配置 是指那些大多数项目都需要启用的 ESLint 规则,包括但不限于 JavscriptTypescriptignoresnode 等相关规则。

本文以两个比较直观的 Javscript 规则为例:

bash 复制代码
eqeqeq: ['error', 'smart'] // 要求代码中相等运算符必须使用全等,即 ===
'no-debugger': 'warn' // 要求代码中不能出现 debugger 调试语句

src 下创建 configs 目录,用来维护各种类型的 ESLint 预置配置文件。

bash 复制代码
mkdir configs

configs 目录下新建 javascript.ts 文件,用来维护 Javascript 预置配置。

bash 复制代码
cd configs
touch javascript.ts

javascript.ts 中写入以下代码,导出 javascript 预置配置对象 - javascriptConfigs

javascript 复制代码
import globals from 'globals'

export const javascriptConfigs: Linter.Config[] = [
  {
    languageOptions: {
      globals: {
        ...globals.browser
      },
    },
    plugins: {},
    rules: {
      eqeqeq: ['error', 'smart'],
      'no-debugger': 'warn'
    },
  },
]

注:globals 是一个比较全面的涵盖多个环境全局变量的依赖包,包括但不限于浏览器环境,node 环境等。执行 pnpm add globals -S 安装。

篇幅所致,本文定义的 Javascript 规则比较简单,实际项目可基于风格要求自行扩展,比如在 rules 配置内补充规则,在 plugins 配置内引用现有插件等等。

整合配置

将默认规则添加到 preset 函数中:

javascript 复制代码
import { javascriptConfigs } from './configs/javascript'

// 默认 config
const BasicConfigs = [ ...javascriptConfigs ]

export function preset(config: Linter.Config | Linter.Config[] = [], envOptions: EnvOptions = {}) {
  // 默认规则配置
  const configs: Linter.Config[] = [ ...BasicConfigs ]

  // 环境配置...

  // 合并自定义配置...

  return configs
}

按需启用配置

封装配置

按需启用配置 依赖项目应用技术栈,交由用户决定是否启用。

我们以相对简单的配置 - Prettier 为例。

尽管目前大多项目都结合使用 ESLintPrettier,以加强对代码质量的管理,然而 Prettier 并不是必选项,所以可将其作为按需规则之一。

Prettier 配置涉及两个相关插件:

终端输入以下命令安装依赖:

bash 复制代码
pnpm add eslint-plugin-prettier eslint-config-prettier -S

configs 目录下新增 prettier.ts,用于维护 Prettier 相关配置:

bash 复制代码
cd configs
touch prettier.ts

prettier.ts 中写入以下代码,导出 Prettier 预置配置对象 - prettierConfigs

javascript 复制代码
import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended'
import eslintConfigPrettier from 'eslint-config-prettier'

export const prettierConfigs: Linter.Config[] = [
  eslintPluginPrettierRecommended,
  eslintConfigPrettier
]

方便起见,直接使用 eslint-plugin-prettier 的推荐配置(recommended),结合 eslint-config-prettier 提供的配置解决与 ESLint 规则的冲突问题。

到这,基础的 Prettier 配置就搞定了,若插件默认的规则不符合项目要求,可在后面追加自定义的规则对象。例如:

javascript 复制代码
export const prettierConfigs: Linter.Config[] = [
  eslintPluginPrettierRecommended,
  eslintConfigPrettier,
  {
      rules: {
          'prettier/prettier': 'warn'
      }
  }
]

整合配置

现在将 Prettier 配置添加预置函数 preset 中,分为以下两步:

  1. preset 第二个参数 envOptions 新增 prettier 选项,用于设置是否启用 Prettier 相关配置,默认 true ,即 启用

  2. preset 内部判断 prettier 选项是否为 true ,若是,则将 Prettier 配置加入到最终配置 configs 中。

javascript 复制代码
import { javascriptConfigs, prettierConfigs } from './configs/javascript'

// 默认 config
const BasicConfigs = [ ...javascriptConfigs ]

export function preset(config: Linter.Config | Linter.Config[] = [], {
    prettier: enablePrettier = true
}: EnvOptions = {}) {
  // 默认规则配置
  const configs: Linter.Config[] = [ ...BasicConfigs ]

  if (enablePrettier) {
      configs.push(...prettierConfigs)
  }

  // 环境配置...

  // 合并自定义配置...

  return configs
}

优化项

工具雏形已成,接下来就是在此基础上进行扩展完善,以适应更广泛的应用场景。

集成更多环境配置

一个前端项目,应用的技术多种多样,可针对项目需要,扩展工具内置配置项。

比如 TypeScriptVueReactJSONMarkdown 等,都是前端项目常用的技术栈,因此相关的 ESLint 配置也很有必要集成在工具内。

导出配置

对于某些特殊情况,如对已有 ESLint 配置的增强、完善,可能不想用 preset 函数,仅引用部分规则配置到项目中。

因此可以将工具内置的 ESLint 配置按类导出,供用户按需引入,添加到已有的 ESLint 配置文件中(eslint.config.js)中。

preset 自动判断是否启用按需配置

preset 函数第二个参数 envOptions 涉及按需启用配置选项,如 vue,除了直接给定默认值的方式外,还可通过 扫描项目依赖,自动判断是否启用。

例如:

javascript 复制代码
import { isPackageExists } from 'local-pkg'

// 是否包含 vue
export const hasVue = isPackageExists('vue') || isPackageExists('nuxt')

preset 函数中使用:

javascript 复制代码
export function preset(config: Linter.Config | Linter.Config[] = [], {
    prettier: enablePrettier = true,
    vue: enableVue = hasVue
}: EnvOptions = {}) {
  // 配置整合逻辑...
  
  if (enableVue) {
      // 添加 Vue 配置
  }
  
  // 合并自定义配置...
}

其他...

实践应用

代码写好了,测试环节不能少,起码要意思意思。我们直接在当前工程应用,毕竟本项目也要注意代码质量。

本文开头 「工程初始化 」部分留了个尾巴,没创建 ESLint 配置文件,现在来完成它。

两步搞定 ESLint 配置:

  1. 根目录下新增 eslint-config.js
javascript 复制代码
touch eslint-config.js
  1. eslint-config.js 写入以下代码:
javascript 复制代码
import { preset } from './dist/index.js'

export default preset()

./dist/index.js 是编译后的 js 文件。

OK,ESLint 配置搞定,就这么简单。

配置生效的前提需要确保相关依赖已全部安装,如 eslintprettier 等,安装过程就不赘述了,点击查看官网即可。

src/index.ts 写一点不符合规则的代码,比如:

javascript 复制代码
if (a == 0) {
    debugger
}

此时会发现,VSCode 标记了不合格的代码,鼠标放到问题代码上,会提示不满足的规则配置。

结语

本文重点介绍了 ESLint 预置函数工具的开发过程,包括基础的设计思路,简单的配置整合及粗略的应用演示,旨在帮助同学们加深对于 ESLint 预置函数这东西的了解和应用。希望对您有所帮助。相关代码将上传至 GitHub,欢迎 star

如您对文章内容有任何疑问或想深入讨论,欢迎评论区留下您的问题和见解。

技术简而不凡,创新生生不息。我是 嘟老板,咱们下期再会。


往期推荐

相关推荐
FIRE31 分钟前
uniapp小程序分享使用canvas自定义绘制 vue3
前端·小程序·uni-app
四喜花露水31 分钟前
vue elementui el-dropdown-item设置@click无效的解决方案
前端·vue.js·elementui
jokerest1231 小时前
web——sqliabs靶场——第五关——报错注入和布尔盲注
前端
谢尔登1 小时前
前端开发调试之 PC 端调试
开发语言·前端
每天吃饭的羊1 小时前
在循环中只set一次
开发语言·前端·javascript
_默_4 小时前
adminPage-vue3依赖DetailsModule版本说明:V1.2.1——1) - 新增span与labelSpan属性
前端·javascript·vue.js·npm·开源
也无晴也无风雨6 小时前
深入剖析输入URL按下回车,浏览器做了什么
前端·后端·计算机网络
Martin -Tang7 小时前
Vue 3 中,ref 和 reactive的区别
前端·javascript·vue.js
FakeOccupational8 小时前
nodejs 020: React语法规则 props和state
前端·javascript·react.js
放逐者-保持本心,方可放逐8 小时前
react 组件应用
开发语言·前端·javascript·react.js·前端框架