Eslint 8.23 Flat Config 新配置迁移升级指南

news2024/9/25 11:18:36

前言

直入正题,eslint 目前为止的配置文件格式( 如 .eslintrc.js ) 存在很多无法避免的历史问题:

  1. 配置格式混乱,层层不明确的继承,不易理解。

  2. 插件配置时不支持实体运用(不能传 function / object ),基于字符串的依赖解析一旦错误,插件将失效。

  3. 依赖关系混乱,继承的配置中,依赖查找经常错位,找不到预期的 eslint-plugin-* / eslint-config-* 等依赖,需要在当前项目重新安装。

等等问题,对于 23 问题我们早期会使用或 fork @rushstack/eslint-patch 来 hack 插件的导入路径解决依赖找不到的问题,但方式十分不优雅。

无论你是否遇到过以上 eslint 的配置问题,在 eslint v8.23 版本正式发布时推出了全新的配置格式 Eslint Flat Config ,这一切问题都将逐步得到解决。

下面我们就旧配置如何迁移升级到新配置,以及迁移的技术细节进行拆解介绍。

前置知识

官方迁移文档

先进行前置知识的学习,官方为我们准备了 3 part 的升级迁移指南:

  • ESLint’s new config system, Part 1: Background

  • ESLint’s new config system, Part 2: Introduction to flat config

  • ESLint’s new config system, Part 3: Developer preview

Flat Config 配置说明文档

Eslint doc :Configuration Files (New)

在阅读过以上内容后,我们针对旧配置升级到新的 Flat Config 新配置进行一个简单 case 的实战。

迁移实战

新旧对比

在官方 3 part 升级文章中的 Backwards compatibility utility 章节,我们得知使用 FlatCompat 可以将旧配置 compat 自动转换到新配置。

我们以此为抓手,细粒度的打印对比新旧配置,观察他们的区别,以此得知迁移升级的方法。

  pnpm add -D @eslint/eslintrc
const { FlatCompat } = require('@eslint/eslintrc')

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

const newConfigs = [
  // >> [ { plugins: { prettier: [Object] } } ]
  compat.config({
    plugins: ['prettier'],
  }),
  // >> []
  compat.config({
    root: true
  }),
  // >> [ { languageOptions: { parser: [Object] } } ]
  compat.config({
    parser: '@typescript-eslint/parser'
  }),
  // >> [ { ignores: [ [Function (anonymous)] ] } ]
  compat.config({
    ignorePatterns: ['/dist', '/node_modules']
  }),
  // >> [ { rules: { ... } }, { rules: { ... }, plugins: { prettier: [Object] } } ]
  compat.config({
    extends: ['plugin:prettier/recommended']
  }),
  // [ { languageOptions: { globals: [Object], parserOptions: [Object] } } ]
  compat.config({
    env: {
      node: true
    },
  }),
]

newConfigs.forEach((config) => {
  console.log(config)
})

基于以上对比得到的结果,同时参考官方 Flat Config 新配置的 文档 ,我们得知如下结论:

旧配置项发生的变化
plugins插件现在的配置格式是一个 Record<string, Object> ,即可以传递实体了
root现在新配置没有了,不需要了
parser现在挪到了 languageOptions.parser
ignorePatterns忽略文件的 compat 结果默认是一个函数,我们推测他是一个匹配逻辑,但是通过 官方文档 我们得知正确的写法应该是 ignores: ['**/node_modules/**']
extends我们 compat 得到了一个复杂的对象,由于 Flat Config 新配置抛弃了 extends ,通过阅读 eslint-plugin-prettier 的源码,我们得知转换后的配置即为将 eslint-plugin-prettier 的所有零散配置项组装起来的结果,在下文中我们将继续拆解
env参阅官方升级文档 Goodbye environments, hello globals 章节,可得知新的配置写法需要基于 globals 包进行引用

注:关于更多配置,请自行对比,并参考 Flat Config 新配置的 官方文档 ,最终决定你的迁移结果应该如何编写,切勿直接使用 compat 后的结果!

extends 转换拆解

通过 compat 对比我们可以得到几乎全部旧配置升级新配置的结果,此处比较复杂的是 extends 的转换,我们进一步进行拆解。

如下是 eslint-plugin-prettier 的源码主要部分:

module.exports = {
  configs: {
    recommended: {
      extends: ['prettier'],
      plugins: ['prettier'],
      rules: {
        'prettier/prettier': 'error',
        'arrow-body-style': 'off',
        'prefer-arrow-callback': 'off',
      },
    },
  },
  rules: {
    prettier: {
      // ...
    },
  },
}

