还在复制粘贴 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

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

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


往期推荐

相关推荐
学不会•2 小时前
css数据不固定情况下,循环加不同背景颜色
前端·javascript·html
活宝小娜4 小时前
vue不刷新浏览器更新页面的方法
前端·javascript·vue.js
程序视点4 小时前
【Vue3新工具】Pinia.js:提升开发效率,更轻量、更高效的状态管理方案!
前端·javascript·vue.js·typescript·vue·ecmascript
coldriversnow4 小时前
在Vue中,vue document.onkeydown 无效
前端·javascript·vue.js
我开心就好o4 小时前
uniapp点左上角返回键, 重复来回跳转的问题 解决方案
前端·javascript·uni-app
开心工作室_kaic5 小时前
ssm161基于web的资源共享平台的共享与开发+jsp(论文+源码)_kaic
java·开发语言·前端
刚刚好ā5 小时前
js作用域超全介绍--全局作用域、局部作用、块级作用域
前端·javascript·vue.js·vue
沉默璇年6 小时前
react中useMemo的使用场景
前端·react.js·前端框架
yqcoder6 小时前
reactflow 中 useNodesState 模块作用
开发语言·前端·javascript
2401_882727577 小时前
BY组态-低代码web可视化组件
前端·后端·物联网·低代码·数学建模·前端框架