From f8aeaa479ecaaccd4807db42e8df256aa813b194 Mon Sep 17 00:00:00 2001 From: Joris W Date: Sat, 3 Oct 2020 16:50:37 +0200 Subject: [PATCH 1/5] Add missing introductory exportPathMap purpose description (#17444) The page describing exportPathMap goes straight into an example without explaining what the config is for. --- docs/api-reference/next.config.js/exportPathMap.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/api-reference/next.config.js/exportPathMap.md b/docs/api-reference/next.config.js/exportPathMap.md index bd6a7c28c090a..c28f201852b6c 100644 --- a/docs/api-reference/next.config.js/exportPathMap.md +++ b/docs/api-reference/next.config.js/exportPathMap.md @@ -13,6 +13,8 @@ description: Customize the pages that will be exported as HTML files when using +`exportPathMap` allows you to specify a mapping of request paths to page destinations, to be used during export. + Let's start with an example, to create a custom `exportPathMap` for an app with the following pages: - `pages/index.js` From 91b5390617a1dac36a4ea0cebcb2a21a06630f0a Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Sun, 4 Oct 2020 14:16:30 -0500 Subject: [PATCH 2/5] Remove left-over api-utils method (#17595) Noticed this method was left-over from previous query handling logic in `api-utils` while working on https://github.com/vercel/next.js/pull/17370 so this removes the extra code which should be safe since `api-utils` is an internal file that shouldn't be relied on externally. --- packages/next/next-server/server/api-utils.ts | 28 ------------------- 1 file changed, 28 deletions(-) diff --git a/packages/next/next-server/server/api-utils.ts b/packages/next/next-server/server/api-utils.ts index 658423aa4b0e0..057c31aec2b9a 100644 --- a/packages/next/next-server/server/api-utils.ts +++ b/packages/next/next-server/server/api-utils.ts @@ -162,34 +162,6 @@ function parseJson(str: string): object { } } -/** - * Parsing query arguments from request `url` string - * @param url of request - * @returns Object with key name of query argument and its value - */ -export function getQueryParser({ url }: IncomingMessage) { - return function parseQuery(): NextApiRequestQuery { - const { URL } = require('url') - // we provide a placeholder base url because we only want searchParams - const params = new URL(url, 'https://n').searchParams - - const query: { [key: string]: string | string[] } = {} - for (const [key, value] of params) { - if (query[key]) { - if (Array.isArray(query[key])) { - ;(query[key] as string[]).push(value) - } else { - query[key] = [query[key], value] - } - } else { - query[key] = value - } - } - - return query - } -} - /** * Parse cookies from `req` header * @param req request object From d32b195539b8a7a711fd03095841f79f82cac1b0 Mon Sep 17 00:00:00 2001 From: Rafael Zerbini Date: Mon, 5 Oct 2020 03:27:43 -0300 Subject: [PATCH 3/5] Fixes #16431 (#17610) Fixes #16431 * Added `.babelrc` with `next/babel` to remove the need of the React import on the `with-storybook` example. --- examples/with-storybook/.babelrc | 4 ++++ examples/with-storybook/components/index.js | 1 - 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 examples/with-storybook/.babelrc diff --git a/examples/with-storybook/.babelrc b/examples/with-storybook/.babelrc new file mode 100644 index 0000000000000..9fcef0394fdf0 --- /dev/null +++ b/examples/with-storybook/.babelrc @@ -0,0 +1,4 @@ +{ + "presets": ["next/babel"], + "plugins": [] +} diff --git a/examples/with-storybook/components/index.js b/examples/with-storybook/components/index.js index c9eaaf748d055..8f5129010b9b0 100644 --- a/examples/with-storybook/components/index.js +++ b/examples/with-storybook/components/index.js @@ -1,4 +1,3 @@ -import React from 'react' export default function Home() { return
Hello World
} From 782b7e48ecfb0dddf5ea89b61881632d2aaa8c39 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Mon, 5 Oct 2020 02:11:06 -0500 Subject: [PATCH 4/5] Add warning when exporting with custom routes (#17538) This adds a warning when `next export` and custom routes are defined outside of a platform that supports them since they won't be applied anymore. --- errors/export-no-custom-routes.md | 19 +++++ packages/next/export/index.ts | 16 ++++ .../custom-routes/test/index.test.js | 74 ++++++++++++++++++- 3 files changed, 106 insertions(+), 3 deletions(-) create mode 100644 errors/export-no-custom-routes.md diff --git a/errors/export-no-custom-routes.md b/errors/export-no-custom-routes.md new file mode 100644 index 0000000000000..9a18c5747e24c --- /dev/null +++ b/errors/export-no-custom-routes.md @@ -0,0 +1,19 @@ +# `next export` No Custom Routes + +#### Why This Error Occurred + +In your `next.config.js` `rewrites`, `redirects`, or `headers` were defined while `next export` was being run outside of a platform that supports them. + +These configs do not apply when exporting your Next.js application manually. + +#### Possible Ways to Fix It + +Disable the `rewrites`, `redirects`, and `headers` from your `next.config.js` when using `next export` to deploy your application or deploy your application using [a method](https://nextjs.org/docs/deployment#vercel-recommended) that supports these configs. + +### Useful Links + +- [Deployment Documentation](https://nextjs.org/docs/deployment#vercel-recommended) +- [`next export` Documentation](https://nextjs.org/docs/advanced-features/static-html-export) +- [Rewrites Documentation](https://nextjs.org/docs/api-reference/next.config.js/rewrites) +- [Redirects Documentation](https://nextjs.org/docs/api-reference/next.config.js/redirects) +- [Headers Documentation](https://nextjs.org/docs/api-reference/next.config.js/headers) diff --git a/packages/next/export/index.ts b/packages/next/export/index.ts index c70b4f924b699..7564979686245 100644 --- a/packages/next/export/index.ts +++ b/packages/next/export/index.ts @@ -165,6 +165,22 @@ export default async function exportApp( ) } + const customRoutesDetected = ['rewrites', 'redirects', 'headers'].filter( + (config) => typeof nextConfig[config] === 'function' + ) + + if ( + !process.env.NOW_BUILDER && + !options.buildExport && + customRoutesDetected.length > 0 + ) { + Log.warn( + `rewrites, redirects, and headers are not applied when exporting your application, detected (${customRoutesDetected.join( + ', ' + )}). See more info here: https://err.sh/next.js/export-no-custom-routes` + ) + } + const buildId = readFileSync(join(distDir, BUILD_ID_FILE), 'utf8') const pagesManifest = !options.pages && diff --git a/test/integration/custom-routes/test/index.test.js b/test/integration/custom-routes/test/index.test.js index 2242934493c62..3deb702bbcb35 100644 --- a/test/integration/custom-routes/test/index.test.js +++ b/test/integration/custom-routes/test/index.test.js @@ -19,6 +19,7 @@ import { waitFor, normalizeRegEx, initNextServerScript, + nextExport, } from 'next-test-utils' jest.setTimeout(1000 * 60 * 2) @@ -31,6 +32,7 @@ let nextConfigContent let externalServerPort let externalServer let stdout = '' +let stderr = '' let buildId let appPort let app @@ -1119,16 +1121,82 @@ describe('Custom routes', () => { describe('server mode', () => { beforeAll(async () => { - const { stdout: buildStdout } = await nextBuild(appDir, ['-d'], { - stdout: true, - }) + const { stdout: buildStdout, stderr: buildStderr } = await nextBuild( + appDir, + ['-d'], + { + stdout: true, + stderr: true, + } + ) stdout = buildStdout + stderr = buildStderr appPort = await findPort() app = await nextStart(appDir, appPort) buildId = await fs.readFile(join(appDir, '.next/BUILD_ID'), 'utf8') }) afterAll(() => killApp(app)) runTests() + + it('should not show warning for custom routes when not next export', async () => { + expect(stderr).not.toContain( + `rewrites, redirects, and headers are not applied when exporting your application detected` + ) + }) + }) + + describe('export', () => { + let exportStderr = '' + let exportVercelStderr = '' + + beforeAll(async () => { + const { stdout: buildStdout, stderr: buildStderr } = await nextBuild( + appDir, + ['-d'], + { + stdout: true, + stderr: true, + } + ) + const exportResult = await nextExport( + appDir, + { outdir: join(appDir, 'out') }, + { stderr: true } + ) + const exportVercelResult = await nextExport( + appDir, + { outdir: join(appDir, 'out') }, + { + stderr: true, + env: { + NOW_BUILDER: '1', + }, + } + ) + + stdout = buildStdout + stderr = buildStderr + exportStderr = exportResult.stderr + exportVercelStderr = exportVercelResult.stderr + }) + + it('should not show warning for custom routes when not next export', async () => { + expect(stderr).not.toContain( + `rewrites, redirects, and headers are not applied when exporting your application detected` + ) + }) + + it('should not show warning for custom routes when next export on Vercel', async () => { + expect(exportVercelStderr).not.toContain( + `rewrites, redirects, and headers are not applied when exporting your application detected` + ) + }) + + it('should show warning for custom routes with next export', async () => { + expect(exportStderr).toContain( + `rewrites, redirects, and headers are not applied when exporting your application, detected (rewrites, redirects, headers)` + ) + }) }) describe('serverless mode', () => { From b42be17593d69854b3f3cbed7b1ed14e999444dc Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Mon, 5 Oct 2020 02:34:50 -0500 Subject: [PATCH 5/5] Normalize optional catch-all fallback: true page params (#17551) This makes sure to normalize the params for optional catch-all routes on Vercel since for `fallback: true` pages the `[[...paramName]]` value will be provided for the undefined/root param which needs to be normalized. Tests have been added in https://github.com/vercel/vercel/pull/5247 and were manually tested with the changes in this PR with https://github.com/ijjk/next-update-loader Fixes: https://github.com/vercel/next.js/issues/17220 x-ref: https://github.com/vercel/vercel/pull/5247 --- .../next/build/webpack/loaders/next-serverless-loader.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/next/build/webpack/loaders/next-serverless-loader.ts b/packages/next/build/webpack/loaders/next-serverless-loader.ts index 82e3db7c7d293..e2b67a9cce03d 100644 --- a/packages/next/build/webpack/loaders/next-serverless-loader.ts +++ b/packages/next/build/webpack/loaders/next-serverless-loader.ts @@ -89,7 +89,12 @@ const nextServerlessLoader: loader.Loader = function () { (!value || ( Array.isArray(value) && value.length === 1 && - value[0] === 'index' + ${ + '' + // fallback optional catch-all SSG pages have + // [[...paramName]] for the root path on Vercel + } + (value[0] === 'index' || value[0] === \`[[...\${key}]]\`) )) ) { value = undefined