慣性聚合 高效追讀感興趣之博客、新聞、科技資訊
閱原文 以慣性聚合開啟

推薦訂閱源

博客园 - 司徒正美
V
V2EX
T
Tailwind CSS Blog
有赞技术团队
有赞技术团队
aimingoo的专栏
aimingoo的专栏
Apple Machine Learning Research
Apple Machine Learning Research
IT之家
IT之家
Blog — PlanetScale
Blog — PlanetScale
A
About on SuperTechFans
月光博客
月光博客
T
The Blog of Author Tim Ferriss
宝玉的分享
宝玉的分享
Martin Fowler
Martin Fowler
博客园 - 聂微东
The GitHub Blog
The GitHub Blog
V
Visual Studio Blog
WordPress大学
WordPress大学
酷 壳 – CoolShell
酷 壳 – CoolShell
Engineering at Meta
Engineering at Meta
GbyAI
GbyAI

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python)
无环之术于next.js(及他物所言之妄)无所察
Ofri Peretz · 2026-05-24 · via DEV Community

import-next/no-cycleeslint-plugin-import/no-cycle及oxlint所译之Rust版于next.js(星标131K,源文件14,556)为衡。二ESLint插件意同:0周而复始。oxlint异议:17周而复始

吾等信从众议。复以吾之规于同仓之33文件小集(packages/next/src/client/components/router-reducer/**)试之。其得立时5+ 轮。

规同也,配置同也,文件同也,范围异也,应答亦异也。

谬误藏于缓存之层,深六十行——此故广范围寂然无声。

隐谬之设

凡检测循环之术,形皆同也:

  1. 于检错之域内,每文件__JHSNS_SEG_96313024_15__F。
  2. 于其导入图行深度有界之深度优先遍历
  3. 若深度优先遍历复归F,则得循环
  4. 否则,F为无环,当记之,以备后用

第四步,方见缓存之效。有N文件,平均图深为D,则愚直之循环检测为O(N²·D)。有"已知无环"之缓存,则重访为O(1)。于实代码库,缓存命中率逾70%——无之,则此规过缓,难行于持续集成。

缓存之形:

interface FileSystemCache {
  // ...
  nonCyclicFiles: Set<string>; // files known not to be in any cycle
}

入全屏模式 出全屏模式

及其用之域:

function dfs(file: string, depth: number, visited: Set<string>) {
  if (file === sourceFile) {
    allCycles.push([...pathStack, file]);
    return;
  }
  if (depth >= maxDepth) return; // <-- early return on depth limit
  if (visited.has(file)) return;
  if (cache.nonCyclicFiles.has(file)) return;
  // ... recurse into imports
}

dfs(targetFile, 1, new Set());
if (allCycles.length === 0) {
  cache.nonCyclicFiles.add(targetFile); // <-- cache the result
}

入全屏模式 出全屏模式

察其弊乎?在彼二行之间// <--

缓存何以自戕

当DFS至时depth >= maxDepth者,返,若已穷尽探索而无环。呼者不能辨"吾已遍察无所见"与"吾止于深十"之异

。故文件惟环在深十二(十二> maxDepth=十)者,得:

  1. DFS止于深十
  2. allCycles.length === 0
  3. cache.nonCyclicFiles.add(targetFile) — 误标为已知无环

。今后任何未来之深度优先遍历,若经此文件,则因if (cache.nonCyclicFiles.has(file)) return;而中断。毒化蔓延:同强连通分量子树之每文件,皆因关联而标为无环。

于微尘之域,不见其流布之象——无足多之文书,不足以掩其余。于十四万卷之域,一早失而继以缓存,则群集尽毁。

狭域与广域之辨,其证在此

此乃验之之术。同法,同制,同--no-cache 此旗以避 ESLint 之缓存——然吾之进程缓存仍存于运行期间:

# Wide scope: 2,363 files, includes everything in packages/
$ eslint --config flagship.config.mjs 'packages/**/*.{ts,tsx,js}'
# 0 import-next/no-cycle findings

# Narrow scope: 33 files, just the router-reducer directory
$ eslint --config flagship.config.mjs 'packages/next/src/client/components/router-reducer/**/*.ts'
# 5+ import-next/no-cycle findings

全屏模式 退出全屏模式

狭行发现循环。广行,自新进程与新缓存始,亦生新缓存——然 ESLint 依序限文件,及处理二千三百六十三文件,渐积之。nonCyclicFiles缓存。及至绒絮通道达于文件之时,属乎循环,彼循环者,乃为伪作非循环之名,由层叠所致。

oxlint,其为一异法,有自之实,不共吾之缓存。乃用oxlint之自。ModuleGraphVisitorBuilder乃得十七周而复始。

其补

察DFS是否截断,勿缓存截断之运行:

let depthLimitHit = false;

function dfs(file: string, depth: number, visited: Set<string>) {
  if (file === sourceFile) {
    allCycles.push([...pathStack, file]);
    return;
  }
  if (depth >= maxDepth) {
    depthLimitHit = true; // <-- record the truncation
    return;
  }
  // ... rest unchanged
}

dfs(targetFile, 1, new Set());

// Only cache as acyclic when DFS COMPLETED and found nothing.
// A depth-truncated DFS isn't proof of acyclicity.
if (allCycles.length === 0 && !depthLimitHit) {
  cache.nonCyclicFiles.add(targetFile);
}

入全屏模式 出全屏模式

五行。于next.js再运行:0 → 245独文件于循环,914独(文件,行)对。广域之正误今合于狭域之正误.

eslint-plugin-import所为之事何哉

既得真谬,当察同域之侪如何拟此患。恒久之eslint-plugin-import/no-cycle法,其术迥异:

// from eslint-plugin-import/src/rules/no-cycle.js:73
const scc = options.disableScc
  ? {}
  : StronglyConnectedComponentsBuilder.get(myPath, context);

// ...

// If we're in different SCCs, we can't have a circular dependency
const hasDependencyCycle =
  options.disableScc || scc[myPath] === scc[imported.path];
if (!hasDependencyCycle) return;

入全景模式 出全景模式

彼辈构强连通分量之图,每检校一遭即成之,则逐文之环核验,时恒一也。"此二文件同属一SCC乎?"。SCC之图,以Tarjan之算法,计之需O(V+E)时

。此法全避深度之限。SCC者,答"何为循环之簇"之确解也——无截断,无近似,无缓存之毒。其缓存SCC之果于全域,并于Program:exit时清之。

oxlint之道,更进一层:于解析之际,立显明之模组图,继而环视者直行于图。无复需强连通分量,盖图已具结构矣。

二法共具一性,吾之缓存深度优先法所无:算法为精确,非约略。缓存以部分计算易取正确——此正吾误行之道也。

下次我将有所不同

三得之於诊:

缓存之不可欺也。一缓存条目,当唯编码汝所。已证,非汝所知之信息也未能证伪吾等nonCyclicFiles 缓存编码"DFS未发现环"为"无环存在"。此非同义之语。

当于部署之域,试此算法。 我等单元测试得通,盖因测试之具小而深有界。此弊惟于2K以上之文件显,时缓存已盈,遂启级联。吾辈需一压力测试,以拟生产之境。

精算法可避缓存所引之谬。 基于强连通分量之循环检测(eslint-plugin-import)与模块图遍历(oxlint)于构造上即避深度限制之交互。吾持深度优先遍历之法有由——逐文件缓存之增量分析实受其益——然深度限制与缓存之交互恰为强连通分量之法所不能有之弊。当再评估增量是否值得此交易.

修复已就包/eslint-devkit/src/解析器/依赖分析.ts曝之凳也benchmarks/suites/ilb-flagship

此乃三律之弊,同此一扫而得。其伴文如下:何真境为单元测试所遗(烟门之器)与熵不足时 (807 假证之发见于vercel/ai).


📊 有关作者

吾乃Ofri Peretz,筑Interlace ESLint之生态——JavaScript静态分析之目录,行于ESLint与Oxlint,以CI所强制之均等.