为什么 eslint-plugin-import 要花 45 秒(以及我们是如何修复的)
发布: (2025年12月31日 GMT+8 13:34)
3 min read
原文: Dev.to
Source: Dev.to
你的 CI 运行缓慢,pre‑commit 钩子超时。开发者为了更快上线而关闭 lint。
罪魁祸首?eslint-plugin-import。
问题
┌─────────────────────────────────────────────────────┐
│ Linting 10,000 files │
├─────────────────────────────────────────────────────┤
│ eslint-plugin-import: 45.0s ███████████████████│
│ eslint-plugin-import-next: 0.4s ▏ │
└─────────────────────────────────────────────────────┘
提升了 100 倍的速度。
// eslint-plugin-import 会从头解析每一个 import
import { Button } from '@company/ui'; // 解析整个包
// 在每一次 lint 时、每个文件、每个 import 都会重新解析。
import/no-cycle 性能杀手
import/no-cycle 规则会构建完整的依赖图。
- 对于 N 个文件、每个文件 M 个 import:
- 时间复杂度:O(N × M²)
- 内存:整个图全部驻留在 RAM 中
结果:在大型 monorepo 中出现内存溢出错误。
真正的 GitHub issue
- “import/no-cycle 占用了 70 % 的 lint 时间”(#2182)
- “检查循环依赖时 OOM”
- “在 monorepo 中 lint 需要几分钟”
每一次 lint 都会重复相同的工作——没有增量分析。
解决方案
我们重新实现了模块解析,使用了带缓存和记忆化的新插件。
功能对比
| 特性 | eslint-plugin-import | eslint-plugin-import-next |
|---|---|---|
| 缓存 | ❌ 无 | ✅ 跨文件共享缓存 |
| 循环检测 | O(N × M²) | O(N) 通过记忆化 |
| TypeScript 解析器 | 🐌 缓慢 | ⚡ 原生 TS 支持 |
| Flat Config 支持 | ⚠️ 部分 | ✅ 原生支持 |
迁移步骤
npm uninstall eslint-plugin-import
npm install --save-dev eslint-plugin-import-next
// eslint.config.js
import importNext from 'eslint-plugin-import-next';
export default [importNext.configs.recommended];
就这么简单——相同的规则,快约 100 倍。
基准测试
# 使用 eslint-plugin-import
time npx eslint --no-cache .
# 使用 eslint-plugin-import-next
time npx eslint --no-cache .
入门
- 📦 npm:
eslint-plugin-import-next - ⭐ 在 GitHub 上给项目加星并自行运行基准测试。
- 🚀 如果你的 CI 很慢,欢迎在评论里留下你的 lint 用时!