diff --git a/packages/next/package.json b/packages/next/package.json index c4816823dc67f1f..97f3931582f7560 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -78,7 +78,7 @@ "@swc/helpers": "0.4.11", "caniuse-lite": "^1.0.30001406", "postcss": "8.4.14", - "styled-jsx": "5.0.7", + "styled-jsx": "5.1.0", "use-sync-external-store": "1.2.0" }, "peerDependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 80fb5e9a4d65767..3a816b0eb712487 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -614,7 +614,7 @@ importers: string_decoder: 1.3.0 string-hash: 1.1.3 strip-ansi: 6.0.0 - styled-jsx: 5.0.7 + styled-jsx: 5.1.0 tar: 6.1.11 taskr: 1.1.0 terser: 5.14.1 @@ -639,7 +639,7 @@ importers: '@swc/helpers': 0.4.11 caniuse-lite: 1.0.30001406 postcss: 8.4.14 - styled-jsx: 5.0.7_uuaxwgga6hqycsez5ok7v2wg4i + styled-jsx: 5.1.0_uuaxwgga6hqycsez5ok7v2wg4i use-sync-external-store: 1.2.0_react@18.2.0 devDependencies: '@ampproject/toolbox-optimizer': 2.8.3 @@ -11097,6 +11097,13 @@ packages: } engines: { node: '>= 10' } + /client-only/0.0.1: + resolution: + { + integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==, + } + dev: false + /cliui/5.0.0: resolution: { @@ -28106,10 +28113,10 @@ packages: postcss-load-plugins: 2.3.0 dev: true - /styled-jsx/5.0.7_uuaxwgga6hqycsez5ok7v2wg4i: + /styled-jsx/5.1.0_uuaxwgga6hqycsez5ok7v2wg4i: resolution: { - integrity: sha512-b3sUzamS086YLRuvnaDigdAewz1/EFYlHpYBP5mZovKEdQQOIIYq8lApylub3HHZ6xFjV051kkGU7cudJmrXEA==, + integrity: sha512-/iHaRJt9U7T+5tp6TRelLnqBqiaIT0HsO0+vgyj8hK2KUk7aejFqRrumqPUlAqDwAj8IbS/1hk3IhBAAK/FCUQ==, } engines: { node: '>= 12.0.0' } peerDependencies: @@ -28123,6 +28130,7 @@ packages: optional: true dependencies: '@babel/core': 7.18.0 + client-only: 0.0.1 react: 18.2.0 dev: false diff --git a/test/e2e/app-dir/index.test.ts b/test/e2e/app-dir/index.test.ts index 534af0ebfe8890c..ffb63348233520d 100644 --- a/test/e2e/app-dir/index.test.ts +++ b/test/e2e/app-dir/index.test.ts @@ -1240,62 +1240,6 @@ describe('app dir', () => { await next.patchFile(filePath, origContent) } }) - - it('should throw an error when getServerSideProps is used', async () => { - const pageFile = - 'app/client-with-errors/get-server-side-props/page.js' - const content = await next.readFile(pageFile) - const uncomment = content.replace( - '// export function getServerSideProps', - 'export function getServerSideProps' - ) - await next.patchFile(pageFile, uncomment) - const res = await fetchViaHTTP( - next.url, - '/client-with-errors/get-server-side-props' - ) - await next.patchFile(pageFile, content) - - await check(async () => { - const { status } = await fetchViaHTTP( - next.url, - '/client-with-errors/get-server-side-props' - ) - return status - }, /200/) - - expect(res.status).toBe(500) - expect(await res.text()).toContain( - '`getServerSideProps` is not allowed in Client Components' - ) - }) - - it('should throw an error when getStaticProps is used', async () => { - const pageFile = 'app/client-with-errors/get-static-props/page.js' - const content = await next.readFile(pageFile) - const uncomment = content.replace( - '// export function getStaticProps', - 'export function getStaticProps' - ) - await next.patchFile(pageFile, uncomment) - const res = await fetchViaHTTP( - next.url, - '/client-with-errors/get-static-props' - ) - await next.patchFile(pageFile, content) - await check(async () => { - const { status } = await fetchViaHTTP( - next.url, - '/client-with-errors/get-static-props' - ) - return status - }, /200/) - - expect(res.status).toBe(500) - expect(await res.text()).toContain( - '`getStaticProps` is not allowed in Client Components' - ) - }) } }) diff --git a/test/e2e/app-dir/rsc-errors.test.ts b/test/e2e/app-dir/rsc-errors.test.ts new file mode 100644 index 000000000000000..5526ad382602481 --- /dev/null +++ b/test/e2e/app-dir/rsc-errors.test.ts @@ -0,0 +1,92 @@ +import path from 'path' +import { check, fetchViaHTTP, renderViaHTTP } from 'next-test-utils' +import { createNext, FileRef } from 'e2e-utils' +import { NextInstance } from 'test/lib/next-modes/base' + +describe('app dir - rsc basics', () => { + let next: NextInstance + + const { isNextDeploy, isNextDev } = global as any + const isReact17 = process.env.NEXT_TEST_REACT_VERSION === '^17' + if (isNextDeploy || isReact17) { + it('should skip tests for next-deploy and react 17', () => {}) + return + } + if (!isNextDev) { + it('should skip tests for next-start', () => {}) + return + } + + beforeAll(async () => { + next = await createNext({ + files: new FileRef(path.join(__dirname, './rsc-errors')), + dependencies: { + react: 'experimental', + 'react-dom': 'experimental', + }, + }) + }) + afterAll(() => next.destroy()) + + it('should throw an error when getServerSideProps is used', async () => { + const pageFile = 'app/client-with-errors/get-server-side-props/page.js' + const content = await next.readFile(pageFile) + const uncomment = content.replace( + '// export function getServerSideProps', + 'export function getServerSideProps' + ) + await next.patchFile(pageFile, uncomment) + const res = await fetchViaHTTP( + next.url, + '/client-with-errors/get-server-side-props' + ) + await next.patchFile(pageFile, content) + + await check(async () => { + const { status } = await fetchViaHTTP( + next.url, + '/client-with-errors/get-server-side-props' + ) + return status + }, /200/) + + expect(res.status).toBe(500) + expect(await res.text()).toContain( + '`getServerSideProps` is not allowed in Client Components' + ) + }) + + it('should throw an error when getStaticProps is used', async () => { + const pageFile = 'app/client-with-errors/get-static-props/page.js' + const content = await next.readFile(pageFile) + const uncomment = content.replace( + '// export function getStaticProps', + 'export function getStaticProps' + ) + await next.patchFile(pageFile, uncomment) + const res = await fetchViaHTTP( + next.url, + '/client-with-errors/get-static-props' + ) + await next.patchFile(pageFile, content) + await check(async () => { + const { status } = await fetchViaHTTP( + next.url, + '/client-with-errors/get-static-props' + ) + return status + }, /200/) + + expect(res.status).toBe(500) + expect(await res.text()).toContain( + '`getStaticProps` is not allowed in Client Components' + ) + }) + + it('should error for styled-jsx imports on server side', async () => { + const html = await renderViaHTTP(next.url, '/server-with-errors/styled-jsx') + expect(html).toContain( + 'This module cannot be imported from a Server Component module. It should only be used from a Client Component.' + ) + }) +}) diff --git a/test/e2e/app-dir/app/app/client-with-errors/get-server-side-props/page.js b/test/e2e/app-dir/rsc-errors/app/client-with-errors/get-server-side-props/page.js similarity index 100% rename from test/e2e/app-dir/app/app/client-with-errors/get-server-side-props/page.js rename to test/e2e/app-dir/rsc-errors/app/client-with-errors/get-server-side-props/page.js diff --git a/test/e2e/app-dir/app/app/client-with-errors/get-static-props/page.js b/test/e2e/app-dir/rsc-errors/app/client-with-errors/get-static-props/page.js similarity index 100% rename from test/e2e/app-dir/app/app/client-with-errors/get-static-props/page.js rename to test/e2e/app-dir/rsc-errors/app/client-with-errors/get-static-props/page.js diff --git a/test/e2e/app-dir/rsc-errors/app/server-with-errors/styled-jsx/page.js b/test/e2e/app-dir/rsc-errors/app/server-with-errors/styled-jsx/page.js new file mode 100644 index 000000000000000..2ba4eaa6b98ac38 --- /dev/null +++ b/test/e2e/app-dir/rsc-errors/app/server-with-errors/styled-jsx/page.js @@ -0,0 +1,5 @@ +import JSXStyle from 'styled-jsx/style' + +export default function Page() { + return {`p{color:red}`} +} diff --git a/test/e2e/app-dir/rsc-errors/next.config.js b/test/e2e/app-dir/rsc-errors/next.config.js new file mode 100644 index 000000000000000..8e2a6c369174469 --- /dev/null +++ b/test/e2e/app-dir/rsc-errors/next.config.js @@ -0,0 +1,3 @@ +module.exports = { + experimental: { appDir: true }, +}