-
Notifications
You must be signed in to change notification settings - Fork 3.7k
Expand file tree
/
Copy pathwithPayload.js
More file actions
293 lines (277 loc) · 12.3 KB
/
withPayload.js
File metadata and controls
293 lines (277 loc) · 12.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
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
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
/**
* These files must remain as plain JavaScript (.js) rather than TypeScript (.ts) because they are
* imported directly in next.config.mjs files. Since next.config files run before the build process,
* TypeScript compilation is not available. This ensures compatibility with all templates and
* user projects regardless of their TypeScript setup.
*/
import {
getNextjsVersion,
supportsServerFastRefreshConfig,
supportsTurbopackExternalizeTransitiveDependencies,
} from './withPayload.utils.js'
import { withPayloadLegacy } from './withPayloadLegacy.js'
const poweredByHeader = {
key: 'X-Powered-By',
value: 'Next.js, Payload',
}
/**
* @param {import('next').NextConfig} nextConfig
* @param {Object} [options] - Optional configuration options
* @param {boolean} [options.devBundleServerPackages] - Whether to bundle server packages in development mode. @default false
* */
export const withPayload = (nextConfig = {}, options = {}) => {
const nextjsVersion = getNextjsVersion()
const supportsTurbopackBuild = supportsTurbopackExternalizeTransitiveDependencies(nextjsVersion)
const hasServerFastRefreshConfigOption = supportsServerFastRefreshConfig(nextjsVersion)
const env = nextConfig.env || {}
if (nextConfig.experimental?.staleTimes?.dynamic) {
console.warn(
'Payload: detected a non-zero value for the `staleTimes.dynamic` option in your Next.js config. This will slow down page transitions and may cause stale data to load within the Admin panel. To clear this warning, remove the `staleTimes.dynamic` option from your Next.js config or set it to 0. In the future, Next.js may support scoping this option to specific routes.',
)
env.NEXT_PUBLIC_ENABLE_ROUTER_CACHE_REFRESH = 'true'
}
if (nextConfig.cacheComponents) {
env.PAYLOAD_CACHE_COMPONENTS_ENABLED = 'true'
}
if (nextjsVersion?.major === 16 && !hasServerFastRefreshConfigOption) {
console.warn(
'Payload: You are using an unsupported Next.js 16 version. You can find the supported Next.js versions here: https://payloadcms.com/docs/getting-started/installation',
)
}
const consoleWarn = console.warn
const sassWarningTexts = [
// This warning is a lie - without silencing import deprecation warnings, sass will spam the console with deprecation warnings
'Future import deprecation is not yet active, so silencing it is unnecessary',
// Sometimes happens despite silenceDeprecations
'The legacy JS API is deprecated and will be removed in Dart Sass 2.0.0',
]
console.warn = (...args) => {
if (
(typeof args[1] === 'string' && sassWarningTexts.some((text) => args[1].includes(text))) ||
(typeof args[0] === 'string' && sassWarningTexts.some((text) => args[0].includes(text)))
) {
return
}
consoleWarn(...args)
}
/** @type {import('next').NextConfig} */
const baseConfig = {
...nextConfig,
env,
experimental: {
...(nextConfig.experimental || {}),
// Server fast refresh breaks HMR
...(hasServerFastRefreshConfigOption ? { enableServerFastRefresh: false } : {}),
},
sassOptions: {
...(nextConfig.sassOptions || {}),
/**
* This prevents scss warning spam during pnpm dev that looks like this:
* ⚠ ./test/admin/components/views/CustomMinimal/index.scss
* Issue while running loader
* SassWarning: Deprecation Warning on line 8, column 8 of file:///Users/alessio/Documents/GitHub/ payload/packages/ui/src/scss/styles.scss:8:8:
* Sass @import rules are deprecated and will be removed in Dart Sass 3.0.0.
*
* More info and automated migrator: https://sass-lang.com/d/import
*
* 8 | @import 'queries';
*
*
* packages/ui/src/scss/styles.scss 9:9 @import
* test/admin/components/views/CustomMinimal/index.scss 1:9 root stylesheet
*
* @todo: update all outdated scss imports to use @use instead of @import. Then, we can remove this.
*/
silenceDeprecations: [...(nextConfig.sassOptions?.silenceDeprecations || []), 'import'],
},
outputFileTracingExcludes: {
...(nextConfig.outputFileTracingExcludes || {}),
'**/*': [
...(nextConfig.outputFileTracingExcludes?.['**/*'] || []),
'drizzle-kit',
'drizzle-kit/api',
],
},
outputFileTracingIncludes: {
...(nextConfig.outputFileTracingIncludes || {}),
'**/*': [...(nextConfig.outputFileTracingIncludes?.['**/*'] || []), '@libsql/client'],
},
turbopack: {
...(nextConfig.turbopack || {}),
},
// We disable the poweredByHeader here because we add it manually in the headers function below
...(nextConfig.poweredByHeader !== false ? { poweredByHeader: false } : {}),
headers: async () => {
const headersFromConfig = 'headers' in nextConfig ? await nextConfig.headers() : []
return [
...(headersFromConfig || []),
{
headers: [
{
key: 'Accept-CH',
value: 'Sec-CH-Prefers-Color-Scheme',
},
{
key: 'Vary',
value: 'Sec-CH-Prefers-Color-Scheme',
},
{
key: 'Critical-CH',
value: 'Sec-CH-Prefers-Color-Scheme',
},
...(nextConfig.poweredByHeader !== false ? [poweredByHeader] : []),
],
source: '/:path*',
},
]
},
serverExternalPackages: [
...(nextConfig.serverExternalPackages || []),
// WHY: without externalizing graphql, a graphql version error will be thrown
// during runtime ("Ensure that there is only one instance of \"graphql\" in the node_modules\ndirectory.")
'graphql',
...(process.env.NODE_ENV === 'development' && options.devBundleServerPackages !== true
? /**
* Unless explicitly disabled by the user, by passing `devBundleServerPackages: true` to withPayload, we
* do not bundle server-only packages during dev for two reasons:
*
* 1. Performance: Fewer files to compile means faster compilation speeds.
* 2. Turbopack support: Webpack's externals are not supported by Turbopack.
*
* Regarding Turbopack support: Unlike webpack.externals, we cannot use serverExternalPackages to
* externalized packages that are not resolvable from the project root. So including a package like
* "drizzle-kit" in here would do nothing - Next.js will ignore the rule and still bundle the package -
* because it detects that the package is not resolvable from the project root (= not directly installed
* by the user in their own package.json).
*
* Instead, we can use serverExternalPackages for the entry-point packages that *are* installed directly
* by the user (e.g. db-postgres, which then installs drizzle-kit as a dependency).
*
*
*
* We should only do this during development, not build, because externalizing these packages can hurt
* the bundle size. Not only does it disable tree-shaking, it also risks installing duplicate copies of the
* same package.
*
* Example:
* - @payloadcms/richtext-lexical (in bundle) -> installs qs-esm (bundled because of importer)
* - payload (not in bundle, external) -> installs qs-esm (external because of importer)
* Result: we have two copies of qs-esm installed - one in the bundle, and one in node_modules.
*
* During development, these bundle size difference do not matter much, and development speed /
* turbopack support are more important.
*/
[
'payload',
'@payloadcms/db-mongodb',
'@payloadcms/db-postgres',
'@payloadcms/db-sqlite',
'@payloadcms/db-vercel-postgres',
'@payloadcms/db-d1-sqlite',
'@payloadcms/drizzle',
'@payloadcms/email-nodemailer',
'@payloadcms/email-resend',
'@payloadcms/graphql',
'@payloadcms/payload-cloud',
'@payloadcms/plugin-redirects',
// TODO: Add the following packages, excluding their /client subpath exports, once Next.js supports it
// see: https://github.com/vercel/next.js/discussions/76991
//'@payloadcms/plugin-cloud-storage',
//'@payloadcms/plugin-sentry',
//'@payloadcms/plugin-stripe',
// @payloadcms/richtext-lexical
//'@payloadcms/storage-azure',
//'@payloadcms/storage-gcs',
//'@payloadcms/storage-s3',
//'@payloadcms/storage-uploadthing',
//'@payloadcms/storage-vercel-blob',
]
: []),
],
webpack: (webpackConfig, webpackOptions) => {
const incomingWebpackConfig =
typeof nextConfig.webpack === 'function'
? nextConfig.webpack(webpackConfig, webpackOptions)
: webpackConfig
return {
...incomingWebpackConfig,
externals: [
...(incomingWebpackConfig?.externals || []),
/**
* See the explanation in the serverExternalPackages section above.
* We need to force Webpack to emit require() calls for these packages, even though they are not
* resolvable from the project root. You would expect this to error during runtime, but Next.js seems to be able to require these just fine.
*
* This is the only way to get Webpack Build to work, without the bundle size caveats of externalizing the
* entry point packages, as explained in the serverExternalPackages section above.
*/
'drizzle-kit',
'drizzle-kit/api',
'sharp',
'libsql',
'require-in-the-middle',
'json-schema-to-typescript',
],
plugins: [
...(incomingWebpackConfig?.plugins || []),
// Fix cloudflare:sockets error: https://github.com/vercel/next.js/discussions/50177
new webpackOptions.webpack.IgnorePlugin({
resourceRegExp: /^pg-native$|^cloudflare:sockets$/,
}),
],
resolve: {
...(incomingWebpackConfig?.resolve || {}),
alias: {
...(incomingWebpackConfig?.resolve?.alias || {}),
},
fallback: {
...(incomingWebpackConfig?.resolve?.fallback || {}),
/*
* This fixes the following warning when running next build with webpack (tested on Next.js 16.0.3 with Payload 3.64.0):
*
* ⚠ Compiled with warnings in 8.7s
*
* ./node_modules/.pnpm/mongodb@6.16.0/node_modules/mongodb/lib/deps.js
* Module not found: Can't resolve 'aws4' in '/Users/alessio/Documents/temp/next16p/node_modules/.pnpm/mongodb@6.16.0/node_modules/mongodb/lib'
*
* Import trace for requested module:
* ./node_modules/.pnpm/mongodb@6.16.0/node_modules/mongodb/lib/deps.js
* ./node_modules/.pnpm/mongodb@6.16.0/node_modules/mongodb/lib/client-side-encryption/client_encryption.js
* ./node_modules/.pnpm/mongodb@6.16.0/node_modules/mongodb/lib/index.js
* ./node_modules/.pnpm/mongoose@8.15.1/node_modules/mongoose/lib/index.js
* ./node_modules/.pnpm/mongoose@8.15.1/node_modules/mongoose/index.js
* ./node_modules/.pnpm/@payloadcms+db-mongodb@3.64.0_payload@3.64.0_graphql@16.12.0_typescript@5.7.3_/node_modules/@payloadcms/db-mongodb/dist/index.js
* ./src/payload.config.ts
* ./src/app/my-route/route.ts
*
**/
aws4: false,
},
},
}
},
}
if (nextConfig.basePath) {
process.env.NEXT_BASE_PATH = nextConfig.basePath
baseConfig.env.NEXT_BASE_PATH = nextConfig.basePath
}
if (!supportsTurbopackBuild) {
return withPayloadLegacy(baseConfig)
} else {
return {
...baseConfig,
serverExternalPackages: [
...(baseConfig.serverExternalPackages || []),
'drizzle-kit',
'drizzle-kit/api',
'sharp',
'libsql',
'require-in-the-middle',
'json-schema-to-typescript',
// Prevents turbopack build errors by the thread-stream package which is installed by pino
'pino',
],
}
}
}
export default withPayload