forked from gatsbyjs/gatsby
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(gatsby): refresh browser if webpack rebuild occurs (gatsbyjs#13871)
* move query running into build and develop * save build compilation hash * write compilationHash to page data * reload browser if rebuild occurs in background * add test to ensure that browser is reloaded if rebuild occurs * update page-datas when compilation hash changes * use worker pool to udpate page data compilation hash * update tests snapshot * reset plugin offline whitelist if compilation hash changes * prettier: remove global Cypress * separate page for testing compilation-hash * fix case typo * mock out static entry test webpackCompilationHash field * consolidate jest-worker calls into a central worker pool
- Loading branch information
Showing
33 changed files
with
462 additions
and
152 deletions.
There are no files selected for viewing
9 changes: 9 additions & 0 deletions
9
e2e-tests/production-runtime/cypress/integration/1-production.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
64 changes: 64 additions & 0 deletions
64
e2e-tests/production-runtime/cypress/integration/compilation-hash.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
/* global cy */ | ||
|
||
const getRandomInt = (min, max) => { | ||
min = Math.ceil(min) | ||
max = Math.floor(max) | ||
return Math.floor(Math.random() * (max - min)) + min | ||
} | ||
|
||
const createMockCompilationHash = () => | ||
[...Array(20)] | ||
.map(a => getRandomInt(0, 16)) | ||
.map(k => k.toString(16)) | ||
.join(``) | ||
|
||
describe(`Webpack Compilation Hash tests`, () => { | ||
it(`should render properly`, () => { | ||
cy.visit(`/`).waitForRouteChange() | ||
}) | ||
|
||
// This covers the case where a user loads a gatsby site and then | ||
// the site is changed resulting in a webpack recompile and a | ||
// redeploy. This could result in a mismatch between the page-data | ||
// and the component. To protect against this, when gatsby loads a | ||
// new page-data.json, it refreshes the page if it's webpack | ||
// compilation hash differs from the one on on the window object | ||
// (which was set on initial page load) | ||
// | ||
// Since initial page load results in all links being prefetched, we | ||
// have to navigate to a non-prefetched page to test this. Thus the | ||
// `deep-link-page`. | ||
// | ||
// We simulate a rebuild by updating all page-data.jsons and page | ||
// htmls with the new hash. It's not pretty, but it's easier than | ||
// figuring out how to perform an actual rebuild while cypress is | ||
// running. See ../plugins/compilation-hash.js for the | ||
// implementation | ||
it(`should reload page if build occurs in background`, () => { | ||
cy.window().then(window => { | ||
const oldHash = window.___webpackCompilationHash | ||
expect(oldHash).to.not.eq(undefined) | ||
|
||
const mockHash = createMockCompilationHash() | ||
|
||
// Simulate a new webpack build | ||
cy.task(`overwriteWebpackCompilationHash`, mockHash).then(() => { | ||
cy.getTestElement(`compilation-hash`).click() | ||
cy.waitForAPIorTimeout(`onRouteUpdate`, { timeout: 3000 }) | ||
|
||
// Navigate into a non-prefetched page | ||
cy.getTestElement(`deep-link-page`).click() | ||
cy.waitForAPIorTimeout(`onRouteUpdate`, { timeout: 3000 }) | ||
|
||
// If the window compilation hash has changed, we know the | ||
// page was refreshed | ||
cy.window() | ||
.its(`___webpackCompilationHash`) | ||
.should(`equal`, mockHash) | ||
}) | ||
|
||
// Cleanup | ||
cy.task(`overwriteWebpackCompilationHash`, oldHash) | ||
}) | ||
}) | ||
}) |
32 changes: 32 additions & 0 deletions
32
e2e-tests/production-runtime/cypress/plugins/compilation-hash.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
const fs = require(`fs-extra`) | ||
const path = require(`path`) | ||
const glob = require(`glob`) | ||
|
||
const replaceHtmlCompilationHash = (filename, newHash) => { | ||
const html = fs.readFileSync(filename, `utf-8`) | ||
const regex = /window\.webpackCompilationHash="\w*"/ | ||
const replace = `window.webpackCompilationHash="${newHash}"` | ||
fs.writeFileSync(filename, html.replace(regex, replace), `utf-8`) | ||
} | ||
|
||
const replacePageDataCompilationHash = (filename, newHash) => { | ||
const pageData = JSON.parse(fs.readFileSync(filename, `utf-8`)) | ||
pageData.webpackCompilationHash = newHash | ||
fs.writeFileSync(filename, JSON.stringify(pageData), `utf-8`) | ||
} | ||
|
||
const overwriteWebpackCompilationHash = newHash => { | ||
glob | ||
.sync(path.join(__dirname, `../../public/page-data/**/page-data.json`)) | ||
.forEach(filename => replacePageDataCompilationHash(filename, newHash)) | ||
glob | ||
.sync(path.join(__dirname, `../../public/**/index.html`)) | ||
.forEach(filename => replaceHtmlCompilationHash(filename, newHash)) | ||
|
||
// cypress requires that null be returned instead of undefined | ||
return null | ||
} | ||
|
||
module.exports = { | ||
overwriteWebpackCompilationHash, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
19 changes: 19 additions & 0 deletions
19
e2e-tests/production-runtime/src/pages/compilation-hash.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import React from 'react' | ||
import { Link } from 'gatsby' | ||
|
||
import Layout from '../components/layout' | ||
import InstrumentPage from '../utils/instrument-page' | ||
|
||
const CompilationHashPage = () => ( | ||
<Layout> | ||
<h1>Hi from Compilation Hash page</h1> | ||
<p>Used by integration/compilation-hash.js test</p> | ||
<p> | ||
<Link to="/deep-link-page/" data-testid="deep-link-page"> | ||
To deeply linked page | ||
</Link> | ||
</p> | ||
</Layout> | ||
) | ||
|
||
export default InstrumentPage(CompilationHashPage) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import React from 'react' | ||
|
||
import Layout from '../components/layout' | ||
import InstrumentPage from '../utils/instrument-page' | ||
|
||
const DeepLinkPage = () => ( | ||
<Layout> | ||
<h1>Hi from a deeply linked page</h1> | ||
<p> | ||
Used to navigate to a non prefetched page by | ||
integrations/compilation-hash.js tests | ||
</p> | ||
</Layout> | ||
) | ||
|
||
export default InstrumentPage(DeepLinkPage) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.