diff --git a/lib/router/index.js b/lib/router/index.js index 550ef110d3e2..aa9d4439b872 100644 --- a/lib/router/index.js +++ b/lib/router/index.js @@ -1,4 +1,4 @@ -/* global window, location */ +/* global window */ import _Router from './router' const SingletonRouter = { @@ -81,6 +81,7 @@ export function _notifyBuildIdMismatch (nextRoute) { if (SingletonRouter.onAppUpdated) { SingletonRouter.onAppUpdated(nextRoute) } else { - location.href = nextRoute + console.warn(`An app update detected. Loading the SSR version of "${nextRoute}"`) + window.location.href = nextRoute } } diff --git a/lib/router/router.js b/lib/router/router.js index 518d1faff774..ed6f1e82b529 100644 --- a/lib/router/router.js +++ b/lib/router/router.js @@ -1,11 +1,11 @@ import { parse, format } from 'url' import { EventEmitter } from 'events' +import fetch from 'unfetch' import evalScript from '../eval-script' import shallowEquals from '../shallow-equals' import PQueue from '../p-queue' import { loadGetInitialProps, getURL } from '../utils' import { _notifyBuildIdMismatch } from './' -import fetch from 'unfetch' if (typeof window !== 'undefined' && typeof navigator.serviceWorker !== 'undefined') { navigator.serviceWorker.getRegistrations() @@ -322,6 +322,7 @@ export default class Router extends EventEmitter { doFetchRoute (route) { const { buildId } = window.__NEXT_DATA__ const url = `/_next/${encodeURIComponent(buildId)}/pages${route}` + return fetch(url, { method: 'GET', headers: { 'Accept': 'application/json' } diff --git a/server/build/index.js b/server/build/index.js index 65dcf31da8f4..0fcff294423b 100644 --- a/server/build/index.js +++ b/server/build/index.js @@ -11,7 +11,8 @@ export default async function build (dir) { const compiler = await webpack(dir, { buildDir }) try { - await runCompiler(compiler) + const webpackStats = await runCompiler(compiler) + await writeBuildStats(buildDir, webpackStats) await writeBuildId(buildDir) } catch (err) { console.error(`> Failed to build on ${buildDir}`) @@ -30,6 +31,7 @@ function runCompiler (compiler) { if (err) return reject(err) const jsonStats = stats.toJson() + if (jsonStats.errors.length > 0) { const error = new Error(jsonStats.errors[0]) error.errors = jsonStats.errors @@ -37,11 +39,24 @@ function runCompiler (compiler) { return reject(error) } - resolve() + resolve(jsonStats) }) }) } +async function writeBuildStats (dir, webpackStats) { + const chunkHashMap = {} + webpackStats.chunks + // We are not interested about pages + .filter(({ files }) => !/^bundles/.test(files[0])) + .forEach(({ hash, files }) => { + chunkHashMap[files[0]] = { hash } + }) + + const buildStatsPath = join(dir, '.next', 'build-stats.json') + await fs.writeFile(buildStatsPath, JSON.stringify(chunkHashMap), 'utf8') +} + async function writeBuildId (dir) { const buildIdPath = join(dir, '.next', 'BUILD_ID') const buildId = uuid.v4() diff --git a/server/document.js b/server/document.js index 588da328f7b8..a2682aa1b0f5 100644 --- a/server/document.js +++ b/server/document.js @@ -59,16 +59,25 @@ export class NextScript extends Component { _documentProps: PropTypes.any } + getChunkScript (filename) { + const { __NEXT_DATA__ } = this.context._documentProps + let { buildStats } = __NEXT_DATA__ + const hash = buildStats ? buildStats[filename].hash : '-' + + return ( +