Commit c484a05
authored
fix(next): remove turbopack build support to fix bundle size regression (#14696)
## Background
The following PRs attempted to add support for Turbopack build:
- #14475
- #14473
## The Fundamental Problem
Payload's database adapters (e.g., `@payloadcms/db-postgres`) depend on
packages with native dependencies that cannot be bundled (e.g.,
`drizzle-kit`, which imports `esbuild`). We need to externalize these
packages.
**Why we can't externalize them directly:**
With pnpm, externalizing a package like `drizzle-kit` generates
`require('drizzle-kit')` calls in the bundle. However, `drizzle-kit` is
not in the user's `package.json` (it's a transitive dependency installed
by `db-postgres`). pnpm's strict dependency isolation prevents importing
dependencies of dependencies, causing runtime failures.
**The attempted workaround:**
Instead of externalizing `drizzle-kit`, we tried externalizing the
entry-point package `@payloadcms/db-postgres` (which users DO install)
via `serverExternalPackages`. This works in development, but creates
severe issues in production builds.
## Why the Workaround Failed
When you externalize `@payloadcms/db-postgres`:
1. **Everything it imports becomes external**, including `payload`
itself
2. This creates **two copies of `payload`**:
- One bundled (from user's direct imports)
- One external in node_modules (from db-postgres's imports)
3. **Bundle size explodes** due to:
- Disabled tree-shaking for externalized packages
- Duplicate package installations
- Loss of code-splitting optimizations
**Another example of duplication:**
```
@payloadcms/richtext-lexical (bundled) → qs-esm (bundled)
payload (external) → qs-esm (external)
Result: Two copies of qs-esm in production
```
This issue was reported on our discord
[here](https://discord.com/channels/967097582721572934/1422639568808841329/1440689060015374437).
## The Solution (This PR)
**Short term:** Disable Turbopack build support until Next.js provides a
proper solution.
### Why Webpack Works
Webpack has `webpack.externals`, which can externalize **any** package
regardless of whether it's in the user's `package.json`:
- We externalize `drizzle-kit` directly via `webpack.externals`
- Webpack generates `require('drizzle-kit')` calls in the bundle
- At runtime, Node.js resolves these just fine - we're not yet sure why
that is
- We avoid externalizing entry-point packages, preventing the
duplication problem
### Why Turbopack Build Doesn't Work
Turbopack only has `serverExternalPackages` (similar to
webpack.externals but with restrictions):
- **The constraint**: Packages must be resolvable from the project root
(i.e., in the user's `package.json`)
- If a package isn't directly installed by the user, Next.js **ignores
the externalization rule** and tries to bundle it anyway
- This forces us to externalize entry-point packages (`db-postgres`),
which causes the duplication and bundle size problems described above
### Why Turbopack Dev Works
Turbopack dev has the same `serverExternalPackages` constraint, BUT:
- **In dev, we can afford the trade-off** of externalizing entry-point
packages because:
- Bundle size doesn't matter in development
- Faster compilation speed is more important
- We're not shipping to production
- The duplication problem still exists, but it's acceptable for the dev
experience
**Changes made:**
1. **Throw error for Turbopack builds** - Prevent production builds with
Turbopack until Next.js fixes the underlying issue
2. **Restore webpack.externals** - Use webpack-specific externals for
problematic transitive dependencies (`drizzle-kit`, `sharp`, `libsql`,
etc.) that aren't in user's package.json
3. **Simplify serverExternalPackages** - Only externalize packages
resolvable from project root (`graphql`, `@sentry/nextjs`)
4. **Clean up unnecessary config** - Remove webpack configurations that
are no longer justifiable. Any configuration we have left now comes with
a comment block explaining why we need it
5. **enable devBundleServerPackages optimization by default** - there
have not been any reported issues since this was introduced, and this
setting is now **necessary** for turbopack support during dev
## Future
In order to properly support Turbopack Build, Next.js will have to
implement one of these solutions:
- **Option 1**: Implement webpack.externals-like functionality for
Turbopack (no package.json constraint)
- **Option 2**: Remove the need for declaring all externals as direct
dependencies in the application
We're tracking Next.js's progress on this issue.1 parent a3f490b commit c484a05
1 file changed
+101
-27
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
4 | | - | |
| 4 | + | |
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
| |||
52 | 52 | | |
53 | 53 | | |
54 | 54 | | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
55 | 65 | | |
56 | 66 | | |
57 | 67 | | |
| |||
106 | 116 | | |
107 | 117 | | |
108 | 118 | | |
| 119 | + | |
| 120 | + | |
109 | 121 | | |
110 | | - | |
111 | | - | |
112 | | - | |
113 | | - | |
114 | | - | |
115 | | - | |
116 | | - | |
117 | | - | |
| 122 | + | |
118 | 123 | | |
119 | | - | |
120 | | - | |
121 | | - | |
122 | | - | |
123 | | - | |
124 | | - | |
125 | | - | |
126 | | - | |
127 | | - | |
128 | | - | |
129 | | - | |
130 | | - | |
131 | | - | |
132 | 124 | | |
133 | 125 | | |
134 | 126 | | |
135 | | - | |
136 | | - | |
137 | | - | |
138 | | - | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
139 | 161 | | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
140 | 168 | | |
141 | 169 | | |
142 | 170 | | |
| 171 | + | |
143 | 172 | | |
144 | 173 | | |
| 174 | + | |
145 | 175 | | |
146 | 176 | | |
147 | 177 | | |
| |||
162 | 192 | | |
163 | 193 | | |
164 | 194 | | |
165 | | - | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
166 | 240 | | |
167 | 241 | | |
168 | 242 | | |
| |||
0 commit comments