fix: resolve directory imports for next/font shims#157
fix: resolve directory imports for next/font shims#157hoangnv170752 wants to merge 1 commit intocloudflare:mainfrom
Conversation
Co-authored-by: ask-bonk[bot] <ask-bonk[bot]@users.noreply.github.com> Co-authored-by: southpolesteve <southpolesteve@users.noreply.github.com> Co-authored-by: Steve Faulkner <sfaulkner@cloudflare.com>
|
/bigbonk review |
There was a problem hiding this comment.
Thanks for the PR! The intent is sound — catching next/font/local and next/font/google directory-style imports from third-party packages like geist is a real need. However, I have a few concerns:
1. Redundancy with resolve.alias
The nextShimMap is already used as resolve.alias (line 1917), which maps "next/font/local" and "next/font/google" to their shim paths. Vite aliases apply globally, including to imports from node_modules. Can you confirm that resolve.alias genuinely fails for the geist package case? The error you quoted ("Directory import ... is not supported resolving ES modules") typically comes from Node's ESM module resolver, not from Vite's alias plugin. If this is reproducible, please document why the alias fails in the comment.
2. Unify with the existing .js handler
The existing .js handler (lines 2094-2105) and this new block do fundamentally the same thing: look up the import in nextShimMap and return the shim path. They should be merged into a single block:
// Handle next/* imports that resolve.alias may not catch:
// - With .js extension (e.g., "next/navigation.js" from nuqs)
// - Without extension from node_modules (e.g., "next/font/local" from geist)
// Strip .js if present, then resolve through our shim map.
if (cleanId.startsWith("next/")) {
const baseId = cleanId.endsWith(".js") ? cleanId.slice(0, -3) : cleanId;
if (nextShimMap[baseId]) {
const shimPath = nextShimMap[baseId];
return shimPath.endsWith(".js") ? shimPath : shimPath + ".js";
}
}This is cleaner — one block handles both cases with the same logic.
3. No tests
This is a resolution-level change. Please add a test that verifies the resolveId handler returns the correct shim path for bare next/font/local and next/font/google imports without .js.
See inline comments for more detail.
| // Handle directory imports without extension (e.g., "next/font/local") | ||
| // Libraries like geist import "next/font/local" as a directory which | ||
| // Vite's ESM resolution rejects. Resolve through our shim map. | ||
| if (cleanId.startsWith("next/") && !cleanId.endsWith(".js")) { |
There was a problem hiding this comment.
The condition cleanId.startsWith("next/") && !cleanId.endsWith(".js") matches every non-.js next/* import — not just "directory imports". For example, "next/navigation", "next/link", and "next/router" all match this condition.
This is benign (the shim map has those entries and the alias would resolve them anyway), but the comment "Handle directory imports without extension" is misleading — it implies only directory-like paths are caught, when in reality all next/* bare imports match.
Consider either:
- Making the comment accurate: "Fallback for any next/* bare import not resolved by resolve.alias"
- Or narrowing the condition if you truly only want directory-style subpath imports (e.g., paths with more than one
/segment afternext/)
| if (cleanId.startsWith("next/") && !cleanId.endsWith(".js")) { | ||
| if (nextShimMap[cleanId]) { | ||
| const shimPath = nextShimMap[cleanId]; | ||
| return shimPath.endsWith(".js") ? shimPath : shimPath + ".js"; |
There was a problem hiding this comment.
This logic is identical to what the .js handler above does (lines 2101-2103). Rather than duplicating, consider merging both blocks into a single handler as suggested in the review summary. This reduces code duplication and makes the intent clearer.
|
The review has been submitted successfully. Here's a summary of the feedback I posted: Review: Changes Requested on PR #157 Three main concerns raised:
Two inline comments were also posted:
|
1/ Summary
2/ Problem
import localFont from "next/font/local"The existing resolve.alias only works for user code, not for dependencies in node_modules.
3/ Solution