From 5a4176cffe7d72afbf6f9071adee8d38cd93c60d Mon Sep 17 00:00:00 2001 From: Giuseppe Date: Sun, 3 Feb 2019 01:12:49 +0100 Subject: [PATCH] Invalidate cache for link[preload] in DEV (#6183) Fixes #5860 --- packages/next/pages/_document.js | 51 ++++++++++++------- .../app-document/test/rendering.js | 16 ++++++ .../integration/production/test/index.test.js | 21 ++++++++ 3 files changed, 71 insertions(+), 17 deletions(-) diff --git a/packages/next/pages/_document.js b/packages/next/pages/_document.js index e3fa8ea61c..a3b076f417 100644 --- a/packages/next/pages/_document.js +++ b/packages/next/pages/_document.js @@ -10,7 +10,8 @@ const Fragment = React.Fragment || function Fragment ({ children }) { export default class Document extends Component { static childContextTypes = { - _documentProps: PropTypes.any + _documentProps: PropTypes.any, + _devOnlyInvalidateCacheQueryString: PropTypes.string, } static getInitialProps ({ renderPage }) { @@ -20,7 +21,13 @@ export default class Document extends Component { } getChildContext () { - return { _documentProps: this.props } + return { + _documentProps: this.props, + // In dev we invalidate the cache by appending a timestamp to the resource URL. + // This is a workaround to fix https://github.com/zeit/next.js/issues/5860 + // TODO: remove this workaround when https://bugs.webkit.org/show_bug.cgi?id=187726 is fixed. + _devOnlyInvalidateCacheQueryString: process.env.NODE_ENV !== 'production' ? '?ts=' + Date.now() : '' + } } render () { @@ -36,7 +43,8 @@ export default class Document extends Component { export class Head extends Component { static contextTypes = { - _documentProps: PropTypes.any + _documentProps: PropTypes.any, + _devOnlyInvalidateCacheQueryString: PropTypes.string, } static propTypes = { @@ -68,11 +76,13 @@ export class Head extends Component { getPreloadDynamicChunks () { const { dynamicImports, assetPrefix } = this.context._documentProps + const { _devOnlyInvalidateCacheQueryString } = this.context + return dynamicImports.map((bundle) => { return { // Only render .js files here @@ -96,7 +107,7 @@ export class Head extends Component { key={file} nonce={this.props.nonce} rel='preload' - href={`${assetPrefix}/_next/${file}`} + href={`${assetPrefix}/_next/${file}${_devOnlyInvalidateCacheQueryString}`} as='script' crossOrigin={this.props.crossOrigin || process.crossOrigin} /> @@ -105,6 +116,7 @@ export class Head extends Component { render () { const { head, styles, assetPrefix, __NEXT_DATA__ } = this.context._documentProps + const { _devOnlyInvalidateCacheQueryString } = this.context const { page, buildId } = __NEXT_DATA__ const pagePathname = getPagePathname(page) @@ -119,12 +131,11 @@ export class Head extends Component { }) if (this.props.crossOrigin) console.warn('Warning: `Head` attribute `crossOrigin` is deprecated. https://err.sh/next.js/doc-crossorigin-deprecated') } - return {children} {head} - {page !== '/_error' && } - + {page !== '/_error' && } + {this.getPreloadDynamicChunks()} {this.getPreloadMainLinks()} {this.getCssLinks()} @@ -135,7 +146,8 @@ export class Head extends Component { export class Main extends Component { static contextTypes = { - _documentProps: PropTypes.any + _documentProps: PropTypes.any, + _devOnlyInvalidateCacheQueryString: PropTypes.string, } render () { @@ -148,7 +160,8 @@ export class Main extends Component { export class NextScript extends Component { static contextTypes = { - _documentProps: PropTypes.any + _documentProps: PropTypes.any, + _devOnlyInvalidateCacheQueryString: PropTypes.string, } static propTypes = { @@ -158,11 +171,13 @@ export class NextScript extends Component { getDynamicChunks () { const { dynamicImports, assetPrefix } = this.context._documentProps + const { _devOnlyInvalidateCacheQueryString } = this.context + return dynamicImports.map((bundle) => { return