From 8aa3620a169f5c38beaf4a1b158c01bc3b5ba4c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20Born=C3=B6?= Date: Sat, 5 Feb 2022 22:15:49 +0100 Subject: [PATCH] Babel & next-swc: Fix exporting page config with AsExpression (#32702) fixes #20626 No changes needed in next-swc, see comments from @kdy1 below. Co-authored-by: JJ Kasper <22380829+ijjk@users.noreply.github.com> --- .../build/babel/plugins/next-page-config.ts | 13 ++-- .../app/pages/page-config.tsx | 17 +++++ .../babel-plugin-next-page-config.test.ts | 62 +++++++++++++++++++ 3 files changed, 87 insertions(+), 5 deletions(-) create mode 100644 test/production/typescript-basic/app/pages/page-config.tsx create mode 100644 test/unit/babel-plugin-next-page-config.test.ts diff --git a/packages/next/build/babel/plugins/next-page-config.ts b/packages/next/build/babel/plugins/next-page-config.ts index 2e4725f290c1b1d..3126ba6ccf533ff 100644 --- a/packages/next/build/babel/plugins/next-page-config.ts +++ b/packages/next/build/babel/plugins/next-page-config.ts @@ -144,10 +144,13 @@ export default function nextPageConfig({ continue } - if (!BabelTypes.isObjectExpression(declaration.init)) { - const got = declaration.init - ? declaration.init.type - : 'undefined' + let { init } = declaration + if (BabelTypes.isTSAsExpression(init)) { + init = init.expression + } + + if (!BabelTypes.isObjectExpression(init)) { + const got = init ? init.type : 'undefined' throw new Error( errorMessage( exportState, @@ -156,7 +159,7 @@ export default function nextPageConfig({ ) } - for (const prop of declaration.init.properties) { + for (const prop of init.properties) { if (BabelTypes.isSpreadElement(prop)) { throw new Error( errorMessage( diff --git a/test/production/typescript-basic/app/pages/page-config.tsx b/test/production/typescript-basic/app/pages/page-config.tsx new file mode 100644 index 000000000000000..1f3e7c5d6c4da76 --- /dev/null +++ b/test/production/typescript-basic/app/pages/page-config.tsx @@ -0,0 +1,17 @@ +import Link from 'next/link' +import { PageConfig } from 'next' + +export const config: PageConfig = { + unstable_runtimeJS: false, +} + +export default function Page() { + return ( + <> +

hello world

+ + to /another + + + ) +} diff --git a/test/unit/babel-plugin-next-page-config.test.ts b/test/unit/babel-plugin-next-page-config.test.ts new file mode 100644 index 000000000000000..21609e2d81b4533 --- /dev/null +++ b/test/unit/babel-plugin-next-page-config.test.ts @@ -0,0 +1,62 @@ +/* eslint-env jest */ +import { transformSync } from '@babel/core' + +const babel = (code) => + transformSync(code, { + filename: 'page.tsx', + presets: ['@babel/preset-typescript'], + plugins: [require('next/dist/build/babel/plugins/next-page-config')], + babelrc: false, + configFile: false, + sourceType: 'module', + compact: true, + caller: { + name: 'tests', + isDev: false, + }, + } as any).code + +describe('babel plugin (next-page-config)', () => { + test('export config with type annotation', () => { + const output = babel('export const config: PageConfig = {};') + + expect(output).toMatch(`export const config={};`) + }) + + test('export config with AsExpression', () => { + const output = babel('export const config = {} as PageConfig;') + + expect(output).toMatch('export const config={};') + }) + + test('amp enabled', () => { + jest.spyOn(Date, 'now').mockReturnValue(1234) + const output = babel(` + export const config = { amp: true } + + function About(props) { + return

My AMP About Page!

+ } + + export default About`) + + expect(output).toMatch( + 'const __NEXT_DROP_CLIENT_FILE__="__NEXT_DROP_CLIENT_FILE__ 1234";' + ) + }) + + test('amp hybrid enabled', () => { + const output = babel(` + export const config = { amp: 'hybrid' } + + function About(props) { + return

My AMP About Page!

+ } + + export default About`) + + expect(output).toMatch( + "export const config={amp:'hybrid'};function About(props){return

My AMP About Page!

;}export default About;" + ) + }) +})