From d34098f99e7c7e1e2b7f5bae9ddf719fe69b5e30 Mon Sep 17 00:00:00 2001 From: kakiuwang-ui Date: Sun, 6 Sep 2026 11:16:35 +0800 Subject: [PATCH 1/2] fix: only treat whole `node_modules` path segments as dependencies (fix #17467) --- .../vite/src/node/__tests__/utils.spec.ts | 24 +++++++++++++++++++ packages/vite/src/node/utils.ts | 7 +++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/packages/vite/src/node/__tests__/utils.spec.ts b/packages/vite/src/node/__tests__/utils.spec.ts index 83d565011a5115..2805d7fb008635 100644 --- a/packages/vite/src/node/__tests__/utils.spec.ts +++ b/packages/vite/src/node/__tests__/utils.spec.ts @@ -20,6 +20,7 @@ import { getServerUrlByHost, injectQuery, isFileReadable, + isInNodeModules, isParentDirectory, mergeWithDefaults, normalizePath, @@ -83,6 +84,29 @@ describe('bareImportRE', () => { }) }) +describe('isInNodeModules', () => { + test('should detect node_modules path segments', () => { + expect(isInNodeModules('/project/node_modules/foo/index.js')).toBe(true) + expect(isInNodeModules('node_modules/foo/index.js')).toBe(true) + expect( + isInNodeModules( + '/project/node_modules/.pnpm/foo@1/node_modules/foo/i.js', + ), + ).toBe(true) + expect(isInNodeModules('C:\\project\\node_modules\\foo\\index.js')).toBe( + true, + ) + expect(isInNodeModules('/project/node_modules')).toBe(true) + }) + + test('should not match node_modules as part of a directory name', () => { + expect(isInNodeModules('/project/node_modules_bug/src/main.js')).toBe(false) + expect(isInNodeModules('/project/my_node_modules/src/main.js')).toBe(false) + expect(isInNodeModules('/project/src/node_modules.js')).toBe(false) + expect(isInNodeModules('C:\\node_modules_bug\\src\\main.js')).toBe(false) + }) +}) + describe('isParentDirectory', () => { const cases = { '/parent': { diff --git a/packages/vite/src/node/utils.ts b/packages/vite/src/node/utils.ts index 2207e00f13a426..6771452168c80f 100644 --- a/packages/vite/src/node/utils.ts +++ b/packages/vite/src/node/utils.ts @@ -137,8 +137,13 @@ export function isNodeBuiltin(id: string): boolean { return nodeBuiltins.includes(id) } +// `node_modules` has to be a complete path segment, otherwise a project that +// happens to live in a directory like `my-node_modules-test` would have all of +// its own sources treated as dependencies. +const inNodeModulesRE = /(?:^|[\\/])node_modules(?:[\\/]|$)/ + export function isInNodeModules(id: string): boolean { - return id.includes('node_modules') + return inNodeModulesRE.test(id) } export function moduleListContains( From f39e5308461ce8442d1228ce1f6dd94a5fb20614 Mon Sep 17 00:00:00 2001 From: Bjorn Lu Date: Wed, 9 Sep 2026 16:39:12 +0800 Subject: [PATCH 2/2] Apply suggestion from @bluwy --- packages/vite/src/node/utils.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/vite/src/node/utils.ts b/packages/vite/src/node/utils.ts index 6771452168c80f..f9f1ea48e74605 100644 --- a/packages/vite/src/node/utils.ts +++ b/packages/vite/src/node/utils.ts @@ -137,9 +137,6 @@ export function isNodeBuiltin(id: string): boolean { return nodeBuiltins.includes(id) } -// `node_modules` has to be a complete path segment, otherwise a project that -// happens to live in a directory like `my-node_modules-test` would have all of -// its own sources treated as dependencies. const inNodeModulesRE = /(?:^|[\\/])node_modules(?:[\\/]|$)/ export function isInNodeModules(id: string): boolean {