diff --git a/packages/next/build/entries.ts b/packages/next/build/entries.ts index 8f06c922c1dab..429b28dc06fbd 100644 --- a/packages/next/build/entries.ts +++ b/packages/next/build/entries.ts @@ -61,6 +61,7 @@ type Entrypoints = { } export function createEntrypoints( + dev: boolean, pages: PagesMapping, target: 'server' | 'serverless' | 'experimental-serverless-trace', buildId: string, @@ -132,6 +133,7 @@ export function createEntrypoints( const pageLoaderOpts: ClientPagesLoaderOptions = { page, absolutePagePath, + hotRouterUpdates: dev, // Hot router updates only apply in development mode } const pageLoader = `next-client-pages-loader?${stringify( pageLoaderOpts diff --git a/packages/next/build/index.ts b/packages/next/build/index.ts index f6307e5ab48e3..7b574f6626478 100644 --- a/packages/next/build/index.ts +++ b/packages/next/build/index.ts @@ -217,6 +217,7 @@ export default async function build(dir: string, conf = null): Promise { const mappedPages = createPagesMapping(pagePaths, config.pageExtensions) const entrypoints = createEntrypoints( + /* dev */ false, mappedPages, target, buildId, diff --git a/packages/next/build/webpack/loaders/next-client-pages-loader.ts b/packages/next/build/webpack/loaders/next-client-pages-loader.ts index 85f8b9e76909e..9a592a7f4d7c1 100644 --- a/packages/next/build/webpack/loaders/next-client-pages-loader.ts +++ b/packages/next/build/webpack/loaders/next-client-pages-loader.ts @@ -4,25 +4,31 @@ import loaderUtils from 'loader-utils' export type ClientPagesLoaderOptions = { absolutePagePath: string page: string + hotRouterUpdates: boolean } const nextClientPagesLoader: loader.Loader = function() { - const { absolutePagePath, page }: any = loaderUtils.getOptions(this) + const { absolutePagePath, page, hotRouterUpdates } = loaderUtils.getOptions( + this + ) as ClientPagesLoaderOptions const stringifiedAbsolutePagePath = JSON.stringify(absolutePagePath) const stringifiedPage = JSON.stringify(page) return ` - (window.__NEXT_P=window.__NEXT_P||[]).push([${stringifiedPage}, function() { - var mod = require(${stringifiedAbsolutePagePath}) - if(module.hot) { - module.hot.accept(${stringifiedAbsolutePagePath}, function() { - if(!next.router.components[${stringifiedPage}]) return - var updatedPage = require(${stringifiedAbsolutePagePath}) - next.router.update(${stringifiedPage}, updatedPage) - }) + (window.__NEXT_P = window.__NEXT_P || []).push([ + ${stringifiedPage}, + function () { + var mod = require(${stringifiedAbsolutePagePath}); + if (${!!hotRouterUpdates} && module.hot) { + module.hot.accept(${stringifiedAbsolutePagePath}, function () { + if (!next.router.components[${stringifiedPage}]) return; + var updatedPage = require(${stringifiedAbsolutePagePath}); + next.router.update(${stringifiedPage}, updatedPage); + }); + } + return mod; } - return mod - }]); + ]); ` } diff --git a/packages/next/server/hot-reloader.ts b/packages/next/server/hot-reloader.ts index 633cd60761e73..d9729ec7f7f03 100644 --- a/packages/next/server/hot-reloader.ts +++ b/packages/next/server/hot-reloader.ts @@ -252,6 +252,7 @@ export default class HotReloader { this.config.pageExtensions ) const entrypoints = createEntrypoints( + /* dev */ true, pages, 'server', this.buildId, @@ -488,6 +489,7 @@ export default class HotReloader { pagesDir: this.pagesDir, reload: this.reload.bind(this), pageExtensions: this.config.pageExtensions, + hotRouterUpdates: true, ...(this.config.onDemandEntries as { maxInactiveAge: number pagesBufferLength: number diff --git a/packages/next/server/on-demand-entry-handler.ts b/packages/next/server/on-demand-entry-handler.ts index 74b0171dd6a72..02e60a835d2f9 100644 --- a/packages/next/server/on-demand-entry-handler.ts +++ b/packages/next/server/on-demand-entry-handler.ts @@ -48,6 +48,7 @@ export default function onDemandEntryHandler( pageExtensions, maxInactiveAge, pagesBufferLength, + hotRouterUpdates, }: { buildId: string pagesDir: string @@ -55,6 +56,7 @@ export default function onDemandEntryHandler( pageExtensions: string[] maxInactiveAge: number pagesBufferLength: number + hotRouterUpdates: boolean } ) { const { compilers } = multiCompiler @@ -88,6 +90,7 @@ export default function onDemandEntryHandler( const pageLoaderOpts: ClientPagesLoaderOptions = { page, absolutePagePath, + hotRouterUpdates, } return addEntry(compilation, compiler.context, name, [ compiler.name === 'client' diff --git a/test/integration/production-config/test/index.test.js b/test/integration/production-config/test/index.test.js index 8e6bc9e55b74c..a42bd11378f6c 100644 --- a/test/integration/production-config/test/index.test.js +++ b/test/integration/production-config/test/index.test.js @@ -39,6 +39,18 @@ describe('Production Config Usage', () => { }) }) + describe('with generateBuildId', () => { + it('should add the custom buildid', async () => { + const browser = await webdriver(appPort, '/') + const text = await browser.elementByCss('#mounted').text() + expect(text).toMatch(/ComponentDidMount executed on client\./) + + const html = await browser.elementByCss('html').getAttribute('innerHTML') + expect(html).toMatch('custom-buildid') + await browser.close() + }) + }) + describe('env', () => { it('should fail with leading __ in env key', async () => { const result = await runNextCommand(['build', appDir], { @@ -70,18 +82,6 @@ describe('Production Config Usage', () => { expect(result.stderr).not.toMatch(/The key "SOME__ENV__VAR" under/) }) }) - - describe('with generateBuildId', () => { - it('should add the custom buildid', async () => { - const browser = await webdriver(appPort, '/') - const text = await browser.elementByCss('#mounted').text() - expect(text).toMatch(/ComponentDidMount executed on client\./) - - const html = await browser.elementByCss('html').getAttribute('innerHTML') - expect(html).toMatch('custom-buildid') - await browser.close() - }) - }) }) async function testBrowser() {