Field Test #020b — Next.js Root Ownership Refinement

Field Test #020b — Next.js Root Ownership Refinement

现场测试 #020b — Next.js 根目录所有权优化

The first version of the patch treated the issue as a nearest-root problem. That was too broad. The failure in #92978 involved a stray parent lockfile causing Next.js to infer a root that was much wider than the app’s actual project boundary. For Turbopack, that can route module resolution and file watching through the wrong directory tree. 该补丁的第一个版本将此问题视为“最近根目录”问题,但这过于宽泛。#92978 中的故障涉及一个无关的父级 lockfile,导致 Next.js 推断出的根目录范围远超应用程序的实际项目边界。对于 Turbopack 而言,这可能导致模块解析和文件监视被路由到错误的目录树中。

But there is also a valid monorepo case: /monorepo/pnpm-lock.yaml / /monorepo/apps/docs/pnpm-lock.yaml. In that layout, the higher lockfile can be the correct root. So the better rule is not: “nearest lockfile wins” or “highest lockfile wins”. The better rule is: “workspace authority wins”. 但同时也存在合法的 Monorepo 情况,例如:/monorepo/pnpm-lock.yaml/monorepo/apps/docs/pnpm-lock.yaml。在这种布局中,上层的 lockfile 可能是正确的根目录。因此,更好的规则不是“最近的 lockfile 胜出”或“最顶层的 lockfile 胜出”,而是“工作区权限(workspace authority)胜出”。

The updated patch now separates root markers that actually own the workspace from parent markers that are only accidental detections. Current repair shape: 更新后的补丁现在将真正拥有工作区的根标记与仅被意外检测到的父级标记区分开来。目前的修复方案如下:

  • Explicit pnpm-workspace.yaml roots still win.
  • Parent package.json roots still win when they declare workspaces.
  • Plain parent lockfiles without workspace authority are ignored.
  • Parent package roots without workspaces are ignored.
  • Nested app lockfiles remain valid when no higher workspace authority exists.
  • 显式的 pnpm-workspace.yaml 根目录依然胜出。
  • 声明了工作区的父级 package.json 根目录依然胜出。
  • 没有工作区权限的普通父级 lockfile 将被忽略。
  • 没有工作区的父级包根目录将被忽略。
  • 当不存在更高级别的工作区权限时,嵌套的应用程序 lockfile 依然有效。

That keeps the intended monorepo behavior while addressing the stray-parent-lockfile-failure. 这既保留了预期的 Monorepo 行为,又解决了无关父级 lockfile 导致的故障。

What changed

变更内容

The PR now narrows root inference around workspace authority rather than lockfile distance alone. The important distinction is: discovered marker is not automatically root ownership. A parent lockfile can be seen by root discovery without being allowed to take over the app’s inferred root. 该 PR 现在围绕“工作区权限”而非仅仅依靠“lockfile 距离”来缩小根目录推断范围。一个重要的区别是:发现标记并不等同于拥有根目录所有权。根目录发现机制可以识别到父级 lockfile,但不能让它接管应用程序推断出的根目录。

The patch keeps higher roots only when they provide an explicit workspace signal: pnpm-workspace.yaml or a parent package.json with workspaces. Everything else stays as diagnostic context, not root ownership. 该补丁仅在提供明确的工作区信号(如 pnpm-workspace.yaml 或带有工作区声明的父级 package.json)时,才会保留更高级别的根目录。其他所有内容仅作为诊断上下文,而非根目录所有权。

Test coverage

测试覆盖范围

The updated tests cover both sides of the boundary: 更新后的测试覆盖了边界的两侧:

  • stray parent lockfiles do not hijack root inference
  • non-workspace parent package roots do not hijack root inference
  • higher package roots with workspaces still win
  • higher pnpm-workspace.yaml roots still win
  • 无关的父级 lockfile 不会劫持根目录推断
  • 非工作区的父级包根目录不会劫持根目录推断
  • 带有工作区的更高级别包根目录依然胜出
  • 更高级别的 pnpm-workspace.yaml 根目录依然胜出

That is the key difference from the first patch. The first patch fixed the reported failure path. The updated patch preserves the valid monorepo path too. 这是与第一个补丁的关键区别。第一个补丁修复了报告的故障路径,而更新后的补丁同时保留了合法的 Monorepo 路径。

Current PR

当前 PR

  • PR: vercel/next.js#94597
  • Title: Ignore stray parent lockfiles when inferring workspace root
  • 标题: 在推断工作区根目录时忽略无关的父级 lockfile

Field test outcome

现场测试结果

This field test tightened from a simple root-distance fix into a root-ownership fix. The boundary is now clearer: A parent marker should not own the app root unless it carries workspace authority. That is the difference between fixing the reported failure and preserving the larger monorepo invariant. 本次现场测试从简单的“根目录距离修复”升级为“根目录所有权修复”。边界现在更加清晰:除非父级标记带有工作区权限,否则它不应拥有应用程序的根目录。这就是修复报告故障与维护更广泛的 Monorepo 不变性之间的区别。

The resulting patch is more precise: 最终的补丁更加精确:

  • stray parent lockfiles are filtered
  • workspace roots are preserved
  • focused tests cover both paths
  • root inference no longer treats every discovered parent marker as an owner
  • 过滤了无关的父级 lockfile
  • 保留了工作区根目录
  • 重点测试覆盖了两种路径
  • 根目录推断不再将每个发现的父级标记视为所有者

Disclosure: This article was drafted with AI assistance from my own field-test notes, PR records, validation logs, and repair summaries. The technical work, issue analysis, patch review, and final claims were reviewed by me before publication. 披露:本文是在 AI 的辅助下,根据我个人的现场测试笔记、PR 记录、验证日志和修复总结草拟而成。技术工作、问题分析、补丁审查和最终结论在发布前均已由我本人审核。