我们使用的是 plugin:prettier/recommended ,就是 configs.recommended 部分,拆解后的结果:

可以看到正如我们上面所说,extends 的内容只是被每一项零散的拿到了新配置里,仅此而已。

实战演练

下面我们进行一个真实的实战 case ,旧配置如下:

module.exports = {
  // 🎉 新版配置不再需要了
  root: true,
  // 🟢 我们得知新的 parser 应该写在 languageOptions.parser
  parser: '@typescript-eslint/parser',
  // 🟢 官方文档告诉我们需要从 globals 这个包里面引用
  env: {
    es2021: true,
    browser: true,
    node: true,
    commonjs: true,
  },
  // 🟡 经过 extends 的拆解,我们得知要手动把相关零散配置项拼凑起来
  extends: ['plugin:prettier/recommended'],
  // 🟢 我们得知应该写在新配置的 plugins 对象里
  plugins: ['prettier'],
  // 🎉 该配置在 Flat Config 中为默认值,可以不要了
  parserOptions: {
    sourceType: 'module',
  },
  rules: {
    // 🟡 一些自己的自定义 rules
    'prettier/prettier': 'warn',
    '@typescript-eslint/no-unused-vars': 'off',
    'no-unused-vars': 'off',
  },
  // 🟢 我们参考官方文档,得知可以写成 **/node_modules/**
  ignorePatterns: ['/dist', '/node_modules'],
}

最终得到 Flat Config 新配置如下,我们关注以 🟡 标识的部分如何进入新配置 :

const globals = require('globals')

const eslintConfigPrettier = require.resolve('eslint-config-prettier')
const configPrettier = require(eslintConfigPrettier)

const eslintPluginPrettier = require.resolve('eslint-plugin-prettier')
const pluginPrettier = require(eslintPluginPrettier)

const parser = require.resolve('@typescript-eslint/parser')
const parserInstance = require(parser)

module.exports = [
  {
    files: ['**/*.ts?(x)'],
    ignores: ['**/dist/**', '**/node_modules/**'],
    languageOptions: {
      parser: parserInstance,
      globals: {
        ...globals.commonjs,
        ...globals.browser,
        ...globals.es2021,
        ...globals.node,
      },
    },
    // 🟡 recommended.plugins: ['prettier']
    plugins: {
      prettier: pluginPrettier,
    },
    rules: {
      // 🟡 recommended.extends: ['prettier']
      ...configPrettier.rules,
      // 🟡 recommended.rules: { ... }
      ...pluginPrettier.configs.recommended.rules,

      // 🟡 一些自己的自定义 rules
      'prettier/prettier': 'warn',
      '@typescript-eslint/no-unused-vars': 'off',
      'no-unused-vars': 'off',
    },
  }
]

到此为止,我们已经顺利完成 Flat Config 新配置的迁移升级。

此处需要注意的是新配置是 数组 的导出形式,不再是对象:

  • 设定为数组是为分类配置准备的,比如针对 files: ['**/*.ts?(x)'] TypeScript 文件一个配置对象,针对 files: ['**/*.js?(x)'] JavaScript 文件一个配置对象,也可以不包含 files ,但越往后的配置对象在合并过程中优先级越高(如上文中 compat 转换 extends 的结果就是两个对象)。

  • files 匹配冲突时(比如一个文件匹配了多个配置对象),将以最后一个匹配对象为准,其余选项合并,请参见:Cascading configuration objects 。

Vscode 自动格式化

在 vscode 进行 eslint cmd/ctrl + s 保存自动格式化必须依赖 vscode-eslint 插件。

开启 Flat Config 的自动格式化需要 eslint 插件版本 >= 2.3.0 ,若无法更新到 2.3.0 ,可尝试切换到预览版。同时,由于目前 Flat Config 还处于实验性阶段,需要新增如下配置开启:

// settings.json
{
  "eslint.experimental.useFlatConfig": true,
}

满足 eslint 插件版本 >= 2.3.0 ,并开启配置后,便可在项目中使用 eslint.config.js 与 Flat Config 新配置保存自动格式化了!

总结

由于新配置支持将 eslint-plugin-* 经过 require 后以实体的方式使用,所以原来的字符串会导致依赖解析错误的问题迎刃而解了。

