mirror of
https://github.com/terribleplan/next.js.git
synced 2024-01-19 02:48:18 +00:00
* 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
This commit is contained in:
parent
12a7610d9a
commit
9347c8bdd0
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -11,3 +11,5 @@ npm-debug.log
|
|||
# coverage
|
||||
.nyc_output
|
||||
coverage
|
||||
|
||||
.DS_Store
|
||||
|
|
|
@ -22,8 +22,9 @@ if (argv.help) {
|
|||
Usage
|
||||
$ next build <dir>
|
||||
|
||||
<dir> represents where the compiled .next folder should go.
|
||||
If no directory is provided, .next will be created in the current directory
|
||||
<dir> represents where the compiled dist folder should go.
|
||||
If no directory is provided, the dist folder will be created in the current directory.
|
||||
You can set a custom folder in config https://github.com/zeit/next.js#custom-configuration, otherwise it will be created inside '.next'
|
||||
`)
|
||||
process.exit(0)
|
||||
}
|
||||
|
|
|
@ -29,8 +29,9 @@ if (argv.help) {
|
|||
Usage
|
||||
$ next dev <dir> -p <port number>
|
||||
|
||||
<dir> represents where the compiled .next folder should go.
|
||||
If no directory is provided, .next will be created in the current directory
|
||||
<dir> represents where the compiled folder should go.
|
||||
If no directory is provided, the folder will be created in the current directory.
|
||||
You can set a custom folder in config https://github.com/zeit/next.js#custom-configuration.
|
||||
|
||||
Options
|
||||
--port, -p A port number on which to start the application
|
||||
|
|
|
@ -4,6 +4,7 @@ import { resolve } from 'path'
|
|||
import parseArgs from 'minimist'
|
||||
import Server from '../server'
|
||||
import { existsSync } from 'fs'
|
||||
import getConfig from '../server/config'
|
||||
|
||||
process.env.NODE_ENV = process.env.NODE_ENV || 'production'
|
||||
|
||||
|
@ -32,9 +33,10 @@ if (argv.help) {
|
|||
Usage
|
||||
$ next start <dir> -p <port>
|
||||
|
||||
<dir> is the directory that contains the compiled .next folder
|
||||
<dir> is the directory that contains the compiled dist folder
|
||||
created by running \`next build\`.
|
||||
If no directory is provided, the current directory will be assumed.
|
||||
You can set a custom dist folder in config https://github.com/zeit/next.js#custom-configuration
|
||||
|
||||
Options
|
||||
--port, -p A port number on which to start the application
|
||||
|
@ -45,11 +47,12 @@ if (argv.help) {
|
|||
}
|
||||
|
||||
const dir = resolve(argv._[0] || '.')
|
||||
const dist = getConfig(dir).distDir
|
||||
|
||||
const srv = new Server({ dir })
|
||||
|
||||
if (!existsSync(resolve(dir, '.next', 'BUILD_ID'))) {
|
||||
console.error(`> Could not find a valid build in the '.next' directory! Try building your app with 'next build' before starting the server.`)
|
||||
if (!existsSync(resolve(dir, dist, 'BUILD_ID'))) {
|
||||
console.error(`> Could not find a valid build in the '${dist}' directory! Try building your app with 'next build' before starting the server.`)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
|
|
13
readme.md
13
readme.md
|
@ -644,6 +644,17 @@ module.exports = {
|
|||
}
|
||||
```
|
||||
|
||||
#### Setting a custom build directory
|
||||
|
||||
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.
|
||||
|
||||
```javascript
|
||||
// next.config.js
|
||||
module.exports = {
|
||||
distDir: 'build'
|
||||
}
|
||||
```
|
||||
|
||||
### Customizing webpack config
|
||||
|
||||
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!
|
|||
|
||||
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.
|
||||
|
||||
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`)
|
||||
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)
|
||||
|
||||
## FAQ
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import { resolve } from 'path'
|
||||
import del from 'del'
|
||||
import getConfig from '../config'
|
||||
|
||||
export default function clean (dir) {
|
||||
return del(resolve(dir, '.next'))
|
||||
const dist = getConfig(dir).distDir
|
||||
return del(resolve(dir, dist))
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { tmpdir } from 'os'
|
||||
import { join } from 'path'
|
||||
import getConfig from '../config'
|
||||
import fs from 'mz/fs'
|
||||
import uuid from 'uuid'
|
||||
import del from 'del'
|
||||
|
@ -13,8 +14,10 @@ export default async function build (dir) {
|
|||
|
||||
try {
|
||||
await runCompiler(compiler)
|
||||
await writeBuildStats(buildDir)
|
||||
await writeBuildId(buildDir)
|
||||
|
||||
// Pass in both the buildDir and the dir to retrieve config
|
||||
await writeBuildStats(buildDir, dir)
|
||||
await writeBuildId(buildDir, dir)
|
||||
} catch (err) {
|
||||
console.error(`> Failed to build on ${buildDir}`)
|
||||
throw err
|
||||
|
@ -45,22 +48,24 @@ function runCompiler (compiler) {
|
|||
})
|
||||
}
|
||||
|
||||
async function writeBuildStats (dir) {
|
||||
async function writeBuildStats (buildDir, dir) {
|
||||
const dist = getConfig(dir).distDir
|
||||
// Here we can't use hashes in webpack chunks.
|
||||
// That's because the "app.js" is not tied to a chunk.
|
||||
// It's created by merging a few assets. (commons.js and main.js)
|
||||
// So, we need to generate the hash ourself.
|
||||
const assetHashMap = {
|
||||
'app.js': {
|
||||
hash: await md5File(join(dir, '.next', 'app.js'))
|
||||
hash: await md5File(join(buildDir, dist, 'app.js'))
|
||||
}
|
||||
}
|
||||
const buildStatsPath = join(dir, '.next', 'build-stats.json')
|
||||
const buildStatsPath = join(buildDir, dist, 'build-stats.json')
|
||||
await fs.writeFile(buildStatsPath, JSON.stringify(assetHashMap), 'utf8')
|
||||
}
|
||||
|
||||
async function writeBuildId (dir) {
|
||||
const buildIdPath = join(dir, '.next', 'BUILD_ID')
|
||||
async function writeBuildId (buildDir, dir) {
|
||||
const dist = getConfig(dir).distDir
|
||||
const buildIdPath = join(buildDir, dist, 'BUILD_ID')
|
||||
const buildId = uuid.v4()
|
||||
await fs.writeFile(buildIdPath, buildId, 'utf8')
|
||||
}
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
import mv from 'mv'
|
||||
import { join } from 'path'
|
||||
import getConfig from '../config'
|
||||
|
||||
export default async function replaceCurrentBuild (dir, buildDir) {
|
||||
const _dir = join(dir, '.next')
|
||||
const _buildDir = join(buildDir, '.next')
|
||||
const oldDir = join(buildDir, '.next.old')
|
||||
const dist = getConfig(dir).distDir
|
||||
const buildDist = getConfig(buildDir).distDir
|
||||
const _dir = join(dir, dist)
|
||||
const _buildDir = join(buildDir, dist)
|
||||
const oldDir = join(buildDir, `${buildDist}.old`)
|
||||
|
||||
try {
|
||||
await move(_dir, oldDir)
|
||||
|
|
|
@ -265,7 +265,7 @@ export default async function createCompiler (dir, { dev = false, quiet = false,
|
|||
context: dir,
|
||||
entry,
|
||||
output: {
|
||||
path: join(buildDir || dir, '.next'),
|
||||
path: join(buildDir || dir, config.distDir),
|
||||
filename: '[name]',
|
||||
libraryTarget: 'commonjs2',
|
||||
publicPath: '/_webpack/',
|
||||
|
|
|
@ -5,7 +5,8 @@ const cache = new Map()
|
|||
|
||||
const defaultConfig = {
|
||||
webpack: null,
|
||||
poweredByHeader: true
|
||||
poweredByHeader: true,
|
||||
distDir: '.next'
|
||||
}
|
||||
|
||||
export default function getConfig (dir) {
|
||||
|
|
|
@ -27,7 +27,8 @@ export default class Server {
|
|||
this.hotReloader = dev ? new HotReloader(this.dir, { quiet }) : null
|
||||
this.http = null
|
||||
this.config = getConfig(this.dir)
|
||||
this.buildStats = !dev ? require(join(this.dir, '.next', 'build-stats.json')) : null
|
||||
this.dist = this.config.distDir
|
||||
this.buildStats = !dev ? require(join(this.dir, this.dist, 'build-stats.json')) : null
|
||||
this.buildId = !dev ? this.readBuildId() : '-'
|
||||
this.renderOpts = {
|
||||
dev,
|
||||
|
@ -92,25 +93,25 @@ export default class Server {
|
|||
|
||||
'/_next/:hash/manifest.js': async (req, res, params) => {
|
||||
this.handleBuildHash('manifest.js', params.hash, res)
|
||||
const p = join(this.dir, '.next/manifest.js')
|
||||
const p = join(this.dir, `${this.dist}/manifest.js`)
|
||||
await this.serveStatic(req, res, p)
|
||||
},
|
||||
|
||||
'/_next/:hash/main.js': async (req, res, params) => {
|
||||
this.handleBuildHash('main.js', params.hash, res)
|
||||
const p = join(this.dir, '.next/main.js')
|
||||
const p = join(this.dir, `${this.dist}/main.js`)
|
||||
await this.serveStatic(req, res, p)
|
||||
},
|
||||
|
||||
'/_next/:hash/commons.js': async (req, res, params) => {
|
||||
this.handleBuildHash('commons.js', params.hash, res)
|
||||
const p = join(this.dir, '.next/commons.js')
|
||||
const p = join(this.dir, `${this.dist}/commons.js`)
|
||||
await this.serveStatic(req, res, p)
|
||||
},
|
||||
|
||||
'/_next/:hash/app.js': async (req, res, params) => {
|
||||
this.handleBuildHash('app.js', params.hash, res)
|
||||
const p = join(this.dir, '.next/app.js')
|
||||
const p = join(this.dir, `${this.dist}/app.js`)
|
||||
await this.serveStatic(req, res, p)
|
||||
},
|
||||
|
||||
|
@ -291,7 +292,7 @@ export default class Server {
|
|||
}
|
||||
|
||||
readBuildId () {
|
||||
const buildIdPath = join(this.dir, '.next', 'BUILD_ID')
|
||||
const buildIdPath = join(this.dir, this.dist, 'BUILD_ID')
|
||||
const buildId = fs.readFileSync(buildIdPath, 'utf8')
|
||||
return buildId.trim()
|
||||
}
|
||||
|
@ -312,7 +313,7 @@ export default class Server {
|
|||
const errors = this.hotReloader.getCompilationErrors()
|
||||
if (!errors.size) return
|
||||
|
||||
const id = join(this.dir, '.next', 'bundles', 'pages', page)
|
||||
const id = join(this.dir, this.dist, 'bundles', 'pages', page)
|
||||
const p = resolveFromList(id, errors.keys())
|
||||
if (p) return errors.get(p)[0]
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ import { createElement } from 'react'
|
|||
import { renderToString, renderToStaticMarkup } from 'react-dom/server'
|
||||
import send from 'send'
|
||||
import requireModule from './require'
|
||||
import getConfig from './config'
|
||||
import resolvePath from './resolve'
|
||||
import readPage from './read-page'
|
||||
import { Router } from '../lib/router'
|
||||
|
@ -43,9 +44,11 @@ async function doRender (req, res, pathname, query, {
|
|||
|
||||
await ensurePage(page, { dir, hotReloader })
|
||||
|
||||
const dist = getConfig(dir).distDir
|
||||
|
||||
let [Component, Document] = await Promise.all([
|
||||
requireModule(join(dir, '.next', 'dist', 'pages', page)),
|
||||
requireModule(join(dir, '.next', 'dist', 'pages', '_document'))
|
||||
requireModule(join(dir, dist, 'dist', 'pages', page)),
|
||||
requireModule(join(dir, dist, 'dist', 'pages', '_document'))
|
||||
])
|
||||
Component = Component.default || Component
|
||||
Document = Document.default || Document
|
||||
|
@ -57,8 +60,8 @@ async function doRender (req, res, pathname, query, {
|
|||
errorComponent
|
||||
] = await Promise.all([
|
||||
loadGetInitialProps(Component, ctx),
|
||||
readPage(join(dir, '.next', 'bundles', 'pages', page)),
|
||||
readPage(join(dir, '.next', 'bundles', 'pages', '_error'))
|
||||
readPage(join(dir, dist, 'bundles', 'pages', page)),
|
||||
readPage(join(dir, dist, 'bundles', 'pages', '_error'))
|
||||
])
|
||||
|
||||
// the response might be finshed on the getinitialprops call
|
||||
|
@ -113,13 +116,15 @@ async function doRender (req, res, pathname, query, {
|
|||
}
|
||||
|
||||
export async function renderJSON (req, res, page, { dir = process.cwd(), hotReloader } = {}) {
|
||||
const dist = getConfig(dir).distDir
|
||||
await ensurePage(page, { dir, hotReloader })
|
||||
const pagePath = await resolvePath(join(dir, '.next', 'bundles', 'pages', page))
|
||||
const pagePath = await resolvePath(join(dir, dist, 'bundles', 'pages', page))
|
||||
return serveStatic(req, res, pagePath)
|
||||
}
|
||||
|
||||
export async function renderErrorJSON (err, req, res, { dir = process.cwd(), dev = false } = {}) {
|
||||
const component = await readPage(join(dir, '.next', 'bundles', 'pages', '_error'))
|
||||
const dist = getConfig(dir).distDir
|
||||
const component = await readPage(join(dir, dist, 'bundles', 'pages', '_error'))
|
||||
|
||||
sendJSON(res, {
|
||||
component,
|
||||
|
|
7
test/integration/dist-dir/next.config.js
Normal file
7
test/integration/dist-dir/next.config.js
Normal file
|
@ -0,0 +1,7 @@
|
|||
module.exports = {
|
||||
onDemandEntries: {
|
||||
// Make sure entries are not getting disposed.
|
||||
maxInactiveAge: 1000 * 60 * 60
|
||||
},
|
||||
distDir: 'dist'
|
||||
}
|
3
test/integration/dist-dir/pages/index.js
Normal file
3
test/integration/dist-dir/pages/index.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
export default () => (
|
||||
<div>Hello World</div>
|
||||
)
|
49
test/integration/dist-dir/test/index.test.js
Normal file
49
test/integration/dist-dir/test/index.test.js
Normal file
|
@ -0,0 +1,49 @@
|
|||
/* global jasmine, describe, it, expect, beforeAll, afterAll */
|
||||
|
||||
import { join } from 'path'
|
||||
import { existsSync } from 'fs'
|
||||
import {
|
||||
nextServer,
|
||||
nextBuild,
|
||||
startApp,
|
||||
stopApp,
|
||||
renderViaHTTP
|
||||
} from 'next-test-utils'
|
||||
|
||||
const appDir = join(__dirname, '../')
|
||||
let appPort
|
||||
let server
|
||||
let app
|
||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 40000
|
||||
|
||||
describe('Production Usage', () => {
|
||||
beforeAll(async () => {
|
||||
await nextBuild(appDir)
|
||||
app = nextServer({
|
||||
dir: join(__dirname, '../'),
|
||||
dev: false,
|
||||
quiet: true
|
||||
})
|
||||
|
||||
server = await startApp(app)
|
||||
appPort = server.address().port
|
||||
})
|
||||
afterAll(() => stopApp(server))
|
||||
|
||||
describe('With basic usage', () => {
|
||||
it('should render the page', async () => {
|
||||
const html = await renderViaHTTP(appPort, '/')
|
||||
expect(html).toMatch(/Hello World/)
|
||||
})
|
||||
})
|
||||
|
||||
describe('File locations', () => {
|
||||
it('should build the app within the given `dist` directory', () => {
|
||||
expect(existsSync(join(__dirname, '/../dist/app.js'))).toBeTruthy()
|
||||
})
|
||||
|
||||
it('should not build the app within the default `.next` directory', () => {
|
||||
expect(existsSync(join(__dirname, '/../.next/app.js'))).toBeFalsy()
|
||||
})
|
||||
})
|
||||
})
|
Loading…
Reference in a new issue