2017-05-07 22:47:40 +00:00
|
|
|
import del from 'del'
|
|
|
|
import cp from 'recursive-copy'
|
|
|
|
import mkdirp from 'mkdirp-then'
|
2017-05-08 06:10:26 +00:00
|
|
|
import { resolve, join, dirname, sep } from 'path'
|
|
|
|
import { existsSync, readFileSync, writeFileSync } from 'fs'
|
|
|
|
import getConfig from './config'
|
|
|
|
import { renderToHTML } from './render'
|
|
|
|
import { printAndExit } from '../lib/utils'
|
2017-05-07 22:47:40 +00:00
|
|
|
|
2017-05-09 01:53:08 +00:00
|
|
|
export default async function (dir, options) {
|
2017-05-08 06:10:26 +00:00
|
|
|
dir = resolve(dir)
|
2017-05-09 02:10:55 +00:00
|
|
|
const outDir = options.outdir
|
2017-05-08 06:10:26 +00:00
|
|
|
const nextDir = join(dir, '.next')
|
2017-05-07 22:47:40 +00:00
|
|
|
|
|
|
|
if (!existsSync(nextDir)) {
|
|
|
|
console.error('Build your with "next build" before running "next start".')
|
|
|
|
process.exit(1)
|
|
|
|
}
|
|
|
|
|
2017-05-08 06:10:26 +00:00
|
|
|
const config = getConfig(dir)
|
2017-05-07 22:47:40 +00:00
|
|
|
const buildId = readFileSync(join(nextDir, 'BUILD_ID'), 'utf8')
|
|
|
|
const buildStats = require(join(nextDir, 'build-stats.json'))
|
|
|
|
|
|
|
|
// Initialize the output directory
|
|
|
|
await del(outDir)
|
|
|
|
await mkdirp(join(outDir, '_next', buildStats['app.js'].hash))
|
|
|
|
await mkdirp(join(outDir, '_next', buildId))
|
|
|
|
|
|
|
|
// Copy files
|
|
|
|
await cp(
|
|
|
|
join(nextDir, 'app.js'),
|
|
|
|
join(outDir, '_next', buildStats['app.js'].hash, 'app.js')
|
|
|
|
)
|
|
|
|
|
|
|
|
await cp(
|
|
|
|
join(nextDir, 'bundles', 'pages'),
|
|
|
|
join(outDir, '_next', buildId, 'page')
|
|
|
|
)
|
2017-05-08 06:10:26 +00:00
|
|
|
|
2017-05-09 01:20:50 +00:00
|
|
|
// Get the exportPathMap from the `next.config.js`
|
|
|
|
if (typeof config.exportPathMap !== 'function') {
|
|
|
|
printAndExit(
|
|
|
|
'> Could not found "exportPathMap" function inside "next.config.js"\n' +
|
|
|
|
'> "next export" uses that function build html pages.'
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
const exportPathMap = await config.exportPathMap()
|
|
|
|
const exportPaths = Object.keys(exportPathMap)
|
|
|
|
|
2017-05-08 06:10:26 +00:00
|
|
|
// Start the rendering process
|
|
|
|
const renderOpts = {
|
|
|
|
dir,
|
|
|
|
buildStats,
|
|
|
|
buildId,
|
2017-05-09 01:20:50 +00:00
|
|
|
nextExport: true,
|
2017-05-08 06:10:26 +00:00
|
|
|
assetPrefix: config.assetPrefix.replace(/\/$/, ''),
|
|
|
|
dev: false,
|
|
|
|
staticMarkup: false,
|
|
|
|
hotReloader: null
|
|
|
|
}
|
|
|
|
|
2017-05-09 01:20:50 +00:00
|
|
|
// We need this for server rendering the Link component.
|
|
|
|
global.__NEXT_DATA__ = {
|
|
|
|
nextExport: true
|
2017-05-08 06:10:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for (const path of exportPaths) {
|
2017-05-09 01:53:08 +00:00
|
|
|
if (options.verbose) {
|
|
|
|
console.log(` exporing path: ${path}`)
|
|
|
|
}
|
|
|
|
|
2017-05-08 06:10:26 +00:00
|
|
|
const { page, query } = exportPathMap[path]
|
|
|
|
const req = { url: path }
|
|
|
|
const res = {}
|
|
|
|
|
2017-05-08 17:22:32 +00:00
|
|
|
const htmlFilename = path === '/' ? 'index.html' : `${path}${sep}index.html`
|
2017-05-08 06:10:26 +00:00
|
|
|
const baseDir = join(outDir, dirname(htmlFilename))
|
|
|
|
const htmlFilepath = join(outDir, htmlFilename)
|
|
|
|
|
|
|
|
await mkdirp(baseDir)
|
|
|
|
|
|
|
|
const html = await renderToHTML(req, res, page, query, renderOpts)
|
|
|
|
writeFileSync(htmlFilepath, html, 'utf8')
|
|
|
|
}
|
2017-05-07 22:47:40 +00:00
|
|
|
}
|