另外,新的 Flat Config 配置的配置文件名是 eslint.config.js 而不是 .eslintrc.js ,需要多加注意。

关于更多变化和配置内容,请参考 官方文档 。

以上。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/97760.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

学完框架后的反思—为什么要使用框架?

学习前端也有一定的时间了,最近在网上看到了一个问题让我反思了很久——为什么要使用前端框架? 我发现自己当初学习框架时并没有想那么多,只是看中了其在业界企业的应用,大部分公司开发页面基本上都是使用框架进行开发的,而最为被大厂广泛接受的就是 React 框架,所以我当…

二棕榈酰磷酯酰乙醇胺-聚乙二醇-叠氮 DPPE-PEG-N3简介,可用于药物传递、基因转染和生物分子修饰。

二棕榈酰磷酯酰乙醇胺-聚乙二醇-叠氮 DPPE-PEG-N3 中文名称&#xff1a;二棕榈酰磷酯酰乙醇胺-聚乙二醇-叠氮基 英文名称&#xff1a;DPPE-PEG-N3 英文别名&#xff1a; 1,2-dipalmitoyl-sn-glycero-3-phosphoethanolamine-PEG-Azide 分子量&#xff08;PEG&#xff09;&a…

Linux——任务调度

at定时任务 基本介绍 at命令是一次性定时计划任务&#xff0c;at地守护线程atd会以后台模式运行&#xff0c;检查作业队列来运行默认情况下&#xff0c;atd守护进程没60秒检查作业队列&#xff0c;有作业时&#xff0c;会检查作业运行时间&#xff0c;如果时间于当前时间匹配…

Dubbo 1 分布式系统中的相关概念 1.2 集群和 分布式

Dubbo 【黑马程序员Dubbo快速入门&#xff0c;Java分布式框架dubbo教程】 1 分布式系统中的相关概念 文章目录Dubbo1 分布式系统中的相关概念1.2 集群和 分布式1.2.1 集群和分布式1.2.2 集群和分布式 【互联网 中】1.2 集群和 分布式 1.2.1 集群和分布式 集群&#xff1a;很…

使用synchornized和ReentrantLock来解决并发错误

文章目录什么是并发错误&#xff1f;并发错误是如何产生的&#xff1f;演示并发错误如何解决并发错误使用synchornized解决并发错误使用ReentrantLock解决并发错误什么是并发错误&#xff1f; 多个线程共享操作同一个对象的时候&#xff0c;线程体当中连续的多行操作未必能够连…

下个文档还要马内?还好我会Python,教大家来一手强制复制粘贴

前因后果 公司有人阳了&#xff0c;今天在家上班&#xff0c;突然小姨子就问我有没有baidu文库会员&#xff0c;想下载点东西&#xff0c;我心想这还要会员&#xff1f;用Python不是分分钟的事情&#xff01; 然后我非常自信的告诉她不用会员随便下载&#xff0c;结果她顺势想…

10两级电力市场环境下计及风险的省间交易商最优购电模型

参考文章&#xff1a; 两级电力市场环境下计及风险的省间交易商最优购电模型—郭立邦&#xff08;电网技术2019&#xff09; 主要内容&#xff1a; 为进一步推动电力市场建设&#xff0c;促进电力资源大范围优化配置&#xff0c;我国正逐步建成包含省间与省内电力交易的两级…

齿轮魔方、五阶齿轮魔方

齿轮魔方 1&#xff0c;魔方三要素 &#xff08;1&#xff09;组成部件 部件和三阶魔方完全对应&#xff0c;但每个棱块的朝向不止2种&#xff0c;而是有6种。 &#xff08;2&#xff09;可执行操作 只有3种操作&#xff0c;即上下层同时旋转180度、左右180度、前后180度。…

一文助你快速理解Cookie,Session,Token的区别

目录 一、Cookie简介 1.1.cookie定义 1.2.cookie鉴权原理 1.3.cookie的分类 二、Session简介 2.1.session的定义 2.2.session会话机制 2.3.Session 的缺点 三、cookie与session区别 3.1.存储位置 3.2.安全性 3.3.占用服务器资源 3.4.存储空间 3.5.存储类型 3.6.…

编程入门宝典,刚开始学习编程新手必看的5点建议!

编程就像围城&#xff0c;城里的人想出去&#xff0c;城外的人想进来。 对于零基础的小白&#xff0c;要杀入代码的战场需要准备好哪些东西呢?最帅的萌宝在此给大家分享5点建议。 1、选择编程语言 编程首要还是选择好适合自己的语言。 编程语言有&#xff1a;C/C、java、VB、P…

