惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
人人都是产品经理
人人都是产品经理
Cisco Talos Blog
Cisco Talos Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
V
V2EX
博客园 - 三生石上(FineUI控件)
Martin Fowler
Martin Fowler
WordPress大学
WordPress大学
D
Docker
S
SegmentFault 最新的问题
博客园 - 聂微东
美团技术团队
Apple Machine Learning Research
Apple Machine Learning Research
月光博客
月光博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Last Week in AI
Last Week in AI
M
MIT News - Artificial intelligence
F
Fortinet All Blogs
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
The GitHub Blog
The GitHub Blog
GbyAI
GbyAI
L
LangChain Blog
Vercel News
Vercel News
博客园 - 叶小钗
MongoDB | Blog
MongoDB | Blog
Stack Overflow Blog
Stack Overflow Blog
H
Help Net Security
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
The Cloudflare Blog
Engineering at Meta
Engineering at Meta
T
Threat Research - Cisco Blogs
T
Threatpost
Scott Helme
Scott Helme
T
Tailwind CSS Blog
Latest news
Latest news
Stack Overflow Blog
Stack Overflow Blog
Blog — PlanetScale
Blog — PlanetScale
The Register - Security
The Register - Security
罗磊的独立博客
P
Proofpoint News Feed
腾讯CDC
S
Schneier on Security
雷峰网
雷峰网
A
About on SuperTechFans
T
Tenable Blog
F
Full Disclosure
Cyberwarzone
Cyberwarzone
博客园_首页
有赞技术团队
有赞技术团队
K
Kaspersky official blog

文章列表

