Fix #3741: avoid duplicate-source re-export in motion/react that crashed Turbopack#3743
Fix #3741: avoid duplicate-source re-export in motion/react that crashed Turbopack#3743mattgperry wants to merge 1 commit into
Conversation
The previous `motion/src/react.ts` had two re-export statements pulling
from the same module:
export { motion, m } from "framer-motion"
export * from "framer-motion"
When compiled to ESM and loaded by Next.js 16's Turbopack on Windows,
this duplicate-source pattern caused the dev server to OOM during
module-graph analysis (#3741). Importing `framer-motion` directly worked
fine, since framer-motion's own index never re-exports from the same
source twice.
Switching to an `import * as fm from "framer-motion"` + `const` alias
keeps the explicit `motion`/`m` exports that IDE auto-import relies on
(#3432) without the duplicate-source pattern. Per the ES spec, local
declarations shadow the names from `export * from "framer-motion"`, so
the compiled output now has a single wildcard re-export plus two local
const bindings — a shape Turbopack handles cleanly.
Fixes #3741
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Greptile SummaryThis PR fixes a Turbopack OOM crash by removing a duplicate-source re-export pattern in
Confidence Score: 5/5Safe to merge — the change is a minimal, targeted rewrite of a single 16-line file with no behavioral change for consumers. The fix correctly eliminates the duplicate-source re-export by using a namespace import plus local const aliases. Per the ES spec, the explicit export const motion and export const m declarations shadow the wildcard, so consumers see identical public exports. The typeof fm.motion type annotations preserve declaration-file fidelity. The compiled CJS and ESM outputs are both clean. The other entry points in the motion package are unaffected. No files require special attention. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
subgraph Before["Before (caused Turbopack OOM)"]
B_consumer["Consumer\nimport { motion } from 'motion/react'"]
B_react["motion/react\nexport { motion, m } from 'framer-motion'\nexport * from 'framer-motion'"]
B_fm["framer-motion"]
B_consumer --> B_react
B_react -->|"edge 1: named re-export"| B_fm
B_react -->|"edge 2: wildcard re-export (duplicate!)"| B_fm
end
subgraph After["After (fix)"]
A_consumer["Consumer\nimport { motion } from 'motion/react'"]
A_react["motion/react\nimport * as fm from 'framer-motion'\nexport const motion = fm.motion\nexport const m = fm.m\nexport * from 'framer-motion'"]
A_fm["framer-motion"]
A_consumer --> A_react
A_react -->|"single module-graph edge"| A_fm
end
Reviews (1): Last reviewed commit: "Fix Turbopack OOM by avoiding duplicate-..." | Re-trigger Greptile |
The bug
motion@12.40.0causes Next.js 16.2.6's Turbopack dev server to OOM during compilation on Windows. Switching toframer-motionin the same project compiles fine. Symptoms from the reporter:Fixes #3741
The cause
packages/motion/src/react.tshad two re-export statements pulling from the same module:After Rollup, the published
motion/dist/es/react.mjslooked like:This duplicate-source re-export pattern is the only structural difference between
motion/reactand importingframer-motiondirectly — and it's where Turbopack's module-graph analyser appears to chew through memory on Windows. The named line was added in commitaacf1e0e3to make IDE auto-import suggestmotionandm(#3432); the wildcard already covered them, so the pattern was effectively a duplicate.The fix
Re-export
motionandmthrough a namespace import + local const aliases. The compiledreact.mjsbecomes:Per the ES spec, local exports shadow the names that
export *would have pulled in, somotionandmcome from the explicit bindings and everything else from the wildcard. There's now a singlefrom 'framer-motion'chain in the module graph for Turbopack to follow — no duplicate to choke on. The explicitexport { m, motion }keeps the IDE auto-import fix from #3432 intact.Verification
yarn buildsucceeds. Compiledmotion/dist/es/react.mjsandreact.d.tsare clean (single wildcard, no duplicatefrom 'framer-motion').yarn testpasses — 797 tests, 7 skipped, 0 new failures.motionandmfrommotion/reactis preserved (explicit named exports still in the .d.ts output).Caveat
The OOM is environment-specific (Windows + Next.js 16 Turbopack + pnpm) and I couldn't reproduce it locally on macOS. The fix targets the only meaningful structural difference between
motionandframer-motionfrom a bundler's perspective: the duplicate-source re-export pattern. If the reporter can re-test against this branch and confirm the OOM is gone, we can land confidently.🤖 Generated with Claude Code