零基础学Python:编程规范

1. 注释 python注释也有自己的规范&#xff0c;在文章中会介绍到。注释可以起到一个备注的作用&#xff0c;团队合作的时候&#xff0c;个人编写的代码经常会被多人调用&#xff0c;为了让别人能更容易理解代码的通途&#xff0c;使用注释是非常有效的。 在说规范之前我们有必…

微服务综合部署——SpringBoot项目制作Docker镜像注册在Zookeeper并利用K8S技术部署

一、如果你要从头开发一个基于微服务架构的项目&#xff0c;项目中的服务最终要部署在k8s管理的镜像环境中&#xff0c;你认为应如何创建项目&#xff1f;与本次实验过程相比&#xff0c;哪些改进可以让开发更加合理高效&#xff1f; 第一步&#xff1a;搭建项目并制作合适的j…

回溯算法总结

目录介绍伪代码例题&#xff1a;解释&#xff1a;回溯算法中的优化去重伪代码剪枝常见题型子集例题全排列例题参考资料介绍 递归(DFS)是一个劲的往某一个方向搜索&#xff0c;而回溯算法建立在 DFS 基础之上的&#xff0c;但不同的是在搜索过程中&#xff0c;达到结束条件后&am…

SAP ABAP 扫描 ABAP 源代码(RS_ABAP_SOURCE_SCAN)

SAP ABAP 扫描 ABAP 源代码&#xff08;RS_ABAP_SOURCE_SCAN&#xff09; 引言&#xff1a; RS_ABAP_SOURCE_SCAN 是一个 SAP 标准 ABAP 报表程序&#xff0c;通过输入字符串文本&#xff0c;扫描 ABAP 源代码&#xff0c;列示查找字符串在 ABAP 源代码中出现的位置清单。本文…

20行python代码的入门级小游戏

0、背景&#xff1a; 作为一个python小白&#xff0c;今天从菜鸟教程上看了一些python的教程&#xff0c;看到了python的一些语法&#xff0c;对比起来&#xff08;有其他语言功底&#xff09;&#xff0c;感觉还是非常有趣&#xff0c;就随手添了一点内容&#xff0c;改了一个…

【车载开发系列】CAN总线通信---总线报文格式

【车载开发系列】CAN总线通信—总线报文格式 CAN总线通信---总线报文格式【车载开发系列】CAN总线通信---总线报文格式一.什么是ISO15765二.ISO15765的目的三.单帧传输的概念四.多帧传输的概念五.诊断报文格式1&#xff09;首帧FF2&#xff09;连续帧CF3&#xff09;流控帧FC4&…

【JavaScript】for循环

文章目录for循环案例1&#xff1a;两数相加案例2&#xff1a;绘制九九乘法表案例3&#xff1a;水仙花数案例4&#xff1a;绘制菱形案例5&#xff1a;计算表达式结果break和continue图片切换效果案例&#xff08;轮播图结构&#xff09;一、JavaScript代码二、HTML结构和CSS样式…

基于java+springmvc+mybatis+vue+mysql的演出道具租赁管理系统

项目介绍 前端页面&#xff1a; 功能&#xff1a;首页、道具出租、公告资讯、个人中心、后台管理 管理员后台页面&#xff1a; 功能&#xff1a;首页、个人中心、用户管理、商家管理、道具类型管理、道具出租管理、租赁订单管理、道具归还管理、我的收藏管理、系统管理 用户…

密西根大学张阳实验室郑伟博士在CASP15蛋白质结构预测大赛中斩获多项冠军

简报&#xff1a;在有着蛋白质结构预测领域奥林匹克竞赛之称的最新一届CASP比赛中&#xff08;CASP15&#xff09;&#xff0c;密西根大学张阳教授和Peter Freddolino教授实验室的郑伟博士在多个比赛项目中获得冠军。其中D-I-TASSER算法&#xff08;参赛名&#xff1a;“UM-TBM…

nodejs银行取号系统vue

目 录 1绪论 1 1.1项目研究的背景 1 1.2开发意义 1 1.3项目研究现状及内容 5 1.4论文结构 5 2开发技术介绍 7 2.1 B/S架构 7 2.2 MySQL 介绍 7 2.3 MySQL环境配置 7 3系统分析 9 3.1可行性分析 9 3.1.1技术可行性 9 3.1.2经济可行性 …