win or mac clash 无 TUN 让 Antigravity、Chrome 强制 proxy(解决 Antigravity 无法加载选择 model、自动更新无法登录、跳转) 【大杂烩】在 pnpm 中直接修改 node_modules(.pnpm) 中的依赖项,项目中持久化 - pnpm 中的依赖处理、幽灵依赖、寻址规则等 在 html 中直接使用 Esm、Jsx 脚本快速调试和使用 React@19 和 Vue@3 源码,解决 React19 UMD 构建等问题 一键在本地批量检测并升级更新 package.json 中的模块依赖,ncu(npm-check-updates)在 npm、pnpm 或 workspace 项目中的使用教程 解决 Mac Docker Desktop 中启动出现的问题合集 通过阿里云、腾讯云无服务器搭建自定义的企业域名邮箱,实现在 QQ邮箱 收发等功能(附腾讯 SMTP 和 IMAP) 解决使用代理(clash 等)进行 SSH 连接(如 Github ssh key clone/push)出现 kex_exchange_identification 错误 静态文件资源 cdnjs, jsdelivr 抖音字节国内快速 CDN 镜像推荐【2025】- 仍在使用 bootcdn 和 staticfile CDN 请注意验证资源的完整性(SRI) pnpm monorepo 中管理依赖的最佳实践,与 Catalogs(目录)协议的使用(monorepo 中统一版本管理) Web 安全中的 Secure Contexts(安全上下文)- 解决在本地中使用 clipboard 或 Crypto 等 API 限制或关闭上下文限制 使用 serve 配合 openssl 或 mkcert 创建本地自签名可信任的证书 - 创建本地 TLS\SSL https 协议服务 利用 Github Actions 和 Acme 自动申请、更新和部署至阿里云、腾讯云 CDN Lets Encrypt SSl\TLS ECC RSA 双证书 【CSS】解决在 flex 容器中使用 align-content 或 justify-content 属性 center 居中时的溢出滚动和截断问题 - 理解 safe 关键字 在线工具 - 一键获取下载抖音无水印视频、抖音去水印解析工具、下载抖音无水印高清图集【2025 最新】 【React Router】v6 data router 在非组件(或工具方法)中如何优雅的跳转路由 【React】为什么路由跳转时页面滚动高度不会被重置(保留上个页面高度)?理解 history scrollRestoration 的场景与使用,以及如何使用 React Router 重置和跳转前保留滚动高度 【React】在本地 Html 中快速 debug(调试)React 源码 【React】结合源码和 EventLoop 分析 - 为什么 useLayoutEffect 会阻止 DOM 重绘(而 useEffect 闪烁)?为什么其内部 useState 会“同步”执行? React Compiler - 解放在函数中编程时的性能焦虑(React Conf 2024)附 Next 在线演示 在 github actions 中获取时间,并转换为中国标准时间(中国时区) 【npm】npm ci - npm clean install,在 CI、CD 中保持构建的一致性和可重复性 使用 Spicetify 自定义 Spotify - 歌词翻译、全屏展示、主题替换 在 node 中快速代理请求(Proxy),解决跨域或请求转发问题 - http-proxy-middleware 修改请求体和返回 在 Hexo 中使用 AI(Gemini、deepseek、Azure)生成文章摘要,支持自定义模板。hexo-ai-summaries 插件文档(默认适配主题 Butterfly) 解决在 webstorm 或 idea 等 jetbrains 工具中遇到 Git 无法 force push,或 force push 灰色禁用无法点击(protected branches) hexo-seo-submit,Hexo 博客 SEO 优化插件 - 每日定时自动或手动提交链接至百度、Bing、Google,支持 Github Actions 和 Coding Jenkins 等CI(Hexo 插件编写) 一文吃透 pnpm 如何使用 workspace 构建 monorepo,与 npm、yarn 的用法对比(pnpm 9.x 内部安装依赖问题 link-workspace-packages) 【Node】Corepack - 解决 pnpm 或 yarn 的多版本管理、解决本地版本与 packageManager 中的版本一致性问题 解决 npm、cnpm 或 pnpm install 遇到 certificate has expired (证书已过期) npm、yarn、pnpm 设置最新国内镜像源(附官方镜像源和最新阿里源),以及 nrm 的使用教程【2025】 解决从 docker desktop 内镜像 linux 创建的容器,启动就停止、无法启动等问题(无进程容器) docker(docker desktop)中设置国内镜像源加速(阿里云、中科大),以及代理和容器代理设置,解决桌面端无法登陆就退出问题 【CSS】解决外边距重叠(重合)引起的 margin 垂直方向(top、bottom)不生效,无作用的问题 【CSS】CSS-Nesting:CSS 嵌套写法 —— 有望替代 less sass 的原生嵌套 【CSS】解决移动端(高清方案)下在谷歌浏览器中出现 字体大小布局异常,和设置的 font-size 不符(Text Autosizer、Font Boosting) 【CSS】主流 UI 库都在用的逻辑伪类选择器 not、where、is、has 【windows 11】使用 wePe 纯净 制作pe启动盘 安装\重装\升级 windows 11(windows 10)详细教程,附 windows 11 跳过联网、分区等教程 【webpack】Externals(外部扩展)浅析 - webpack 5 【Windows】一句话(一键、一分钟、一段代码)清除 Windows 11(10) 快捷方式角标(小箭头) 【Git】cherry-pick 使用场景介绍,如何在 WebStorm 中使用 cherry-pick;(从分支中提取 commit 功能) 【message-channel】了解频繁出现在框架的 Message Channel,及在事件循环(Event Loop)中的表现 【web-worker】浅析 useWorker 库如何只需函数方法即可在 worker 内运行;如何区分 Web Socket、Web Worker和Service Worker? 【React】理解学习 React 17中的批处理 与 18 批处理 为何用谷歌(Chrome)浏览器下载PDF时有时预览有时下载? 【less】Parent Selectors & 和 &&(多个父选择器的用法及回顾) 【React Router】在非组件(或工具方法)中如何优雅的跳转路由 - 理解 HashHistory 和 BrowserHistory 处理谷歌浏览器(google Chrome)https 站点将 http 资源自动转成 https - 附全站资源强制转 https vscode 国内直链接下载,提升(加速)下载速度 【css-tricks】从 flex 子元素超出父级(容器)宽度,探其原理 flex:1 时 width 的作用 linux,mac 终端(Terminal)上使用代理(http/https/socks5)提升速度,给 git 一键设置代理提升速度 修复 Win 11或10 Xbox Game Bar 录屏截屏打不开灰色等 ios,Windows 网页皆可平滑、惯性滚动(Smooth-scroll.js)- 博客、网站、web、JavaScript 【2022年】apple 苹果(ios)注册美服区(日区)ID教程(附免税地区及身份信息生成器)-时效:2022年2月 javaScript 文件上传 - input 上传 和 webAPi 上传(解决上传对 input 的依赖) Git 解决 pull 操作出现:不建议在没有为偏离分支指定合并策略时执行pull操作 一行代码解决谷歌浏览器出现:"您的连接不是私密连接" Nginx 中使用 cookie 灰度或分流 css 指定方向模糊 - 鸿蒙开机效果(animation 事件)
eslint 9.x 升级或使用指南,eslint.config.js 配置,包含 react、typescript、prettier 等常用配置升级迁移
kshao · 2024-06-22 · via

