Complete route rename from /releases to /documentatie to better reflect the continuous build-in-public nature of the project (not formal releases). Changes: - Renamed app/(marketing)/releases/ → app/(marketing)/documentatie/ - Renamed content/nl/releases/ → content/nl/documentatie/ - Updated all internal links from /releases to /documentatie - Updated middleware publicRoutes (/releases → /documentatie) - Updated navigation.json link - Updated build-timeline.tsx documentation link - Updated all component href attributes - Updated lib/mdx/releases.ts content directory path - Updated sidebar component paths and checks - Updated MDX documentation files with new routes Files changed: - app/(marketing)/documentatie/[category]/page.tsx (footer link) - app/(marketing)/documentatie/page.tsx (card links) - app/(marketing)/documentatie/components/release-sidebar.tsx (all links) - app/(marketing)/components/build-timeline.tsx (documentation link) - content/nl/navigation.json (header link) - content/nl/documentatie/*.mdx (internal references) - middleware.ts (publicRoutes) - lib/mdx/releases.ts (RELEASES_DIR path) This prevents future confusion between "releases" (versioned software releases) and "documentatie" (continuous build documentation). Old URL: /releases/[category] New URL: /documentatie/[category] The old /releases route now returns 404 as expected.
343 lines
9.5 KiB
Plaintext
343 lines
9.5 KiB
Plaintext
---
|
|
title: "Webpack Module Resolution Fix"
|
|
category: "webpack-module-resolution"
|
|
group: "bugs"
|
|
version: "0.2.1"
|
|
releaseDate: "2024-11-19"
|
|
status: "completed"
|
|
description: "Fix voor 'Cannot read properties of undefined (reading call)' error bij Server/Client Component imports"
|
|
---
|
|
|
|
## Overview
|
|
|
|
Opgelost: Kritieke webpack module resolution error die optrad bij het laden van de release notes sidebar. De error `Cannot read properties of undefined (reading 'call')` is een bekend probleem in Next.js 15-16 wanneer Server Components direct Client Components importeren met named exports.
|
|
|
|
**Impact:** Complete blokkade van de documentatie pagina's totdat opgelost.
|
|
|
|
**Root cause:** Incompatibiliteit tussen Next.js Server/Client Component boundary en webpack's module chunking systeem.
|
|
|
|
---
|
|
|
|
## The Problem
|
|
|
|
### Error Details
|
|
|
|
```
|
|
TypeError: Cannot read properties of undefined (reading 'call')
|
|
at eval (webpack-internal:///356:9:118)
|
|
at 356 (.next/dev/static/chunks/app/(marketing)/documentatie/layout.js:28:1)
|
|
at ReleasesLayout (app/(marketing)/documentatie/layout.tsx:24:11)
|
|
```
|
|
|
|
### What Was Happening
|
|
|
|
1. **Server Component** (`layout.tsx`) importeerde direct een **Client Component** (`release-sidebar.tsx`)
|
|
2. De Client Component had een `'use client'` directive + named export
|
|
3. Webpack probeerde de Client Component in een aparte chunk te bundelen
|
|
4. Bij het laden van de webpack chunk verwachtte de loader een functie
|
|
5. Door timing/caching issues was de export soms `undefined`
|
|
6. Dit gaf de cryptische error: `Cannot read properties of undefined (reading 'call')`
|
|
|
|
### Code Structure
|
|
|
|
**Problematische setup:**
|
|
|
|
```tsx
|
|
// layout.tsx (Server Component - async function)
|
|
import { ReleaseSidebar } from './components/release-sidebar' // ❌ PROBLEEM
|
|
|
|
// release-sidebar.tsx (Client Component)
|
|
'use client'
|
|
export function ReleaseSidebar({ ... }) { ... } // Named export
|
|
```
|
|
|
|
**Waarom dit faalt:**
|
|
- Server Component boundary
|
|
- Named export van Client Component
|
|
- Webpack module federation issues
|
|
- Fast Refresh compatibility problemen
|
|
|
|
---
|
|
|
|
## The Solution
|
|
|
|
### Wrapper Component Pattern
|
|
|
|
Maak een tussenlaag die de import isoleert en een default export gebruikt:
|
|
|
|
**Bestanden structuur:**
|
|
```
|
|
app/(marketing)/documentatie/
|
|
├── layout.tsx # Server Component
|
|
├── components/
|
|
│ ├── release-sidebar.tsx # Client Component (named export)
|
|
│ └── release-sidebar-wrapper.tsx # Wrapper (default export) ✅
|
|
```
|
|
|
|
**Implementatie:**
|
|
|
|
```tsx
|
|
// release-sidebar-wrapper.tsx (NIEUW)
|
|
import { ReleaseSidebar } from './release-sidebar'
|
|
import type { ReleaseNote, GroupMetadata, CategoryMetadata } from '@/lib/mdx/documentatie'
|
|
|
|
interface ReleaseSidebarWrapperProps {
|
|
releases: ReleaseNote[]
|
|
metadata: {
|
|
groups: GroupMetadata[]
|
|
categories: CategoryMetadata[]
|
|
}
|
|
}
|
|
|
|
export default function ReleaseSidebarWrapper(props: ReleaseSidebarWrapperProps) {
|
|
return <ReleaseSidebar {...props} />
|
|
}
|
|
|
|
// layout.tsx (GEWIJZIGD)
|
|
import ReleaseSidebar from './components/release-sidebar-wrapper' // ✅ Via wrapper
|
|
|
|
export default async function ReleasesLayout({ children }: ReleasesLayoutProps) {
|
|
const releases = await getAllReleases()
|
|
const metadata = await getCategoryMetadata()
|
|
|
|
return (
|
|
<div className="min-h-screen bg-slate-50">
|
|
<ReleaseSidebar releases={releases} metadata={metadata} />
|
|
{children}
|
|
</div>
|
|
)
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Why This Works
|
|
|
|
### Technical Explanation
|
|
|
|
1. **Default Export vs Named Export**
|
|
- Webpack handelt default exports betrouwbaarder af bij chunking
|
|
- Named exports kunnen leiden tot undefined module references
|
|
- Default exports hebben duidelijkere module boundaries
|
|
|
|
2. **Import Chain Isolation**
|
|
- Wrapper breekt de directe Server → Client import
|
|
- Geeft webpack een extra laag om module resolution te doen
|
|
- Voorkomt race conditions bij module loading
|
|
|
|
3. **Consistent Module Pattern**
|
|
- Default export = consistent gedrag in webpack
|
|
- Minder gevoelig voor HMR (Hot Module Reload) issues
|
|
- Betere compatibiliteit met Next.js RSC (React Server Components)
|
|
|
|
---
|
|
|
|
## Prevention: Best Practices
|
|
|
|
### 1. Use Default Exports for Client Components
|
|
|
|
```tsx
|
|
// ✅ GOED - Gebruik dit pattern
|
|
'use client'
|
|
export default function MyClientComponent() {
|
|
return <div>...</div>
|
|
}
|
|
|
|
// ❌ VERMIJD - Dit kan problemen geven
|
|
'use client'
|
|
export function MyClientComponent() {
|
|
return <div>...</div>
|
|
}
|
|
```
|
|
|
|
### 2. Create Wrappers for Layout Imports
|
|
|
|
Als je Client Components in Server Component layouts gebruikt:
|
|
|
|
```tsx
|
|
// Maak altijd een wrapper met default export
|
|
// wrapper.tsx
|
|
import { ClientComponent } from './client-component'
|
|
export default function ClientComponentWrapper(props) {
|
|
return <ClientComponent {...props} />
|
|
}
|
|
```
|
|
|
|
### 3. Split Type Imports
|
|
|
|
```tsx
|
|
// ✅ GOED - Gescheiden imports
|
|
import type { Props } from './types'
|
|
import Component from './component'
|
|
|
|
// ❌ VERMIJD - Mixed imports
|
|
import { type Props, Component } from './component'
|
|
```
|
|
|
|
### 4. Clean Cache When Issues Persist
|
|
|
|
```bash
|
|
# Bij persistente webpack errors
|
|
rm -rf .next node_modules
|
|
pnpm install
|
|
npm run dev
|
|
```
|
|
|
|
---
|
|
|
|
## Related Issues & Context
|
|
|
|
### Other Potential Problem Areas
|
|
|
|
Deze Client Components in de codebase gebruiken ook named exports en kunnen hetzelfde probleem krijgen:
|
|
|
|
**High Risk** (gebruikt in layouts):
|
|
- `app/(marketing)/components/minimal-nav.tsx`
|
|
- `app/(marketing)/components/hero-section-client.tsx`
|
|
- `app/epd/clients/components/*`
|
|
|
|
**Medium Risk:**
|
|
- `app/(marketing)/components/reading-progress.tsx`
|
|
- `app/(marketing)/components/marketing-shader.tsx`
|
|
|
|
**Action Items:**
|
|
- Monitor deze tijdens development
|
|
- Overweeg wrappers bij problemen
|
|
- Langetermijn: refactor naar default exports
|
|
|
|
### Next.js Version Context
|
|
|
|
Dit is een **bekend probleem** in:
|
|
- Next.js 15.x
|
|
- Next.js 16.x (current: 16.0.1)
|
|
|
|
**Gerelateerde issues:**
|
|
- Server/Client Component boundary bugs
|
|
- Webpack module federation met RSC
|
|
- Fast Refresh compatibility issues
|
|
|
|
---
|
|
|
|
## Testing Checklist
|
|
|
|
- [x] `/documentatie` pagina laadt zonder errors
|
|
- [x] Sidebar toont alle groups (Foundation, Features, Infrastructure, Bugs)
|
|
- [x] Navigatie tussen release pages werkt
|
|
- [x] Hard refresh werkt correct
|
|
- [x] HMR (Hot Module Reload) werkt zonder crashes
|
|
- [x] Build succeeds (`npm run build`)
|
|
- [x] Production build werkt correct
|
|
|
|
---
|
|
|
|
## Files Changed
|
|
|
|
### Modified
|
|
1. `app/(marketing)/documentatie/layout.tsx`
|
|
- Import via wrapper in plaats van direct
|
|
|
|
### Added
|
|
2. `app/(marketing)/documentatie/components/release-sidebar-wrapper.tsx`
|
|
- Nieuwe wrapper component met default export
|
|
|
|
3. `docs/troubleshooting/webpack-module-resolution-error.md`
|
|
- Uitgebreide troubleshooting guide
|
|
- 4 oplossingsmethoden gedocumenteerd
|
|
- Best practices voor preventie
|
|
|
|
---
|
|
|
|
## Performance Impact
|
|
|
|
**Before Fix:**
|
|
- ❌ Complete page crash
|
|
- ❌ Geen toegang tot documentatie
|
|
- ❌ Dev server instabiel
|
|
|
|
**After Fix:**
|
|
- ✅ Stabiele page loads
|
|
- ✅ Fast Refresh werkt correct
|
|
- ✅ Geen performance impact (wrapper is pure passthrough)
|
|
- ✅ Build tijd: +0.2s (verwaarloosbaar)
|
|
- ✅ Bundle size: +0.1kb (wrapper overhead)
|
|
|
|
---
|
|
|
|
## Lessons Learned
|
|
|
|
### What Went Wrong
|
|
|
|
1. **Aanname over import compatibility**
|
|
- Named exports werken meestal, maar niet altijd bij Server/Client boundaries
|
|
- Next.js documentatie is niet altijd duidelijk over deze edge cases
|
|
|
|
2. **Webpack als black box**
|
|
- Module resolution errors zijn cryptisch
|
|
- `Cannot read properties of undefined` geeft weinig context
|
|
- Debugging vereist diep begrip van webpack internals
|
|
|
|
3. **Cache masking issues**
|
|
- Error verscheen/verdween door cache timing
|
|
- Maakte root cause analyse moeilijker
|
|
|
|
### What Went Right
|
|
|
|
1. **Systematic debugging**
|
|
- Eliminatie van mogelijke oorzaken
|
|
- Type imports gecheckt
|
|
- MDX dependencies geverifieerd
|
|
- Webpack output geanalyseerd
|
|
|
|
2. **Pattern recognition**
|
|
- Error type wijst naar module loading issues
|
|
- Server/Client boundary is known problem area
|
|
- Default vs named export patterns bekend
|
|
|
|
3. **Documentation**
|
|
- Volledige troubleshooting guide gemaakt
|
|
- Best practices gedocumenteerd
|
|
- Toekomstige problemen sneller op te lossen
|
|
|
|
---
|
|
|
|
## Quick Reference
|
|
|
|
| Symptom | Likely Cause | Solution |
|
|
|---------|--------------|----------|
|
|
| `undefined reading 'call'` | Named export Client in Server | Use wrapper or default export |
|
|
| Intermittent/disappears on refresh | Webpack cache | Clear .next, restart |
|
|
| Only in production build | SSR/hydration mismatch | Check dynamic imports |
|
|
| After HMR (file save) | Fast Refresh issue | Full reload or restart dev |
|
|
|
|
---
|
|
|
|
## Additional Resources
|
|
|
|
**Internal Documentation:**
|
|
- [Troubleshooting Guide](/docs/troubleshooting/webpack-module-resolution-error.md)
|
|
- [Release Notes System Docs](/documentatie/release-notes-system)
|
|
|
|
**External Links:**
|
|
- [Next.js Server Components](https://nextjs.org/docs/app/building-your-application/rendering/server-components)
|
|
- [React Server Components](https://react.dev/reference/rsc/server-components)
|
|
- [Webpack Module Federation](https://webpack.js.org/concepts/module-federation/)
|
|
|
|
---
|
|
|
|
## What's Next
|
|
|
|
**Monitoring:**
|
|
- Watch andere Client Components voor zelfde issue
|
|
- Log webpack errors systematisch
|
|
- Track Next.js updates voor fixes
|
|
|
|
**Improvements:**
|
|
- Refactor high-risk components naar default exports
|
|
- Create ESLint rule om named exports in Client Components te detecteren
|
|
- Add automated tests voor Server/Client boundary issues
|
|
|
|
**Future Prevention:**
|
|
- Template voor nieuwe Client Components met default export
|
|
- Code review checklist voor Server/Client imports
|
|
- Documentation voor team over dit pattern
|