diff --git a/.gitignore b/.gitignore index 2b79f54c..30d546ad 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ npm-debug.log # other .next +.next-* # coverage .nyc_output @@ -17,4 +18,4 @@ coverage # editors .idea/* *.iml -*.sublime-* \ No newline at end of file +*.sublime-* diff --git a/server/build/clean.js b/server/build/clean.js index f0d0876a..1e46fd6e 100644 --- a/server/build/clean.js +++ b/server/build/clean.js @@ -1,6 +1,6 @@ import { resolve } from 'path' import del from 'del' -export default function clean (dir) { - return del(resolve(dir, '.next')) +export default function clean (dir, folderName = '.next') { + return del(resolve(dir, folderName)) } diff --git a/server/build/gzip.js b/server/build/gzip.js index c3ae485f..1a03eb47 100644 --- a/server/build/gzip.js +++ b/server/build/gzip.js @@ -3,8 +3,8 @@ import path from 'path' import zlib from 'zlib' import glob from 'glob-promise' -export default async function gzipAssets (dir) { - const nextDir = path.resolve(dir, '.next') +export default async function gzipAssets (dir, buildFolder = '.next') { + const nextDir = path.resolve(dir, buildFolder) const coreAssets = [ path.join(nextDir, 'commons.js'), diff --git a/server/build/index.js b/server/build/index.js index 482626de..b2f9942d 100644 --- a/server/build/index.js +++ b/server/build/index.js @@ -4,16 +4,19 @@ import path from 'path' import webpack from './webpack' import clean from './clean' import gzipAssets from './gzip' +import replaceCurrentBuild from './replace' export default async function build (dir) { - const [compiler] = await Promise.all([ - webpack(dir), - clean(dir) - ]) + const distFolder = '.next' + const buildFolder = `.next-${uuid.v4()}` + const compiler = await webpack(dir, buildFolder) await runCompiler(compiler) - await gzipAssets(dir) - await writeBuildId(dir) + const oldFolder = await replaceCurrentBuild(dir, buildFolder, distFolder) + await gzipAssets(dir, distFolder) + await writeBuildId(dir, distFolder) + + clean(dir, oldFolder) } function runCompiler (compiler) { @@ -34,8 +37,8 @@ function runCompiler (compiler) { }) } -async function writeBuildId (dir) { - const buildIdPath = path.resolve(dir, '.next', 'BUILD_ID') +async function writeBuildId (dir, distFolder) { + const buildIdPath = path.resolve(dir, distFolder, 'BUILD_ID') const buildId = uuid.v4() await fs.writeFile(buildIdPath, buildId, 'utf8') } diff --git a/server/build/replace.js b/server/build/replace.js new file mode 100644 index 00000000..09e5bd1a --- /dev/null +++ b/server/build/replace.js @@ -0,0 +1,18 @@ +import fs from 'fs' +import path from 'path' +import uuid from 'uuid' + +export default function replaceCurrentBuild (dir, buildFolder, distFolder) { + const distDir = path.resolve(dir, distFolder) + const buildDir = path.resolve(dir, buildFolder) + const oldDir = path.resolve(dir, `.next-${uuid.v4()}`) + + return new Promise((resolve, reject) => { + fs.rename(distDir, oldDir, () => { + fs.rename(buildDir, distDir, (err) => { + if (err) return reject(err) + resolve(oldDir) + }) + }) + }) +} diff --git a/server/build/webpack.js b/server/build/webpack.js index 34196897..1af62b8e 100644 --- a/server/build/webpack.js +++ b/server/build/webpack.js @@ -23,7 +23,7 @@ const interpolateNames = new Map(defaultPages.map((p) => { return [join(nextPagesDir, p), `dist/pages/${p}`] })) -export default async function createCompiler (dir, { dev = false, quiet = false } = {}) { +export default async function createCompiler (dir, buildFolder, { dev = false, quiet = false } = {}) { dir = resolve(dir) const config = getConfig(dir) const defaultEntries = dev @@ -228,7 +228,7 @@ export default async function createCompiler (dir, { dev = false, quiet = false context: dir, entry, output: { - path: join(dir, '.next'), + path: join(dir, buildFolder || '.next'), filename: '[name]', libraryTarget: 'commonjs2', publicPath: '/_webpack/', diff --git a/server/hot-reloader.js b/server/hot-reloader.js index 37eeecbd..7d837dc7 100644 --- a/server/hot-reloader.js +++ b/server/hot-reloader.js @@ -35,7 +35,7 @@ export default class HotReloader { async start () { const [compiler] = await Promise.all([ - webpack(this.dir, { dev: true, quiet: this.quiet }), + webpack(this.dir, null, { dev: true, quiet: this.quiet }), clean(this.dir) ])