next.js
c979cefa - Turbopack: Enable tree-shaking for dynamic imports with destructuring (#89683)

Commit
90 days ago
Turbopack: Enable tree-shaking for dynamic imports with destructuring (#89683) ## What? This PR enables tree-shaking for dynamic imports when the imported module's exports are destructured or accessed via member expressions. Previously, dynamic imports were treated as importing all exports, preventing unused exports from being removed. ## Why? Dynamic imports with destructuring patterns like `const { cat } = await import('./lib')` or member access like `(await import('./lib')).cat` now properly communicate which specific exports are actually used. This allows bundlers (particularly Turbopack) to tree-shake unused exports from dynamically imported modules, reducing bundle size. ## How? ### Core Changes: 1. **AST Analysis Enhancement** (`turbopack-ecmascript/src/analyzer/graph.rs`): - Added new `Effect::DynamicImport` variant that captures destructuring patterns and member access - Implemented `extract_dynamic_import_export_names()` to statically analyze destructuring patterns and extract used export names - Supports: const/let/var destructuring, renamed imports, nested destructuring, default exports, member access, and empty destructuring 2. **Export Usage Tracking** (`turbopack-core/src/resolve/mod.rs`): - Added `ExportUsage::NamedSet` variant to track multiple named exports being used - Updated `ModuleExportUsageInfo` to handle merging of multiple named exports 3. **Dynamic Import Reference** (`turbopack-ecmascript/src/references/esm/dynamic.rs`): - Extended `EsmAsyncAssetReference` with `export_names` field - Implemented `binding_usage()` to communicate which exports are used to the module graph 4. **Effect Processing** (`turbopack-ecmascript/src/references/mod.rs`): - Refactored dynamic import handling into dedicated `handle_dynamic_import()` function - Passes export usage information through the reference system ### Test Coverage: - **E2E Tests** (`test/e2e/app-dir/dynamic-import-tree-shaking/`): Comprehensive tests for Next.js App Router covering various destructuring patterns - **Snapshot Tests** (`turbopack-tests/tests/snapshot/basic-tree-shake/`): Turbopack-specific tests validating tree-shaking behavior ### Supported Patterns: - ✅ Named destructuring: `const { cat } = await import('./lib')` - ✅ Variable declarations: `var`, `let`, `const` - ✅ Renamed imports: `const { cat: myCat } = await import('./lib')` - ✅ Nested destructuring: `const { dogRef: { get } } = await import('./lib')` - ✅ Default exports: `const { default: val } = await import('./lib')` - ✅ Empty destructuring: `const {} = await import('./lib')` (side effects only) - ✅ Member access: `(await import('./lib')).cat` ### Limitations: - Rest patterns (`const { cat, ...rest }`) conservatively import all exports - Computed property keys are not statically analyzed - Member access tree-shaking is Turbopack-only (webpack limitation) https://claude.ai/code/session_01QWi3udq2LX4GFqJEDaqFFU
Author
Parents
Loading