#2432 made a default import read the module's own `export default`
statement, and its merge pointed #2433's `require('./x').default`
fallback (esmDefaultExport) at the same reading. Nothing in the suite
pinned that path with a guessable helper above the default: #2433's
fixture keeps its helper unexported.
Two cases:
- React Native's AnimatedColor shape, an exported helper above
`export default class AnimatedColor`, loaded with
`require("./AnimatedColor").default` and
`const { default: Color } = require("./AnimatedColor")`. With the
first-exported guess both `new` calls instantiate the helper.
- `export default abstract class Repository` below an exported
`connect()`, extended by `class Users extends Repository`. With the
guess the `extends` edge is missing.
Both fail with e47cb258's resolver (before #2432). On main, putting the
guess back on the require path fails only the first, and dropping
`abstract` from the declaration pattern fails only the second.
The CHANGELOG's default-import bullet now says `require('./x').default`
is read the same way.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A default import resolved to the module's first exported function or
component whenever the `export default` statement wrote a declaration
(`export default function Vans()`, `export default class Store`): only a
separate `export default NAME` statement was read. A React Router 6.4+
data-router page exports its `loader` or `action` above the page
component, so `import Vans, { loader as vansLoader } from './Vans'` bound
the route `/vans` (and every call through `Vans`) to `loader`.
The resolver now reads the file's own `export default` statement from
comment-stripped code. A declaration it writes is found by position, a
binding it names by name, and an anonymous function, class or arrow
function is no node at all (the guess took an exported function beside it,
or one nested inside it). The statement also beats an exported styled/memo
component above it. Every line-initial statement is read and the first one
that names a node of the file wins, so template text that only reads like
a statement names nothing. Strings are not masked: a masker loses step on a
template whose `${…}` holds another template or a regex with a backtick,
and on outline it blanked the real statement below one. Only an expression
default (`memo(Card)`, `new Service()`), a binding the file doesn't
declare, or no statement keeps the old guess.
`require('./x').default` (#2433) reads the same statement first, so it
reaches the declared default too.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>