Clear up production build missing message for next start
and next export
(#19777)
Adds an err.sh link to the production build missing message. Also clears up `valid` as `production`. Also fixes an edge case where an unhelpful error would be thrown because we checked for `.next` instead of `.next/BUILD_ID` Added the out directory location as the list line during export to make sure people know where the files are output. Fixes #19778 Fixes #19788
This commit is contained in:
parent
cf4665539a
commit
c792317295
9 changed files with 135 additions and 5 deletions
10
errors/next-export-no-build-id.md
Normal file
10
errors/next-export-no-build-id.md
Normal file
|
@ -0,0 +1,10 @@
|
|||
# Could not find a production build
|
||||
|
||||
#### Why This Error Occurred
|
||||
|
||||
When running `next export` a production build is needed.
|
||||
|
||||
#### Possible Ways to Fix It
|
||||
|
||||
- Run `next build` to create a production build before running `next export`.
|
||||
- If your intention was to run the development server run `next dev` instead.
|
10
errors/production-start-no-build-id.md
Normal file
10
errors/production-start-no-build-id.md
Normal file
|
@ -0,0 +1,10 @@
|
|||
# Could not find a production build
|
||||
|
||||
#### Why This Error Occurred
|
||||
|
||||
When running `next start` or a custom server in production mode a production build is needed.
|
||||
|
||||
#### Possible Ways to Fix It
|
||||
|
||||
- Run `next build` to create a production build before booting up the production server.
|
||||
- If your intention was to run the development server run `next dev` instead.
|
|
@ -62,7 +62,7 @@ const nextExport: cliCommand = (argv) => {
|
|||
|
||||
exportApp(dir, options)
|
||||
.then(() => {
|
||||
printAndExit('Export successful', 0)
|
||||
printAndExit(`Export successful. Files written to ${options.outdir}`, 0)
|
||||
})
|
||||
.catch((err) => {
|
||||
printAndExit(err)
|
||||
|
|
|
@ -164,9 +164,11 @@ export default async function exportApp(
|
|||
Log.info(`using build directory: ${distDir}`)
|
||||
}
|
||||
|
||||
if (!existsSync(distDir)) {
|
||||
const buildIdFile = join(distDir, BUILD_ID_FILE)
|
||||
|
||||
if (!existsSync(buildIdFile)) {
|
||||
throw new Error(
|
||||
`Build directory ${distDir} does not exist. Make sure you run "next build" before running "next start" or "next export".`
|
||||
`Could not find a production build in the '${distDir}' directory. Try building your app with 'next build' before starting the static export. https://err.sh/vercel/next.js/next-export-no-build-id`
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -186,7 +188,7 @@ export default async function exportApp(
|
|||
)
|
||||
}
|
||||
|
||||
const buildId = readFileSync(join(distDir, BUILD_ID_FILE), 'utf8')
|
||||
const buildId = readFileSync(buildIdFile, 'utf8')
|
||||
const pagesManifest =
|
||||
!options.pages &&
|
||||
(require(join(
|
||||
|
|
|
@ -1899,7 +1899,7 @@ export default class Server {
|
|||
} catch (err) {
|
||||
if (!fs.existsSync(buildIdFile)) {
|
||||
throw new Error(
|
||||
`Could not find a valid build in the '${this.distDir}' directory! Try building your app with 'next build' before starting the server.`
|
||||
`Could not find a production build in the '${this.distDir}' directory. Try building your app with 'next build' before starting the production server. https://err.sh/vercel/next.js/production-start-no-build-id`
|
||||
)
|
||||
}
|
||||
|
||||
|
|
39
test/integration/export-no-build/next.config.js
Normal file
39
test/integration/export-no-build/next.config.js
Normal file
|
@ -0,0 +1,39 @@
|
|||
module.exports = {
|
||||
onDemandEntries: {
|
||||
// Make sure entries are not getting disposed.
|
||||
maxInactiveAge: 1000 * 60 * 60,
|
||||
},
|
||||
rewrites() {
|
||||
// add a rewrite so the code isn't dead-code eliminated
|
||||
return [
|
||||
{
|
||||
source: '/some-rewrite',
|
||||
destination: '/',
|
||||
},
|
||||
]
|
||||
},
|
||||
redirects() {
|
||||
return [
|
||||
{
|
||||
source: '/redirect/me/to-about/:lang',
|
||||
destination: '/:lang/about',
|
||||
permanent: false,
|
||||
},
|
||||
{
|
||||
source: '/nonexistent',
|
||||
destination: '/about',
|
||||
permanent: false,
|
||||
},
|
||||
{
|
||||
source: '/shadowed-page',
|
||||
destination: '/about',
|
||||
permanent: false,
|
||||
},
|
||||
{
|
||||
source: '/redirect-query-test/:path',
|
||||
destination: '/about?foo=:path',
|
||||
permanent: false,
|
||||
},
|
||||
]
|
||||
},
|
||||
}
|
13
test/integration/export-no-build/test/index.test.js
Normal file
13
test/integration/export-no-build/test/index.test.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
/* eslint-env jest */
|
||||
import { nextExport } from 'next-test-utils'
|
||||
import { join } from 'path'
|
||||
const appDir = join(__dirname, '../')
|
||||
jest.setTimeout(1000 * 60 * 5)
|
||||
|
||||
describe('next export without build', () => {
|
||||
it('should show error when there is no production build', async () => {
|
||||
const result = await nextExport(appDir, {}, { stderr: true, stdout: true })
|
||||
console.log(result.stdout, result.stderr)
|
||||
expect(result.stderr).toMatch(/Could not find a production build in the/)
|
||||
})
|
||||
})
|
39
test/integration/production-start-no-build/next.config.js
Normal file
39
test/integration/production-start-no-build/next.config.js
Normal file
|
@ -0,0 +1,39 @@
|
|||
module.exports = {
|
||||
onDemandEntries: {
|
||||
// Make sure entries are not getting disposed.
|
||||
maxInactiveAge: 1000 * 60 * 60,
|
||||
},
|
||||
rewrites() {
|
||||
// add a rewrite so the code isn't dead-code eliminated
|
||||
return [
|
||||
{
|
||||
source: '/some-rewrite',
|
||||
destination: '/',
|
||||
},
|
||||
]
|
||||
},
|
||||
redirects() {
|
||||
return [
|
||||
{
|
||||
source: '/redirect/me/to-about/:lang',
|
||||
destination: '/:lang/about',
|
||||
permanent: false,
|
||||
},
|
||||
{
|
||||
source: '/nonexistent',
|
||||
destination: '/about',
|
||||
permanent: false,
|
||||
},
|
||||
{
|
||||
source: '/shadowed-page',
|
||||
destination: '/about',
|
||||
permanent: false,
|
||||
},
|
||||
{
|
||||
source: '/redirect-query-test/:path',
|
||||
destination: '/about?foo=:path',
|
||||
permanent: false,
|
||||
},
|
||||
]
|
||||
},
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
/* eslint-env jest */
|
||||
import { nextServer } from 'next-test-utils'
|
||||
import { join } from 'path'
|
||||
const appDir = join(__dirname, '../')
|
||||
jest.setTimeout(1000 * 60 * 5)
|
||||
|
||||
describe('Production Usage without production build', () => {
|
||||
it('should show error when there is no production build', async () => {
|
||||
expect(() => {
|
||||
nextServer({
|
||||
dir: appDir,
|
||||
dev: false,
|
||||
quiet: true,
|
||||
})
|
||||
}).toThrow(/Could not find a production build in the/)
|
||||
})
|
||||
})
|
Loading…
Reference in a new issue