diff --git a/packages/vinext/src/index.ts b/packages/vinext/src/index.ts index 6f163909..b84ff568 100644 --- a/packages/vinext/src/index.ts +++ b/packages/vinext/src/index.ts @@ -1472,6 +1472,23 @@ export default function vinext(options: VinextOptions = {}): PluginOption[] { ) { return; } + // proxy.ts / middleware.ts may export either a named handler + // or default export. The generated virtual entries probe both + // forms and validate at runtime, which can trigger noisy + // IMPORT_IS_UNDEFINED warnings when only one form exists. + // Match any file extension because findMiddlewareFile() scans + // all configured pageExtensions, not just .ts/.js. + if ( + warning.code === "IMPORT_IS_UNDEFINED" && + /Import `(?:default|proxy|middleware)` will always be undefined/.test( + warning.message ?? "", + ) && + /\b(?:proxy|middleware)\.\w+\b/.test(warning.message ?? "") && + (warning.message?.includes("virtual:vinext-rsc-entry") || + warning.message?.includes("virtual:vinext-server-entry")) + ) { + return; + } if (userOnwarn) { userOnwarn(warning, defaultHandler); } else { diff --git a/tests/pages-router.test.ts b/tests/pages-router.test.ts index 4e0b816d..c437ad13 100644 --- a/tests/pages-router.test.ts +++ b/tests/pages-router.test.ts @@ -1444,6 +1444,81 @@ describe("Plugin config", () => { expect(defaultHandler).toHaveBeenCalledWith(otherWarning); }); + it("suppresses IMPORT_IS_UNDEFINED noise for generated proxy/middleware fallback probes", async () => { + const plugins = vinext() as any[]; + const configPlugin = plugins.find((p) => p.name === "vinext:config"); + expect(configPlugin).toBeDefined(); + + const result = await configPlugin.config({ root: FIXTURE_DIR, plugins: [] }); + + expect(result.build).toBeDefined(); + const bundlerOptions = getBuildBundlerOptions(result); + expect(bundlerOptions).toBeDefined(); + expect(bundlerOptions.onwarn).toBeDefined(); + + const defaultHandler = vi.fn(); + + bundlerOptions.onwarn( + { + code: "IMPORT_IS_UNDEFINED", + message: + "[IMPORT_IS_UNDEFINED] Warning: Import `default` will always be undefined because there is no matching export in 'proxy.ts'\\n ╭─[ \\0virtual:vinext-rsc-entry:2632:34 ]", + }, + defaultHandler, + ); + expect(defaultHandler).not.toHaveBeenCalled(); + + bundlerOptions.onwarn( + { + code: "IMPORT_IS_UNDEFINED", + message: + "[IMPORT_IS_UNDEFINED] Warning: Import `default` will always be undefined because there is no matching export in 'middleware.ts'\\n ╭─[ \\0virtual:vinext-server-entry:168:34 ]", + }, + defaultHandler, + ); + expect(defaultHandler).not.toHaveBeenCalled(); + + bundlerOptions.onwarn( + { + code: "IMPORT_IS_UNDEFINED", + message: + "[IMPORT_IS_UNDEFINED] Warning: Import `proxy` will always be undefined because there is no matching export in 'proxy.tsx'\\n ╭─[ \\0virtual:vinext-rsc-entry:2632:34 ]", + }, + defaultHandler, + ); + expect(defaultHandler).not.toHaveBeenCalled(); + + bundlerOptions.onwarn( + { + code: "IMPORT_IS_UNDEFINED", + message: + "[IMPORT_IS_UNDEFINED] Warning: Import `middleware` will always be undefined because there is no matching export in 'middleware.jsx'\\n ╭─[ \\0virtual:vinext-server-entry:168:34 ]", + }, + defaultHandler, + ); + expect(defaultHandler).not.toHaveBeenCalled(); + + bundlerOptions.onwarn( + { + code: "IMPORT_IS_UNDEFINED", + message: + "[IMPORT_IS_UNDEFINED] Warning: Import `default` will always be undefined because there is no matching export in 'some-user-file.ts'", + }, + defaultHandler, + ); + expect(defaultHandler).toHaveBeenCalledTimes(1); + + bundlerOptions.onwarn( + { + code: "IMPORT_IS_UNDEFINED", + message: + "[IMPORT_IS_UNDEFINED] Warning: Import `proxy` will always be undefined because there is no matching export in 'some-user-file.ts'", + }, + defaultHandler, + ); + expect(defaultHandler).toHaveBeenCalledTimes(2); + }); + it("preserves user-supplied build.rollupOptions.onwarn", async () => { const plugins = vinext() as any[]; const configPlugin = plugins.find((p) => p.name === "vinext:config");