前言

距离 9.0 版本发布已经两个多月了,主流框架或者工具基本都已经适配,一起来体验新版本吧~

Breaking Changes

不再支持 Node v19.xLTS18.18.0 版本

名词解释:

  • LTSLong-Term SupportNode 的长期支持版本(维护和安全更新),通常每隔两年发布一次,特点是稳定和可靠性,建议生产使用。
  • LTScurrent):是 Node 的最新开发版本,通常每隔几个月发布一次,包含最新的功能和实验特性,缺乏稳定性。

Flat 配置文件取代 eslintrc 配置

新版 eslint.config.{js,cjs,mjs} 已经取代了 .eslintrc 配置文件,如果你是“怀旧派”可以将你的环境变量 ESLINT_USE_FLAT_CONFIG 设为 false,但 Implement Flat Config 中已经明确表示在下一阶段(10.x)中会移除对旧配置文件的兼容。

eslint.config.js

eslint 9 中支持 Common JSESM 两种配置文件格式,推荐使用 ESM

eslint.config.js

const eslint = require('@eslint/eslint'); module.exports = [ eslint.configs.recommended, // your config { name: 'custom-lint-config', files: ['*.js'], rules: { 'no-undef': 0, }, }, ];

eslint.config.mjs

import eslint from '@eslint/eslint'; export default [ eslint.configs.recommended, // your config { name: 'custom-lint-config', files: ['*.js'], rules: { 'no-undef': 0, }, }, ];

新 Rule:no-useless-assignment

no-useless-assignment 规则用于检测无用的赋值操作,例如 let id = 1234;1234 没有被使用。

let id = 1234; // 1234 is never used
id = calculateId();

flat config 中,不向 CLI 中传入任何参数时,eslint 会默认对当前目录进行 lint 检查,如:npx eslint

npx eslint

基本使用

使用 eslint 推荐配置来初始化 lint 规则。在 flat config 中,配置顺序也尤为重要,若规则相同,后面的配置会覆盖前面的配置。 或者定义全局生效的 rulesignores, 来覆盖。

pnpm add eslint @eslint/js -D

若你的配置对象的 key 仅有 filesignores 时,那么这些规则将全局生效。

eslint.config.mjs

import eslint from '@eslint/js'; const flatConfig = [ { name: 'some global cofig here', languageOptions: { globals: { // ... }, }, rules: { 'no-unused-vars': 0, }, }, { name: 'some user comfig here', files: ['src/**.{ts, tsx}'], rules: { // ... }, }, // global files { files: ['src/**.{ts, tsx}'], }, // global ignores { ignores: ['dist'], }, ]; export default [ eslint.configs.recommended, // ... your config ...flatConfig, ];

相关配置迁移

本文档包含 typescript、react、prettier、babel 等常用配置的升级迁移,更多配置请查看官方文档的迁移指南或查看仓库说明。

typescript-eslint

typescript-eslint 提供了在 flat config 中使用推荐配置来帮你快速开箱,该推荐配置默认包含 @typescript-eslint/parser@typescript-eslint/eslint-plugin

使用 typescript-eslint 推荐配置

若需要覆盖 rules,需定义 global rules

https://typescript-eslint.io/getting-started/ > https://github.com/typescript-eslint/typescript-eslint

pnpm add typescript typescript-eslint -D

eslint.config.mjs

import eslint from '@eslint/js'; import tsEslint from 'typescript-eslint'; const flatConfig = [ { name: 'some comfig here', rules: { // ... }, }, // global rules { rules: { '@typescript-eslint/ban-types': 2, }, }, ]; export default tsEslint.config( eslint.configs.recommended, ...flatConfig, ...tsEslint.configs.recommended, );

使用 @typescript-eslint/parser 自定义

pnpm add @typescript-eslint/eslint-plugin @typescript-eslint/parser -D

eslint.config.mjs

import eslint from '@eslint/js'; import tsEslintPlugin from '@typescript-eslint/eslint-plugin'; import tsEslintParser from '@typescript-eslint/parser'; const flatConfig = [ // .... ]; const customTsFlatConfig = [ { // any string name: 'typescript-eslint/base', languageOptions: { parser: tsEslintParser, sourceType: 'module', }, files: ['**/*.{ts,tsx}'], // custom rules or use recommended rules rules: { ...tsEslintPlugin.configs.recommended.rules, '@typescript-eslint/ban-types': 2, '@typescript-eslint/no-confusing-non-null-assertion': 2, }, plugins: { // ts 语法特有的规则,例如泛型 '@typescript-eslint': tsEslintPlugin, }, }, ]; export default [eslint.configs.recommended, ...flatConfig, ...customTsFlatConfig];

@babel/eslint-parser

@babel/eslint-parserbabel 官方提供的 parser,支持 babel 的所有语法特性,包括 jsxflowtypescript 等。大部分情况下,你可能只需要 @typescript-eslint/parser 即可

pnpm add @babel/eslint-parser @babel/preset-env -D

配置时请注意多个 parser 之间顺序。

eslint.config.mjs

import eslint from '@eslint/js'; import tsEslintPlugin from '@typescript-eslint/eslint-plugin'; import tsEslintParser from '@typescript-eslint/parser'; import babelParser from '@babel/eslint-parser'; const flatConfig = [ // .... ]; const customTsFlatConfig = [ // ... ]; const bableConfig = { name: 'babel-parser', languageOptions: { parser: babelParser, parserOptions: { babelOptions: { babelrc: false, configFile: false, browserslistConfigFile: false, presets: ['@babel/preset-env'], }, requireConfigFile: false, }, }, }; export default [eslint.configs.recommended, ...flatConfig, bableConfig, ...customTsFlatConfig];

eslint-plugin-reacteslint-plugin-react-hooks

同样,eslint-plugin-react 也提供了 flat config 的推荐配置,你可以直接使用它们。

https://github.com/jsx-eslint/eslint-plugin-react > https://github.com/facebook/react/tree/main/packages/eslint-plugin-react-hooks

pnpm add eslint-plugin-react eslint-plugin-react-hooks globals -D

eslint.config.mjs

import eslint from '@eslint/js'; import tsEslintPlugin from '@typescript-eslint/eslint-plugin'; import tsEslintParser from '@typescript-eslint/parser'; import babelParser from '@babel/eslint-parser'; import reactPlugin from 'eslint-plugin-react'; import reactHooksPlugin from 'eslint-plugin-react-hooks'; import globals from 'globals'; const flatConfig = [ // .... ]; const customTsFlatConfig = [ // ... ]; const bableConfig = { // ... }; const reactConfig = { name: 'react-eslint', files: ['**/*.{js,jsx,mjs,cjs,ts,tsx}'], plugins: { react: reactPlugin, 'react-hooks': reactHooksPlugin, }, languageOptions: { ...reactPlugin.configs.recommended.languageOptions, // parserOptions: { // ecmaFeatures: { // jsx: true, // }, // }, globals: { ...globals.es2022, ...globals.browser, ...globals.node, }, }, rules: { ...reactPlugin.configs.recommended.rules, 'react/react-in-jsx-scope': 0, }, settings: { react: { // 需要显示安装 react version: 'detect', }, }, }; export default [ eslint.configs.recommended, ...flatConfig, bableConfig, reactConfig, ...customTsFlatConfig, ];

或者直接使用 推荐配置

eslint.config.mjs

import reactPlugin from 'eslint-plugin-react'; export default [reactPlugin.configs.recommended];

eslint-plugin-prettier

eslint-plugin-prettier 用于将 prettier 的格式化规则转换为 eslint 的规则,以便在 eslint 中使用 prettier 的格式化规则。

https://github.com/prettier/eslint-plugin-prettier/tree/master

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

eslint.config.mjs

import eslint from '@eslint/js'; import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended'; export default [eslint.configs.recommended, eslintPluginPrettierRecommended];

ESLint Config Inspector

使用 @eslint/config-inspector 来检测配置的规则或 parser 是否命中。matchconfig name 为每项 flat configname

[{"url":"https://static.ksh7.com/post/eslint-update-9/0085UwQ9gy1hqyany1mx0j31dm11a7d9.webp?imageMogr2/thumbnail/!50p","dataset":{"originPic":"https://static.ksh7.com/post/eslint-update-9/0085UwQ9gy1hqyany1mx0j31dm11a7d9.webp","thumbnail":""}},{"url":"https://static.ksh7.com/post/eslint-update-9/0085UwQ9gy1hqyanyktc3j31ks17kgx5.webp?imageMogr2/thumbnail/!50p","dataset":{"originPic":"https://static.ksh7.com/post/eslint-update-9/0085UwQ9gy1hqyanyktc3j31ks17kgx5.webp","thumbnail":""}}]

总结

配置汇总

eslint.config.mjs

import eslint from '@eslint/js'; import tsEslintPlugin from '@typescript-eslint/eslint-plugin'; import tsEslintParser from '@typescript-eslint/parser'; import tsEslint from 'typescript-eslint'; import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended'; import reactPlugin from 'eslint-plugin-react'; import reactHooksPlugin from 'eslint-plugin-react-hooks'; import babelParser from '@babel/eslint-parser'; import globals from 'globals'; const customTsFlatConfig = [ { name: 'typescript-eslint/base', languageOptions: { parser: tsEslintParser, sourceType: 'module', }, files: ['**/*.{ts,tsx}'], rules: { ...tsEslintPlugin.configs.recommended.rules, '@typescript-eslint/ban-types': 2, '@typescript-eslint/no-confusing-non-null-assertion': 2, }, plugins: { // ts 语法特有的规则,例如泛型 '@typescript-eslint': tsEslintPlugin, }, }, ]; const flatConfig = [ // 全局生效的规则 { name: 'global config', languageOptions: { globals: { ...globals.es2022, ...globals.browser, ...globals.node, }, parserOptions: { warnOnUnsupportedTypeScriptVersion: false, }, }, rules: { 'no-dupe-class-members': 0, 'no-redeclare': 0, 'no-undef': 0, 'no-unused-vars': 0, }, }, { name: 'react-eslint', files: ['**/*.{js,jsx,mjs,cjs,ts,tsx}'], plugins: { react: reactPlugin, 'react-hooks': reactHooksPlugin, }, languageOptions: { ...reactPlugin.configs.recommended.languageOptions, // parserOptions: { // ecmaFeatures: { // jsx: true, // }, // }, }, rules: { ...reactPlugin.configs.recommended.rules, 'react/react-in-jsx-scope': 0, }, settings: { react: { // 需要显示安装 react version: 'detect', }, }, }, { name: 'babel-parser', languageOptions: { parser: babelParser, parserOptions: { babelOptions: { babelrc: false, configFile: false, browserslistConfigFile: false, presets: ['@babel/preset-env'], }, requireConfigFile: false, }, }, }, { ignores: ['dist'], } ]; // export default tsEslint.config( // eslint.configs.recommended, // eslintPluginPrettierRecommended, // ...flatConfig, // ...tsEslint.configs.recommended, // ); export default [ eslint.configs.recommended, eslintPluginPrettierRecommended, ...flatConfig, ...customTsFlatConfig, ];