Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions packages/vinext/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
75 changes: 75 additions & 0 deletions tests/pages-router.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 ]",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nit: these test messages use \\n (literal two-character backslash-n) instead of \n (actual newline). In real Rolldown output the message contains an actual newline character. This doesn't affect correctness since .includes() and the regex both match against the substring before the newline, but using actual \n would make the test data more faithful to what the bundler produces.

Not blocking — just a fidelity improvement if you're doing another pass.

},
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");
Expand Down
Loading