Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9347c8b

Browse files
alexnewmannnarunoda
authored andcommitted
Specify a different build directory for vercel#1513 (vercel#1599)
* Update references to `.next` * Remove console logs and extraneous semi colons * Remove lint errors * Update references to .next and update docs * Update options from nested to flat with `distDir` * Add integration tests, and update `.gitignore` * Rename integration folder to dist-dir to match standards
1 parent 12a7610 commit 9347c8b

File tree

15 files changed

+128
-34
lines changed

15 files changed

+128
-34
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,5 @@ npm-debug.log
1111
# coverage
1212
.nyc_output
1313
coverage
14+
15+
.DS_Store

bin/next-build

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,9 @@ if (argv.help) {
2222
Usage
2323
$ next build <dir>
2424
25-
<dir> represents where the compiled .next folder should go.
26-
If no directory is provided, .next will be created in the current directory
25+
<dir> represents where the compiled dist folder should go.
26+
If no directory is provided, the dist folder will be created in the current directory.
27+
You can set a custom folder in config https://github.com/zeit/next.js#custom-configuration, otherwise it will be created inside '.next'
2728
`)
2829
process.exit(0)
2930
}

bin/next-dev

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,9 @@ if (argv.help) {
2929
Usage
3030
$ next dev <dir> -p <port number>
3131
32-
<dir> represents where the compiled .next folder should go.
33-
If no directory is provided, .next will be created in the current directory
32+
<dir> represents where the compiled folder should go.
33+
If no directory is provided, the folder will be created in the current directory.
34+
You can set a custom folder in config https://github.com/zeit/next.js#custom-configuration.
3435
3536
Options
3637
--port, -p A port number on which to start the application

bin/next-start

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { resolve } from 'path'
44
import parseArgs from 'minimist'
55
import Server from '../server'
66
import { existsSync } from 'fs'
7+
import getConfig from '../server/config'
78

89
process.env.NODE_ENV = process.env.NODE_ENV || 'production'
910

@@ -32,9 +33,10 @@ if (argv.help) {
3233
Usage
3334
$ next start <dir> -p <port>
3435
35-
<dir> is the directory that contains the compiled .next folder
36+
<dir> is the directory that contains the compiled dist folder
3637
created by running \`next build\`.
3738
If no directory is provided, the current directory will be assumed.
39+
You can set a custom dist folder in config https://github.com/zeit/next.js#custom-configuration
3840
3941
Options
4042
--port, -p A port number on which to start the application
@@ -45,11 +47,12 @@ if (argv.help) {
4547
}
4648

4749
const dir = resolve(argv._[0] || '.')
50+
const dist = getConfig(dir).distDir
4851

4952
const srv = new Server({ dir })
5053

51-
if (!existsSync(resolve(dir, '.next', 'BUILD_ID'))) {
52-
console.error(`> Could not find a valid build in the '.next' directory! Try building your app with 'next build' before starting the server.`)
54+
if (!existsSync(resolve(dir, dist, 'BUILD_ID'))) {
55+
console.error(`> Could not find a valid build in the '${dist}' directory! Try building your app with 'next build' before starting the server.`)
5356
process.exit(1)
5457
}
5558

readme.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -644,6 +644,17 @@ module.exports = {
644644
}
645645
```
646646

647+
#### Setting a custom build directory
648+
649+
You can specify a name to use for a custom build directory. For example, the following config will create a `build` folder instead of a `.next` folder. If no configuration is specified then next will create a `.next` folder.
650+
651+
```javascript
652+
// next.config.js
653+
module.exports = {
654+
distDir: 'build'
655+
}
656+
```
657+
647658
### Customizing webpack config
648659

649660
In order to extend our usage of `webpack`, you can define a function that extends its config via `next.config.js`.
@@ -718,7 +729,7 @@ Then run `now` and enjoy!
718729

719730
Next.js can be deployed to other hosting solutions too. Please have a look at the ['Deployment'](https://github.com/zeit/next.js/wiki/Deployment) section of the wiki.
720731

721-
Note: we recommend putting `.next` in `.npmignore` or `.gitignore`. Otherwise, use `files` or `now.files` to opt-into a whitelist of files you want to deploy (and obviously exclude `.next`)
732+
Note: we recommend putting `.next`, or your custom dist folder (Please have a look at ['Custom Config'](You can set a custom folder in config https://github.com/zeit/next.js#custom-configuration.)), in `.npmignore` or `.gitignore`. Otherwise, use `files` or `now.files` to opt-into a whitelist of files you want to deploy (and obviously exclude `.next` or your custom dist folder)
722733

723734
## FAQ
724735

server/build/clean.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { resolve } from 'path'
22
import del from 'del'
3+
import getConfig from '../config'
34

45
export default function clean (dir) {
5-
return del(resolve(dir, '.next'))
6+
const dist = getConfig(dir).distDir
7+
return del(resolve(dir, dist))
68
}

server/build/index.js

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { tmpdir } from 'os'
22
import { join } from 'path'
3+
import getConfig from '../config'
34
import fs from 'mz/fs'
45
import uuid from 'uuid'
56
import del from 'del'
@@ -13,8 +14,10 @@ export default async function build (dir) {
1314

1415
try {
1516
await runCompiler(compiler)
16-
await writeBuildStats(buildDir)
17-
await writeBuildId(buildDir)
17+
18+
// Pass in both the buildDir and the dir to retrieve config
19+
await writeBuildStats(buildDir, dir)
20+
await writeBuildId(buildDir, dir)
1821
} catch (err) {
1922
console.error(`> Failed to build on ${buildDir}`)
2023
throw err
@@ -45,22 +48,24 @@ function runCompiler (compiler) {
4548
})
4649
}
4750

48-
async function writeBuildStats (dir) {
51+
async function writeBuildStats (buildDir, dir) {
52+
const dist = getConfig(dir).distDir
4953
// Here we can't use hashes in webpack chunks.
5054
// That's because the "app.js" is not tied to a chunk.
5155
// It's created by merging a few assets. (commons.js and main.js)
5256
// So, we need to generate the hash ourself.
5357
const assetHashMap = {
5458
'app.js': {
55-
hash: await md5File(join(dir, '.next', 'app.js'))
59+
hash: await md5File(join(buildDir, dist, 'app.js'))
5660
}
5761
}
58-
const buildStatsPath = join(dir, '.next', 'build-stats.json')
62+
const buildStatsPath = join(buildDir, dist, 'build-stats.json')
5963
await fs.writeFile(buildStatsPath, JSON.stringify(assetHashMap), 'utf8')
6064
}
6165

62-
async function writeBuildId (dir) {
63-
const buildIdPath = join(dir, '.next', 'BUILD_ID')
66+
async function writeBuildId (buildDir, dir) {
67+
const dist = getConfig(dir).distDir
68+
const buildIdPath = join(buildDir, dist, 'BUILD_ID')
6469
const buildId = uuid.v4()
6570
await fs.writeFile(buildIdPath, buildId, 'utf8')
6671
}

server/build/replace.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
import mv from 'mv'
22
import { join } from 'path'
3+
import getConfig from '../config'
34

45
export default async function replaceCurrentBuild (dir, buildDir) {
5-
const _dir = join(dir, '.next')
6-
const _buildDir = join(buildDir, '.next')
7-
const oldDir = join(buildDir, '.next.old')
6+
const dist = getConfig(dir).distDir
7+
const buildDist = getConfig(buildDir).distDir
8+
const _dir = join(dir, dist)
9+
const _buildDir = join(buildDir, dist)
10+
const oldDir = join(buildDir, `${buildDist}.old`)
811

912
try {
1013
await move(_dir, oldDir)

server/build/webpack.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ export default async function createCompiler (dir, { dev = false, quiet = false,
265265
context: dir,
266266
entry,
267267
output: {
268-
path: join(buildDir || dir, '.next'),
268+
path: join(buildDir || dir, config.distDir),
269269
filename: '[name]',
270270
libraryTarget: 'commonjs2',
271271
publicPath: '/_webpack/',

server/config.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ const cache = new Map()
55

66
const defaultConfig = {
77
webpack: null,
8-
poweredByHeader: true
8+
poweredByHeader: true,
9+
distDir: '.next'
910
}
1011

1112
export default function getConfig (dir) {

server/index.js

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ export default class Server {
2727
this.hotReloader = dev ? new HotReloader(this.dir, { quiet }) : null
2828
this.http = null
2929
this.config = getConfig(this.dir)
30-
this.buildStats = !dev ? require(join(this.dir, '.next', 'build-stats.json')) : null
30+
this.dist = this.config.distDir
31+
this.buildStats = !dev ? require(join(this.dir, this.dist, 'build-stats.json')) : null
3132
this.buildId = !dev ? this.readBuildId() : '-'
3233
this.renderOpts = {
3334
dev,
@@ -92,25 +93,25 @@ export default class Server {
9293

9394
'/_next/:hash/manifest.js': async (req, res, params) => {
9495
this.handleBuildHash('manifest.js', params.hash, res)
95-
const p = join(this.dir, '.next/manifest.js')
96+
const p = join(this.dir, `${this.dist}/manifest.js`)
9697
await this.serveStatic(req, res, p)
9798
},
9899

99100
'/_next/:hash/main.js': async (req, res, params) => {
100101
this.handleBuildHash('main.js', params.hash, res)
101-
const p = join(this.dir, '.next/main.js')
102+
const p = join(this.dir, `${this.dist}/main.js`)
102103
await this.serveStatic(req, res, p)
103104
},
104105

105106
'/_next/:hash/commons.js': async (req, res, params) => {
106107
this.handleBuildHash('commons.js', params.hash, res)
107-
const p = join(this.dir, '.next/commons.js')
108+
const p = join(this.dir, `${this.dist}/commons.js`)
108109
await this.serveStatic(req, res, p)
109110
},
110111

111112
'/_next/:hash/app.js': async (req, res, params) => {
112113
this.handleBuildHash('app.js', params.hash, res)
113-
const p = join(this.dir, '.next/app.js')
114+
const p = join(this.dir, `${this.dist}/app.js`)
114115
await this.serveStatic(req, res, p)
115116
},
116117

@@ -291,7 +292,7 @@ export default class Server {
291292
}
292293

293294
readBuildId () {
294-
const buildIdPath = join(this.dir, '.next', 'BUILD_ID')
295+
const buildIdPath = join(this.dir, this.dist, 'BUILD_ID')
295296
const buildId = fs.readFileSync(buildIdPath, 'utf8')
296297
return buildId.trim()
297298
}
@@ -312,7 +313,7 @@ export default class Server {
312313
const errors = this.hotReloader.getCompilationErrors()
313314
if (!errors.size) return
314315

315-
const id = join(this.dir, '.next', 'bundles', 'pages', page)
316+
const id = join(this.dir, this.dist, 'bundles', 'pages', page)
316317
const p = resolveFromList(id, errors.keys())
317318
if (p) return errors.get(p)[0]
318319
}

server/render.js

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { createElement } from 'react'
33
import { renderToString, renderToStaticMarkup } from 'react-dom/server'
44
import send from 'send'
55
import requireModule from './require'
6+
import getConfig from './config'
67
import resolvePath from './resolve'
78
import readPage from './read-page'
89
import { Router } from '../lib/router'
@@ -43,9 +44,11 @@ async function doRender (req, res, pathname, query, {
4344

4445
await ensurePage(page, { dir, hotReloader })
4546

47+
const dist = getConfig(dir).distDir
48+
4649
let [Component, Document] = await Promise.all([
47-
requireModule(join(dir, '.next', 'dist', 'pages', page)),
48-
requireModule(join(dir, '.next', 'dist', 'pages', '_document'))
50+
requireModule(join(dir, dist, 'dist', 'pages', page)),
51+
requireModule(join(dir, dist, 'dist', 'pages', '_document'))
4952
])
5053
Component = Component.default || Component
5154
Document = Document.default || Document
@@ -57,8 +60,8 @@ async function doRender (req, res, pathname, query, {
5760
errorComponent
5861
] = await Promise.all([
5962
loadGetInitialProps(Component, ctx),
60-
readPage(join(dir, '.next', 'bundles', 'pages', page)),
61-
readPage(join(dir, '.next', 'bundles', 'pages', '_error'))
63+
readPage(join(dir, dist, 'bundles', 'pages', page)),
64+
readPage(join(dir, dist, 'bundles', 'pages', '_error'))
6265
])
6366

6467
// the response might be finshed on the getinitialprops call
@@ -113,13 +116,15 @@ async function doRender (req, res, pathname, query, {
113116
}
114117

115118
export async function renderJSON (req, res, page, { dir = process.cwd(), hotReloader } = {}) {
119+
const dist = getConfig(dir).distDir
116120
await ensurePage(page, { dir, hotReloader })
117-
const pagePath = await resolvePath(join(dir, '.next', 'bundles', 'pages', page))
121+
const pagePath = await resolvePath(join(dir, dist, 'bundles', 'pages', page))
118122
return serveStatic(req, res, pagePath)
119123
}
120124

121125
export async function renderErrorJSON (err, req, res, { dir = process.cwd(), dev = false } = {}) {
122-
const component = await readPage(join(dir, '.next', 'bundles', 'pages', '_error'))
126+
const dist = getConfig(dir).distDir
127+
const component = await readPage(join(dir, dist, 'bundles', 'pages', '_error'))
123128

124129
sendJSON(res, {
125130
component,
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
module.exports = {
2+
onDemandEntries: {
3+
// Make sure entries are not getting disposed.
4+
maxInactiveAge: 1000 * 60 * 60
5+
},
6+
distDir: 'dist'
7+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default () => (
2+
<div>Hello World</div>
3+
)
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/* global jasmine, describe, it, expect, beforeAll, afterAll */
2+
3+
import { join } from 'path'
4+
import { existsSync } from 'fs'
5+
import {
6+
nextServer,
7+
nextBuild,
8+
startApp,
9+
stopApp,
10+
renderViaHTTP
11+
} from 'next-test-utils'
12+
13+
const appDir = join(__dirname, '../')
14+
let appPort
15+
let server
16+
let app
17+
jasmine.DEFAULT_TIMEOUT_INTERVAL = 40000
18+
19+
describe('Production Usage', () => {
20+
beforeAll(async () => {
21+
await nextBuild(appDir)
22+
app = nextServer({
23+
dir: join(__dirname, '../'),
24+
dev: false,
25+
quiet: true
26+
})
27+
28+
server = await startApp(app)
29+
appPort = server.address().port
30+
})
31+
afterAll(() => stopApp(server))
32+
33+
describe('With basic usage', () => {
34+
it('should render the page', async () => {
35+
const html = await renderViaHTTP(appPort, '/')
36+
expect(html).toMatch(/Hello World/)
37+
})
38+
})
39+
40+
describe('File locations', () => {
41+
it('should build the app within the given `dist` directory', () => {
42+
expect(existsSync(join(__dirname, '/../dist/app.js'))).toBeTruthy()
43+
})
44+
45+
it('should not build the app within the default `.next` directory', () => {
46+
expect(existsSync(join(__dirname, '/../.next/app.js'))).toBeFalsy()
47+
})
48+
})
49+
})

0 commit comments

Comments
 (0)