Skip to content

Commit

Permalink
Merge branch 'canary' into update/release-workflow
Browse files Browse the repository at this point in the history
  • Loading branch information
kodiakhq[bot] authored Oct 5, 2020
2 parents d2f796b + b42be17 commit 8190faa
Show file tree
Hide file tree
Showing 8 changed files with 118 additions and 33 deletions.
2 changes: 2 additions & 0 deletions docs/api-reference/next.config.js/exportPathMap.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ description: Customize the pages that will be exported as HTML files when using
</ul>
</details>

`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`
Expand Down
19 changes: 19 additions & 0 deletions errors/export-no-custom-routes.md
Original file line number Diff line number Diff line change
@@ -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)
4 changes: 4 additions & 0 deletions examples/with-storybook/.babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"presets": ["next/babel"],
"plugins": []
}
1 change: 0 additions & 1 deletion examples/with-storybook/components/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import React from 'react'
export default function Home() {
return <div>Hello World</div>
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
16 changes: 16 additions & 0 deletions packages/next/export/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 &&
Expand Down
28 changes: 0 additions & 28 deletions packages/next/next-server/server/api-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
74 changes: 71 additions & 3 deletions test/integration/custom-routes/test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
waitFor,
normalizeRegEx,
initNextServerScript,
nextExport,
} from 'next-test-utils'

jest.setTimeout(1000 * 60 * 2)
Expand All @@ -31,6 +32,7 @@ let nextConfigContent
let externalServerPort
let externalServer
let stdout = ''
let stderr = ''
let buildId
let appPort
let app
Expand Down Expand Up @@ -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', () => {
Expand Down

0 comments on commit 8190faa

Please sign in to comment.