From 3e7f96e16a07e592461b597491c2adb2e081f6ae Mon Sep 17 00:00:00 2001 From: Jimmy Lai Date: Thu, 26 Oct 2023 04:37:13 -0700 Subject: [PATCH] revert "Apply react-server condition for pages api (#57459)" (#57500) This reverts commit 6b18f397cb40199b688111236d47af83f9b3b408. --- packages/next/src/build/webpack-config.ts | 26 ++++--- .../rsc-basic/pages/api/import-test.js | 4 ++ test/e2e/module-layer/index.test.ts | 72 ++++++++++--------- test/e2e/module-layer/pages/api/mixed.js | 2 +- 4 files changed, 59 insertions(+), 45 deletions(-) diff --git a/packages/next/src/build/webpack-config.ts b/packages/next/src/build/webpack-config.ts index 53b1ee50da..1113116f49 100644 --- a/packages/next/src/build/webpack-config.ts +++ b/packages/next/src/build/webpack-config.ts @@ -454,12 +454,13 @@ export default async function getBaseWebpackConfig( ].filter(Boolean) : [] - const swcLoaderForMiddlewareLayer = - // When using Babel, we will have to use SWC to do the optimization - // for middleware to tree shake the unused default optimized imports like "next/server". - // This will cause some performance overhead but - // acceptable as Babel will not be recommended. - [swcServerLayerLoader, babelLoader].filter(Boolean) + const swcLoaderForMiddlewareLayer = useSWCLoader + ? swcServerLayerLoader + : // When using Babel, we will have to use SWC to do the optimization + // for middleware to tree shake the unused default optimized imports like "next/server". + // This will cause some performance overhead but + // acceptable as Babel will not be recommended. + [swcServerLayerLoader, babelLoader] // client components layers: SSR + browser const swcLoaderForClientLayer = [ @@ -487,9 +488,16 @@ export default async function getBaseWebpackConfig( : []), ] - // Loader for API routes will also apply react-server export condition for bundling, - // and the API checks for server side only APIs. - const loaderForAPIRoutes = [swcServerLayerLoader, babelLoader].filter(Boolean) + // Loader for API routes needs to be differently configured as it shouldn't + // have RSC transpiler enabled, so syntax checks such as invalid imports won't + // be performed. + const loaderForAPIRoutes = + hasAppDir && useSWCLoader + ? getSwcLoader({ + serverComponents: false, + isReactServerLayer: false, + }) + : defaultLoaders.babel const pageExtensions = config.pageExtensions diff --git a/test/e2e/app-dir/rsc-basic/pages/api/import-test.js b/test/e2e/app-dir/rsc-basic/pages/api/import-test.js index 403ebab5f8..70e48bc0d8 100644 --- a/test/e2e/app-dir/rsc-basic/pages/api/import-test.js +++ b/test/e2e/app-dir/rsc-basic/pages/api/import-test.js @@ -1,3 +1,7 @@ +// You can still import React and Next's client component APIs from the server +// they won't be poisoned by the environment. +// eslint-disable-next-line no-unused-vars +import { useState } from 'react' import 'next/headers' export default function (_, res) { diff --git a/test/e2e/module-layer/index.test.ts b/test/e2e/module-layer/index.test.ts index 32bc4a65e5..701050aaaa 100644 --- a/test/e2e/module-layer/index.test.ts +++ b/test/e2e/module-layer/index.test.ts @@ -1,5 +1,5 @@ import { createNextDescribe } from 'e2e-utils' -import { check, getRedboxSource, hasRedbox } from 'next-test-utils' +import { getRedboxSource, hasRedbox } from 'next-test-utils' createNextDescribe( 'module layer', @@ -68,49 +68,51 @@ createNextDescribe( // Should error for using mixed (with client-only) in server targets if (isNextDev) { describe('no server-only in server targets', () => { - it('should error when import client-only in middleware', async () => { - const middlewareFile = 'middleware.js' - const middlewareContent = await next.readFile(middlewareFile) + const middlewareFile = 'middleware.js' + // const pagesApiFile = 'pages/api/hello.js' + let middlewareContent = '' + // let pagesApiContent = '' + + beforeAll(async () => { + await next.stop() + + middlewareContent = await next.readFile(middlewareFile) + // pagesApiContent = await next.readFile(pagesApiFile) + await next.patchFile( middlewareFile, - middlewareContent.replace( - "// import './lib/mixed-lib'", - "import './lib/mixed-lib'" - ) + middlewareContent + // .replace("import 'server-only'", "// import 'server-only'") + .replace( + "// import './lib/mixed-lib'", + "import './lib/mixed-lib'" + ) ) + + // await next.patchFile( + // pagesApiFile, + // pagesApiContent + // .replace("import 'server-only'", "// import 'server-only'") + // .replace( + // "// import '../../lib/mixed-lib'", + // "import '../../lib/mixed-lib'" + // ) + // ) + + await next.start() + }) + afterAll(async () => { + await next.patchFile(middlewareFile, middlewareContent) + // await next.patchFile(pagesApiFile, pagesApiContent) + }) + + it('should error when import client-only in middleware', async () => { const browser = await next.browser('/') expect(await hasRedbox(browser, true)).toBe(true) expect(await getRedboxSource(browser)).toContain( `You're importing a component that imports client-only. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components by default.` ) - - await next.patchFile(middlewareFile, middlewareContent) - }) - - it('should error when import client-only in pages/api', async () => { - const pagesApiFile = 'pages/api/mixed.js' - const pagesApiContent = await next.readFile(pagesApiFile) - await next.patchFile( - pagesApiFile, - pagesApiContent.replace( - "// import 'client-only'", - "import 'client-only'" - ) - ) - - const existingCliOutputLength = next.cliOutput.length - await check(async () => { - await next.fetch('/api/mixed') - const newCliOutput = next.cliOutput.slice(existingCliOutputLength) - expect(newCliOutput).toContain('./pages/api/mixed.js') - expect(newCliOutput).toContain( - `You're importing a component that imports client-only. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components by default.` - ) - return 'success' - }, 'success') - - await next.patchFile(pagesApiFile, pagesApiContent) }) }) } diff --git a/test/e2e/module-layer/pages/api/mixed.js b/test/e2e/module-layer/pages/api/mixed.js index a56f2a0890..d49398953e 100644 --- a/test/e2e/module-layer/pages/api/mixed.js +++ b/test/e2e/module-layer/pages/api/mixed.js @@ -1,4 +1,4 @@ -// import 'client-only' +import '../../lib/mixed-lib' export default function handler(req, res) { return res.send('pages/api/mixed.js:')