Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 21 additions & 63 deletions packages/next/src/withPayload.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,6 @@ export const withPayload = (nextConfig = {}, options = {}) => {
env.NEXT_PUBLIC_ENABLE_ROUTER_CACHE_REFRESH = 'true'
}

if (process.env.PAYLOAD_PATCH_TURBOPACK_WARNINGS !== 'false') {
const turbopackWarningText =
'Packages that should be external need to be installed in the project directory, so they can be resolved from the output files.\nTry to install it into the project directory by running'

const consoleWarn = console.warn
console.warn = (...args) => {
// Force to disable serverExternalPackages warnings: https://github.com/vercel/next.js/issues/68805
if (
(typeof args[1] === 'string' && args[1].includes(turbopackWarningText)) ||
(typeof args[0] === 'string' && args[0].includes(turbopackWarningText))
) {
return
}

consoleWarn(...args)
}
}

const poweredByHeader = {
key: 'X-Powered-By',
value: 'Next.js, Payload',
Expand Down Expand Up @@ -88,25 +70,32 @@ export const withPayload = (nextConfig = {}, options = {}) => {
},
serverExternalPackages: [
...(nextConfig.serverExternalPackages || []),
'drizzle-kit',
'drizzle-kit/api',
'pino',
'libsql',
'pino-pretty',
'graphql',
// Do not bundle server-only packages during dev to improve compile speed
// These packages always need to be external, both during dev and production. This is because they install dependencies
// that will error when trying to bundle them (e.g. drizzle-kit, libsql, esbuild etc.).
// We cannot externalize those problem-packages directly. We can only externalize packages that are manually installed
// by the end user. Otherwise, the require('externalPackage') calls generated by the bundler would fail during runtime,
// as you cannot import dependencies of dependencies in a lot of package managers like pnpm. We'd have to force users
// to install the dependencies directly.
// Thus, we externalize the "entry-point" = the package that is installed by the end user, which would be our db adapters.
//
//
// External because it installs mongoose (part of default serverExternalPackages: https://github.com/vercel/next.js/blob/canary/packages/next/src/lib/server-external-packages.json => would throw warning if we don't exclude the entry-point package):
'@payloadcms/db-mongodb',
// External because they install dependencies like drizzle, libsql, esbuild etc.:
'@payloadcms/db-postgres',
'@payloadcms/db-sqlite',
'@payloadcms/db-vercel-postgres',
'@payloadcms/drizzle',
// External because they install @aws-sdk/client-s3:
'@payloadcms/payload-cloud',
// TODO: We need to externalize @payloadcms/storage-s3 as well, once Next.js has the ability to exclude @payloadcms/storage-s3/client from being externalized.
// Do not bundle additional server-only packages during dev to improve compilation speed
...(process.env.NODE_ENV === 'development' && options.devBundleServerPackages === false
? [
'payload',
'@payloadcms/db-mongodb',
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are always externalized now, not just during dev, thus the removal

'@payloadcms/db-postgres',
'@payloadcms/db-sqlite',
'@payloadcms/db-vercel-postgres',
'@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
//'@payloadcms/plugin-cloud-storage',
Expand All @@ -129,45 +118,14 @@ export const withPayload = (nextConfig = {}, options = {}) => {

return {
...incomingWebpackConfig,
externals: [
...(incomingWebpackConfig?.externals || []),
'drizzle-kit',
'drizzle-kit/api',
'sharp',
'libsql',
'require-in-the-middle',
],
ignoreWarnings: [
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is probably a relict from the old next-poc branch days. Doubt we'll run into issues now that this is properly externalized. Works fine when testing it. If we do run into issues, we can add it back with a comment.

...(incomingWebpackConfig?.ignoreWarnings || []),
{ module: /node_modules\/mongodb\/lib\/utils\.js/ },
{ file: /node_modules\/mongodb\/lib\/utils\.js/ },
{ module: /node_modules\/mongodb\/lib\/bson\.js/ },
{ file: /node_modules\/mongodb\/lib\/bson\.js/ },
],
externals: [...(incomingWebpackConfig?.externals || []), 'require-in-the-middle'],
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the dependencies in webpack.externals are now always externalized server-side - see serverExternalDependencies.

On the client, those dependencies are (and should) never imported anyways, thus no point in manually declaring them here

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 || {}),
'@aws-sdk/credential-providers': false,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a relict as well. With our clean server-client separation, those dependencies shouldn't sneak into the client bundle anyways.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

webpack also is used for the server-side bundle in nextjs

'@mongodb-js/zstd': false,
aws4: false,
kerberos: false,
'mongodb-client-encryption': false,
snappy: false,
'supports-color': false,
'yocto-queue': false,
},
},
}
},
}
Expand Down
10 changes: 10 additions & 0 deletions test/plugin-multi-tenant/e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -577,17 +577,22 @@ test.describe('Multi Tenant', () => {
page,
serverURL,
})
await wait(1000)

await goToListDoc({
cellClass: '.cell-name',
page,
textToMatch: 'Blue Dog',
urlUtil: tenantsURL,
})
await wait(1000)

await expect(page.locator('#field-name')).toBeVisible()
await page.locator('#field-name').fill('Red Dog')
await wait(1000)

await saveDocAndAssert(page)
await wait(1000)

await page.goto(tenantsURL.list)
// Wait for backend tenant cache to update after save operation
Expand All @@ -599,17 +604,22 @@ test.describe('Multi Tenant', () => {
return (await getTenantOptions({ page })).sort()
})
.toEqual(['Red Dog', 'Steel Cat', 'Public Tenant', 'Anchor Bar'].sort())
await wait(1000)

await goToListDoc({
cellClass: '.cell-name',
page,
textToMatch: 'Red Dog',
urlUtil: tenantsURL,
})
await wait(1000)

// Change the tenant back to the original name
await page.locator('#field-name').fill('Blue Dog')
await wait(1000)

await saveDocAndAssert(page)
await wait(1000)

await page.goto(tenantsURL.list)
// Wait for backend tenant cache to update after save operation
Expand Down
Loading