Skip to content

Comments

fix(server): include external workspace package roots in fs allow#21703

Open
Vishnuuuu24 wants to merge 2 commits intovitejs:mainfrom
Vishnuuuu24:fix/search-workspace-root-pnpm-21700
Open

fix(server): include external workspace package roots in fs allow#21703
Vishnuuuu24 wants to merge 2 commits intovitejs:mainfrom
Vishnuuuu24:fix/search-workspace-root-pnpm-21700

Conversation

@Vishnuuuu24
Copy link

Fixes #21700.\n\nsearchForWorkspaceRoot now resolves workspace package patterns from pnpm-workspace.yaml and package.json workspaces/workspaces.packages, computes their common ancestor, and uses that as workspace root. This allows valid layouts with ../packages/* to be included in fs allow.\n\nIncludes new regression fixtures/tests for pnpm and npm-style workspaces that reference parent directories.\n\nValidation:\n- pnpm vitest run src/node/server/tests/search-root.spec.ts (packages/vite)\n- pnpm run typecheck (packages/vite)\n- pnpm run typecheck (repo root)

Copilot AI review requested due to automatic review settings February 24, 2026 17:40
@Vishnuuuu24
Copy link
Author

Local verification completed after latest changes:\n- pnpm vitest run src/node/server/tests/search-root.spec.ts (7/7 passing)\n- pnpm run typecheck (packages/vite)\n- pnpm run typecheck (repo root)\n\nThis covers the new pnpm and package.json workspace-parent-directory regression cases.

@Vishnuuuu24
Copy link
Author

Updated PR with a lockfile fix for CI formatting:\n- added missing importer entries in pnpm-lock.yaml for new fixture package.json files\n\nThis addresses the failing "Check formatting" job diff on pnpm-lock.yaml.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a bug where Vite's searchForWorkspaceRoot function incorrectly blocked access to workspace packages located outside the workspace root directory. The fix parses workspace configuration files (pnpm-workspace.yaml and package.json workspaces field) to extract package patterns, computes their base directories, and determines the common ancestor of all workspace packages as the true workspace root.

Changes:

  • Enhanced searchForWorkspaceRoot to parse workspace configurations and compute the common ancestor of all package locations
  • Added comprehensive YAML parsing for pnpm-workspace.yaml without external dependencies
  • Added JSON parsing for package.json workspaces field with support for both array and object formats
  • Added test cases and fixtures for pnpm and npm workspaces with external packages

Reviewed changes

Copilot reviewed 8 out of 9 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
packages/vite/src/node/server/searchRoot.ts Core implementation: added workspace pattern parsing, base directory extraction, and common ancestor computation
packages/vite/src/node/server/tests/search-root.spec.ts Added test cases for pnpm and npm workspaces with packages outside the workspace directory
packages/vite/src/node/server/tests/fixtures/pnpm-outside/workspace/pnpm-workspace.yaml Test fixture for pnpm workspace with external packages
packages/vite/src/node/server/tests/fixtures/pnpm-outside/workspace/my-app/package.json Test fixture package.json for nested app
packages/vite/src/node/server/tests/fixtures/pnpm-outside/packages/my-lib/package.json Test fixture package.json for external library
packages/vite/src/node/server/tests/fixtures/npm-outside/workspace/package.json Test fixture for npm/yarn workspace with external packages
packages/vite/src/node/server/tests/fixtures/npm-outside/workspace/my-app/package.json Test fixture package.json for nested app
packages/vite/src/node/server/tests/fixtures/npm-outside/packages/my-lib/package.json Test fixture package.json for external library
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

return root
}

if (basename(base).includes('.')) {
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The heuristic basename(base).includes('.') assumes that paths with dots in the basename are files rather than directories. While this works for typical cases, directories can have dots in their names (e.g., packages/v1.0/). This could cause the function to incorrectly use the parent directory. Consider checking if the path actually exists on the filesystem and is a directory, or documenting this limitation. However, the impact is limited: it would just make the allow list slightly more permissive than necessary, which is safe.

Suggested change
if (basename(base).includes('.')) {
const basePath = resolve(root, base)
let isDirectory = false
try {
isDirectory = fs.statSync(basePath).isDirectory()
} catch {
// If the path does not exist or can't be stat'ed, fall back to the heuristic below.
}
if (!isDirectory && basename(base).includes('.')) {

Copilot uses AI. Check for mistakes.
Comment on lines +137 to +154
function getCommonAncestor(paths: string[]): string {
if (!paths.length) {
return ''
}

let ancestor = resolve(paths[0])
for (const path of paths.slice(1).map((path) => resolve(path))) {
while (ancestor !== dirname(ancestor)) {
const relation = relative(ancestor, path)
if (
relation === '' ||
(!relation.startsWith('..') && !isAbsolute(relation))
) {
break
}
ancestor = dirname(ancestor)
}
}
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On Windows, if workspace packages are located on different drives, the function may return incorrect results. When paths are on different drives, relative() returns an absolute path, and the algorithm will eventually terminate at the root of the first path's drive, even though that drive doesn't contain the other paths. While this is an extremely rare edge case in practice, consider adding a check or documenting this limitation.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

searchForWorkspaceRoot doesn't account for pnpm workspace packages outside workspace root directory

1 participant