diff --git a/packages/payload/src/bin/register/index.ts b/packages/payload/src/bin/register/index.ts index ef20abb3b9..a44daa0e18 100644 --- a/packages/payload/src/bin/register/index.ts +++ b/packages/payload/src/bin/register/index.ts @@ -27,7 +27,13 @@ const locatedConfig = getTsconfig() const tsconfig = locatedConfig.config.compilerOptions as unknown as ts.CompilerOptions tsconfig.module = ts.ModuleKind.ESNext -tsconfig.moduleResolution = ts.ModuleResolutionKind.NodeNext + +// Specify bundler resolution for Next.js compatibility. +// We will use TS to resolve file paths for most flexibility +tsconfig.moduleResolution = ts.ModuleResolutionKind.Bundler + +// Don't resolve d.ts files, because we aren't type-checking +tsconfig.noDtsResolution = true const moduleResolutionCache = ts.createModuleResolutionCache( ts.sys.getCurrentDirectory(), @@ -78,16 +84,21 @@ export const resolve: ResolveFn = async (specifier, context, nextResolve) => { ) // import from local project to local project TS file - if ( - resolvedModule && - !resolvedModule.resolvedFileName.includes('/node_modules/') && - EXTENSIONS.includes(resolvedModule.extension) - ) { - return { - format: 'ts', - shortCircuit: true, - url: pathToFileURL(resolvedModule.resolvedFileName).href, + if (resolvedModule) { + const resolvedIsNodeModule = resolvedModule.resolvedFileName.includes('/node_modules/') + const resolvedIsTS = EXTENSIONS.includes(resolvedModule.extension) + + if (!resolvedIsNodeModule && resolvedIsTS) { + return { + format: 'ts', + shortCircuit: true, + url: pathToFileURL(resolvedModule.resolvedFileName).href, + } } + + // We want to use TS "Bundler" moduleResolution for just about all files + // so we pass the TS result here + return nextResolve(pathToFileURL(resolvedModule.resolvedFileName).href) } // import from local project to either: diff --git a/test/config-loader/int.spec.ts b/test/config-loader/int.spec.ts new file mode 100644 index 0000000000..bf3cc1fad6 --- /dev/null +++ b/test/config-loader/int.spec.ts @@ -0,0 +1,8 @@ +import { load } from './load.js' + +describe('Config Loader', () => { + it('should load using TS moduleResolution: bundler', async () => { + const file = await load('./next-navigation-test.js') + expect(typeof file.redirect).toStrictEqual('function') + }) +}) diff --git a/test/config-loader/load.ts b/test/config-loader/load.ts new file mode 100644 index 0000000000..c32f8fd2db --- /dev/null +++ b/test/config-loader/load.ts @@ -0,0 +1,16 @@ +import { register } from 'node:module' +import path from 'node:path' +import { fileURLToPath, pathToFileURL } from 'node:url' + +export const load = async (filePath) => { + const filename = fileURLToPath(import.meta.url) + const dirname = path.dirname(filename) + const url = pathToFileURL(dirname).toString() + '/' + + // Need to register loader from payload/dist for a true test of functionality + register('../../packages/payload/dist/bin/register/index.js', url) + + const result = await import(filePath) + + return result +} diff --git a/test/config-loader/next-navigation-test.js b/test/config-loader/next-navigation-test.js new file mode 100644 index 0000000000..fc44a00f82 --- /dev/null +++ b/test/config-loader/next-navigation-test.js @@ -0,0 +1,3 @@ +import { redirect } from 'next/navigation' + +export { redirect } diff --git a/test/tsconfig.json b/test/tsconfig.json index e2ac241919..cbdf7dc691 100644 --- a/test/tsconfig.json +++ b/test/tsconfig.json @@ -25,6 +25,7 @@ "name": "next" } ], + "baseUrl": ".", "paths": { "@payloadcms/ui/assets": ["./packages/ui/src/assets/index.ts"], "@payloadcms/ui/elements/*": ["./packages/ui/src/elements/*/index.tsx"], diff --git a/tsconfig.json b/tsconfig.json index cb0b346566..99002cb035 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -164,4 +164,4 @@ ".next/types/**/*.ts", "scripts/**/*.ts" ] -} \ No newline at end of file +}