Skip to content

Commit c7bb694

Browse files
authored
perf: 50% faster compilation speed by skipping bundling of server-only packages during dev (#11594)
This PR skips bundling server-only payload packages during development, which results in 50% faster compilation speeds using turbo. Test results using our blank template (both /api and /admin): Webpack before: 11.5 Webpack now: 7.1s => 38% faster compilation speed Turbopack before: 4.1s Turbopack after: 2.1s => 50% faster compilation speed
1 parent 8f3d1bd commit c7bb694

File tree

13 files changed

+127
-93
lines changed

13 files changed

+127
-93
lines changed

next.config.mjs

Lines changed: 46 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -12,54 +12,57 @@ const withBundleAnalyzer = bundleAnalyzer({
1212
})
1313

1414
const config = withBundleAnalyzer(
15-
withPayload({
16-
eslint: {
17-
ignoreDuringBuilds: true,
18-
},
19-
typescript: {
20-
ignoreBuildErrors: true,
21-
},
22-
experimental: {
23-
fullySpecified: true,
24-
serverActions: {
25-
bodySizeLimit: '5mb',
15+
withPayload(
16+
{
17+
eslint: {
18+
ignoreDuringBuilds: true,
2619
},
27-
},
28-
env: {
29-
PAYLOAD_CORE_DEV: 'true',
30-
ROOT_DIR: path.resolve(dirname),
31-
// @todo remove in 4.0 - will behave like this by default in 4.0
32-
PAYLOAD_DO_NOT_SANITIZE_LOCALIZED_PROPERTY: 'true',
33-
},
34-
async redirects() {
35-
return [
36-
{
37-
destination: '/admin',
38-
permanent: false,
39-
source: '/',
20+
typescript: {
21+
ignoreBuildErrors: true,
22+
},
23+
experimental: {
24+
fullySpecified: true,
25+
serverActions: {
26+
bodySizeLimit: '5mb',
4027
},
41-
]
42-
},
43-
images: {
44-
domains: ['localhost'],
45-
},
46-
webpack: (webpackConfig) => {
47-
webpackConfig.resolve.extensionAlias = {
48-
'.cjs': ['.cts', '.cjs'],
49-
'.js': ['.ts', '.tsx', '.js', '.jsx'],
50-
'.mjs': ['.mts', '.mjs'],
51-
}
28+
},
29+
env: {
30+
PAYLOAD_CORE_DEV: 'true',
31+
ROOT_DIR: path.resolve(dirname),
32+
// @todo remove in 4.0 - will behave like this by default in 4.0
33+
PAYLOAD_DO_NOT_SANITIZE_LOCALIZED_PROPERTY: 'true',
34+
},
35+
async redirects() {
36+
return [
37+
{
38+
destination: '/admin',
39+
permanent: false,
40+
source: '/',
41+
},
42+
]
43+
},
44+
images: {
45+
domains: ['localhost'],
46+
},
47+
webpack: (webpackConfig) => {
48+
webpackConfig.resolve.extensionAlias = {
49+
'.cjs': ['.cts', '.cjs'],
50+
'.js': ['.ts', '.tsx', '.js', '.jsx'],
51+
'.mjs': ['.mts', '.mjs'],
52+
}
5253

53-
// Ignore sentry warnings when not wrapped with withSentryConfig
54-
webpackConfig.ignoreWarnings = [
55-
...(webpackConfig.ignoreWarnings ?? []),
56-
{ file: /esm\/platform\/node\/instrumentation.js/ },
57-
{ module: /esm\/platform\/node\/instrumentation.js/ },
58-
]
54+
// Ignore sentry warnings when not wrapped with withSentryConfig
55+
webpackConfig.ignoreWarnings = [
56+
...(webpackConfig.ignoreWarnings ?? []),
57+
{ file: /esm\/platform\/node\/instrumentation.js/ },
58+
{ module: /esm\/platform\/node\/instrumentation.js/ },
59+
]
5960

60-
return webpackConfig
61+
return webpackConfig
62+
},
6163
},
62-
}),
64+
{ devBundleServerPackages: false },
65+
),
6366
)
6467

6568
export default process.env.NEXT_PUBLIC_SENTRY_DSN

packages/next/src/withPayload.js

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
/**
22
* @param {import('next').NextConfig} nextConfig
3+
* @param {Object} [options] - Optional configuration options
4+
* @param {boolean} [options.devBundleServerPackages] - Whether to bundle server packages in development mode. @default true
35
*
46
* @returns {import('next').NextConfig}
57
* */
6-
export const withPayload = (nextConfig = {}) => {
8+
export const withPayload = (nextConfig = {}, options = {}) => {
79
const env = nextConfig?.env || {}
810

911
if (nextConfig.experimental?.staleTimes?.dynamic) {
@@ -99,6 +101,32 @@ export const withPayload = (nextConfig = {}) => {
99101
'libsql',
100102
'pino-pretty',
101103
'graphql',
104+
// Do not bundle server-only packages during dev to improve compile speed
105+
...(process.env.npm_lifecycle_event === 'dev' && options.devBundleServerPackages === false
106+
? [
107+
'payload',
108+
'@payloadcms/db-mongodb',
109+
'@payloadcms/db-postgres',
110+
'@payloadcms/db-sqlite',
111+
'@payloadcms/db-vercel-postgres',
112+
'@payloadcms/drizzle',
113+
'@payloadcms/email-nodemailer',
114+
'@payloadcms/email-resend',
115+
'@payloadcms/graphql',
116+
'@payloadcms/payload-cloud',
117+
'@payloadcms/plugin-cloud-storage',
118+
'@payloadcms/plugin-redirects',
119+
'@payloadcms/plugin-sentry',
120+
'@payloadcms/plugin-stripe',
121+
// TODO: Add the following packages, excluding their /client subpath exports, once Next.js supports it
122+
// @payloadcms/richtext-lexical
123+
//'@payloadcms/storage-azure',
124+
//'@payloadcms/storage-gcs',
125+
//'@payloadcms/storage-s3',
126+
//'@payloadcms/storage-uploadthing',
127+
//'@payloadcms/storage-vercel-blob',
128+
]
129+
: []),
102130
],
103131
webpack: (webpackConfig, webpackOptions) => {
104132
const incomingWebpackConfig =

packages/payload-cloud/src/utilities/refreshSession.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import { CognitoIdentityClient } from '@aws-sdk/client-cognito-identity'
2-
import * as AWS from '@aws-sdk/client-s3'
2+
import { S3 } from '@aws-sdk/client-s3'
33
import { fromCognitoIdentityPool } from '@aws-sdk/credential-providers'
44

55
import { authAsCognitoUser } from './authAsCognitoUser.js'
66

77
export type GetStorageClient = () => Promise<{
88
identityID: string
9-
storageClient: AWS.S3
9+
storageClient: S3
1010
}>
1111

1212
export const refreshSession = async () => {
@@ -33,7 +33,7 @@ export const refreshSession = async () => {
3333
// @ts-expect-error - Incorrect AWS types
3434
const identityID = credentials.identityId
3535

36-
const storageClient = new AWS.S3({
36+
const storageClient = new S3({
3737
credentials,
3838
region: process.env.PAYLOAD_CLOUD_BUCKET_REGION,
3939
})

templates/_template/next.config.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ const nextConfig = {
55
// Your Next.js config here
66
}
77

8-
export default withPayload(nextConfig)
8+
export default withPayload(nextConfig, { devBundleServerPackages: false })

templates/blank/next.config.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ const nextConfig = {
55
// Your Next.js config here
66
}
77

8-
export default withPayload(nextConfig)
8+
export default withPayload(nextConfig, { devBundleServerPackages: false })

templates/plugin/dev/next.config.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,4 @@ const nextConfig = {
1818
// transpilePackages: ['../src'],
1919
}
2020

21-
export default withPayload(nextConfig)
21+
export default withPayload(nextConfig, { devBundleServerPackages: false })

templates/website/next.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,4 @@ const nextConfig = {
2424
redirects,
2525
}
2626

27-
export default withPayload(nextConfig)
27+
export default withPayload(nextConfig, { devBundleServerPackages: false })

templates/with-payload-cloud/next.config.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ const nextConfig = {
55
// Your Next.js config here
66
}
77

8-
export default withPayload(nextConfig)
8+
export default withPayload(nextConfig, { devBundleServerPackages: false })

templates/with-postgres/next.config.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ const nextConfig = {
55
// Your Next.js config here
66
}
77

8-
export default withPayload(nextConfig)
8+
export default withPayload(nextConfig, { devBundleServerPackages: false })

templates/with-vercel-mongodb/next.config.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ const nextConfig = {
55
// Your Next.js config here
66
}
77

8-
export default withPayload(nextConfig)
8+
export default withPayload(nextConfig, { devBundleServerPackages: false })

templates/with-vercel-postgres/next.config.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ const nextConfig = {
55
// Your Next.js config here
66
}
77

8-
export default withPayload(nextConfig)
8+
export default withPayload(nextConfig, { devBundleServerPackages: false })

templates/with-vercel-website/next.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,4 @@ const nextConfig = {
2424
redirects,
2525
}
2626

27-
export default withPayload(nextConfig)
27+
export default withPayload(nextConfig, { devBundleServerPackages: false })

test/next.config.mjs

Lines changed: 40 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -12,45 +12,48 @@ const withBundleAnalyzer = bundleAnalyzer({
1212
})
1313

1414
export default withBundleAnalyzer(
15-
withPayload({
16-
eslint: {
17-
ignoreDuringBuilds: true,
18-
},
19-
typescript: {
20-
ignoreBuildErrors: true,
21-
},
22-
experimental: {
23-
fullySpecified: true,
24-
serverActions: {
25-
bodySizeLimit: '5mb',
15+
withPayload(
16+
{
17+
eslint: {
18+
ignoreDuringBuilds: true,
2619
},
27-
},
28-
env: {
29-
PAYLOAD_CORE_DEV: 'true',
30-
ROOT_DIR: path.resolve(dirname),
31-
// @todo remove in 4.0 - will behave like this by default in 4.0
32-
PAYLOAD_DO_NOT_SANITIZE_LOCALIZED_PROPERTY: 'true',
33-
},
34-
async redirects() {
35-
return [
36-
{
37-
destination: '/admin',
38-
permanent: true,
39-
source: '/',
20+
typescript: {
21+
ignoreBuildErrors: true,
22+
},
23+
experimental: {
24+
fullySpecified: true,
25+
serverActions: {
26+
bodySizeLimit: '5mb',
4027
},
41-
]
42-
},
43-
images: {
44-
domains: ['localhost'],
45-
},
46-
webpack: (webpackConfig) => {
47-
webpackConfig.resolve.extensionAlias = {
48-
'.cjs': ['.cts', '.cjs'],
49-
'.js': ['.ts', '.tsx', '.js', '.jsx'],
50-
'.mjs': ['.mts', '.mjs'],
51-
}
28+
},
29+
env: {
30+
PAYLOAD_CORE_DEV: 'true',
31+
ROOT_DIR: path.resolve(dirname),
32+
// @todo remove in 4.0 - will behave like this by default in 4.0
33+
PAYLOAD_DO_NOT_SANITIZE_LOCALIZED_PROPERTY: 'true',
34+
},
35+
async redirects() {
36+
return [
37+
{
38+
destination: '/admin',
39+
permanent: true,
40+
source: '/',
41+
},
42+
]
43+
},
44+
images: {
45+
domains: ['localhost'],
46+
},
47+
webpack: (webpackConfig) => {
48+
webpackConfig.resolve.extensionAlias = {
49+
'.cjs': ['.cts', '.cjs'],
50+
'.js': ['.ts', '.tsx', '.js', '.jsx'],
51+
'.mjs': ['.mts', '.mjs'],
52+
}
5253

53-
return webpackConfig
54+
return webpackConfig
55+
},
5456
},
55-
}),
57+
{ devBundleServerPackages: false },
58+
),
5659
)

0 commit comments

Comments
 (0)