From fd030aea79caa116d40f3c6f2990d0b9b15b9784 Mon Sep 17 00:00:00 2001 From: Qiu Guanzong Date: Sun, 20 Sep 2026 20:25:06 +0800 Subject: [PATCH] fix(optimizer): avoid false-mapping warnings (fix #23512) --- .../vite/src/node/optimizer/rolldownDepPlugin.ts | 12 ++++++++++++ .../optimize-deps/__tests__/optimize-deps.spec.ts | 13 +++++++++++++ .../dep-cjs-browser-field-bare/internal.js | 5 ++++- .../dep-cjs-browser-field-bare/package.json | 3 ++- 4 files changed, 31 insertions(+), 2 deletions(-) diff --git a/packages/vite/src/node/optimizer/rolldownDepPlugin.ts b/packages/vite/src/node/optimizer/rolldownDepPlugin.ts index 07d8cab4566b40..c2953036732d34 100644 --- a/packages/vite/src/node/optimizer/rolldownDepPlugin.ts +++ b/packages/vite/src/node/optimizer/rolldownDepPlugin.ts @@ -58,6 +58,7 @@ const externalTypes = [ const optionalPeerDepNamespace = 'optional-peer-dep:' const browserExternalNamespace = 'browser-external:' +const browserExternalEmptyNamespace = `${browserExternalNamespace}empty:` export function rolldownDepPlugin( environment: Environment, @@ -121,6 +122,11 @@ export function rolldownDepPlugin( } const resolveResult = (id: string, resolved: string, kind: ImportKind) => { + if (resolved === browserExternalId) { + return { + id: browserExternalEmptyNamespace + id, + } + } if (resolved.startsWith(browserExternalId)) { return { id: browserExternalNamespace + id, @@ -260,6 +266,12 @@ export function rolldownDepPlugin( ], }, handler(id) { + if (id.startsWith(browserExternalEmptyNamespace)) { + return { + code: 'module.exports = {}', + } + } + if (id.startsWith(browserExternalNamespace)) { const path = id.slice(browserExternalNamespace.length) if (isProduction) { diff --git a/playground/optimize-deps/__tests__/optimize-deps.spec.ts b/playground/optimize-deps/__tests__/optimize-deps.spec.ts index d6febaafad2c17..eb856425269df1 100644 --- a/playground/optimize-deps/__tests__/optimize-deps.spec.ts +++ b/playground/optimize-deps/__tests__/optimize-deps.spec.ts @@ -116,6 +116,19 @@ test('cjs browser field bare', async () => { .toBe('pong') }) +test.runIf(isServe)( + 'cjs browser field false mapping does not warn when a property is accessed', + () => { + expect( + browserLogs.some((log) => + log.includes( + 'Cannot access "fs.__explicitBrowserFieldTest" in client code.', + ), + ), + ).toBe(false) + }, +) + test('dep from linked dep (lodash-es)', async () => { await expect.poll(() => page.textContent('.deps-linked')).toBe('fooBarBaz') }) diff --git a/playground/optimize-deps/dep-cjs-browser-field-bare/internal.js b/playground/optimize-deps/dep-cjs-browser-field-bare/internal.js index 8590297e4c5138..cffbba1e5c564f 100644 --- a/playground/optimize-deps/dep-cjs-browser-field-bare/internal.js +++ b/playground/optimize-deps/dep-cjs-browser-field-bare/internal.js @@ -2,5 +2,8 @@ // eslint-disable-next-line n/prefer-node-protocol const events = require('events') +// eslint-disable-next-line n/prefer-node-protocol +const fs = require('fs') -module.exports = 'foo' in events ? 'pong' : '' +module.exports = + 'foo' in events && fs.__explicitBrowserFieldTest === undefined ? 'pong' : '' diff --git a/playground/optimize-deps/dep-cjs-browser-field-bare/package.json b/playground/optimize-deps/dep-cjs-browser-field-bare/package.json index d78987e86ed2af..6810037c254b5b 100644 --- a/playground/optimize-deps/dep-cjs-browser-field-bare/package.json +++ b/playground/optimize-deps/dep-cjs-browser-field-bare/package.json @@ -4,6 +4,7 @@ "version": "0.0.0", "main": "index.js", "browser": { - "events": "./events-shim.js" + "events": "./events-shim.js", + "fs": false } }