From 50835251891de7244812a5629fb7f120c608b00a Mon Sep 17 00:00:00 2001 From: James Mikrut Date: Fri, 17 May 2024 09:07:18 -0400 Subject: [PATCH] fix: loader support for server-only (#6383) ## Description Allows `server-only` to work within the Payload loader. Fixes https://github.com/payloadcms/payload-3.0-demo/issues/218 --- packages/payload/src/bin/loader/ignores.ts | 1 + packages/payload/src/bin/loader/index.ts | 11 +++++++---- pnpm-lock.yaml | 7 +++++++ test/loader/int.spec.ts | 5 +++++ test/loader/server-only-test.ts | 3 +++ test/package.json | 1 + 6 files changed, 24 insertions(+), 4 deletions(-) create mode 100644 packages/payload/src/bin/loader/ignores.ts create mode 100644 test/loader/server-only-test.ts diff --git a/packages/payload/src/bin/loader/ignores.ts b/packages/payload/src/bin/loader/ignores.ts new file mode 100644 index 0000000000..42fb5dc246 --- /dev/null +++ b/packages/payload/src/bin/loader/ignores.ts @@ -0,0 +1 @@ +export const specifiersToIgnore = ['server-only'] diff --git a/packages/payload/src/bin/loader/index.ts b/packages/payload/src/bin/loader/index.ts index b01fc2e020..7e30b42813 100644 --- a/packages/payload/src/bin/loader/index.ts +++ b/packages/payload/src/bin/loader/index.ts @@ -5,6 +5,7 @@ import { fileURLToPath, pathToFileURL } from 'url' import { CLIENT_EXTENSIONS } from './clientExtensions.js' import { compile } from './compile.js' +import { specifiersToIgnore } from './ignores.js' import { resolveOriginalPath } from './resolveOriginalPath.js' interface ResolveContext { @@ -55,13 +56,15 @@ const TS_EXTENSIONS: string[] = [ export const resolve: ResolveFn = async (specifier, context, nextResolve) => { const isTS = TS_EXTENSIONS.some((ext) => specifier.endsWith(ext)) const isClient = CLIENT_EXTENSIONS.some((ext) => specifier.endsWith(ext)) + const shouldIgnore = specifiersToIgnore.includes(specifier) - // If a client file is resolved, we'll set `format: client` + // If it's a client file, or a file to be ignored is resolved, + // we'll set `format: 'ignore'` // and short circuit, so the load step // will return source code of empty object - if (isClient) { + if (isClient || shouldIgnore) { return { - format: 'client', + format: 'ignore', shortCircuit: true, // No need to resolve the URL using nextResolve. We ignore client files anyway. // Additionally, nextResolve throws an error if the URL is a TS path, so we'd have to use TypeScript's resolveModuleName to resolve the URL, which is unnecessary @@ -147,7 +150,7 @@ const swcOptions = { paths: undefined, } export const load: LoadFn = async (url, context, nextLoad) => { - if (context.format === 'client') { + if (context.format === 'ignore') { const rawSource = 'export default {}' return { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7f08ef0074..df712bb742 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1717,6 +1717,9 @@ importers: payload: specifier: workspace:* version: link:../packages/payload + server-only: + specifier: ^0.0.1 + version: 0.0.1 tempy: specifier: ^1.0.1 version: 1.0.1 @@ -14795,6 +14798,10 @@ packages: - supports-color dev: false + /server-only@0.0.1: + resolution: {integrity: sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA==} + dev: true + /set-function-length@1.2.2: resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} engines: {node: '>= 0.4'} diff --git a/test/loader/int.spec.ts b/test/loader/int.spec.ts index fda76944fa..72b7a80dba 100644 --- a/test/loader/int.spec.ts +++ b/test/loader/int.spec.ts @@ -11,6 +11,11 @@ describe('Loader', () => { expect(code).toStrictEqual(0) }) + it('should import server-only without breaking', async () => { + const code = await startChildProcess('./server-only-test.ts') + expect(code).toStrictEqual(0) + }) + it('should import configs that rely on custom components', async () => { const code = await startChildProcess('../admin/config.ts') expect(code).toStrictEqual(0) diff --git a/test/loader/server-only-test.ts b/test/loader/server-only-test.ts new file mode 100644 index 0000000000..6b7fdbd1c3 --- /dev/null +++ b/test/loader/server-only-test.ts @@ -0,0 +1,3 @@ +import 'server-only' + +console.log('woo') diff --git a/test/package.json b/test/package.json index 7e80805625..877036ff39 100644 --- a/test/package.json +++ b/test/package.json @@ -48,6 +48,7 @@ "execa": "5.1.1", "http-status": "1.6.2", "payload": "workspace:*", + "server-only": "^0.0.1", "tempy": "^1.0.1", "ts-essentials": "7.0.3", "typescript": "5.4.5",