Skip to content

Commit

Permalink
fix: helpful error when output: export and next export -o (#51191)
Browse files Browse the repository at this point in the history
We already have a warning when using `next export` with `output: export` because the `next export` is effectively a no-op (the exported output was already generated during `next build`).

However, this PR ensures that `next export -o <dir>` throws an error when `output: export` is defined because the files were already emitted to the `distDir` in the `next build` step and we can't safely no-op at this point.

We also guide the user to the correct solution which is to use `output: export` along with `distDir: <dir>` in your next.config.js (instead of mixing legacy behavior with the new behavior).

fix #48207
fix NEXT-980
  • Loading branch information
styfle committed Jun 12, 2023
1 parent de83bf5 commit a6a9d65
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 13 deletions.
1 change: 1 addition & 0 deletions packages/next/src/cli/next-export.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ const nextExport: CliCommand = (argv) => {
silent: args['--silent'] || false,
threads: args['--threads'],
outdir: args['--outdir'] ? resolve(args['--outdir']) : join(dir, 'out'),
hasOutdirFromCli: Boolean(args['--outdir']),
isInvokedFromCli: true,
hasAppDir: false,
buildExport: false,
Expand Down
6 changes: 6 additions & 0 deletions packages/next/src/export/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ export interface ExportOptions {
exportAppPageWorker?: typeof import('./worker').default
endWorker?: () => Promise<void>
nextConfig?: NextConfigComplete
hasOutdirFromCli?: boolean
}

export default async function exportApp(
Expand Down Expand Up @@ -184,6 +185,11 @@ export default async function exportApp(
// Running 'next export'
if (options.isInvokedFromCli) {
if (isExportOutput) {
if (options.hasOutdirFromCli) {
throw new ExportError(
'"next export -o <dir>" cannot be used when "output: export" is configured in next.config.js. Instead add "distDir" in next.config.js https://nextjs.org/docs/advanced-features/static-html-export'
)
}
Log.warn(
'"next export" is no longer needed when "output: export" is configured in next.config.js https://nextjs.org/docs/advanced-features/static-html-export'
)
Expand Down
52 changes: 39 additions & 13 deletions test/integration/app-dir-export/test/config.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import fs from 'fs-extra'
import { nextBuild, nextExport } from 'next-test-utils'
import { nextBuild, nextExport, nextExportDefault } from 'next-test-utils'
import { join } from 'path'
import {
appDir,
Expand Down Expand Up @@ -39,24 +39,50 @@ describe('app dir with output export (next dev / next build)', () => {
expect(await getFiles()).toEqual(expectedFiles)
let stdout = ''
let stderr = ''
await nextExport(
appDir,
{ outdir: exportDir },
{
onStdout(msg) {
stdout += msg
},
onStderr(msg) {
stderr += msg
},
}
)
await nextExportDefault(appDir, {
onStdout(msg) {
stdout += msg
},
onStderr(msg) {
stderr += msg
},
})
expect(stderr).toContain(
'- warn "next export" is no longer needed when "output: export" is configured in next.config.js'
)
expect(stdout).toContain('Export successful. Files written to')
expect(await getFiles()).toEqual(expectedFiles)
})
it('should error when "next export -o <dir>" is used with config', async () => {
await fs.remove(distDir)
await fs.remove(exportDir)
await nextBuild(appDir)
expect(await getFiles()).toEqual(expectedFiles)
let stdout = ''
let stderr = ''
let error = undefined
try {
await nextExport(
appDir,
{ outdir: exportDir },
{
onStdout(msg) {
stdout += msg
},
onStderr(msg) {
stderr += msg
},
}
)
} catch (e) {
error = e
}
expect(error).toBeDefined()
expect(stderr).toContain(
'- error "next export -o <dir>" cannot be used when "output: export" is configured in next.config.js. Instead add "distDir" in next.config.js'
)
expect(stdout).not.toContain('Export successful. Files written to')
})
it('should error when no config.output detected for next export', async () => {
await fs.remove(distDir)
await fs.remove(exportDir)
Expand Down

0 comments on commit a6a9d65

Please sign in to comment.