-
Notifications
You must be signed in to change notification settings - Fork 27.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add automatic reloading when editing GS(S)P methods (#16744)
This adds initial support for reloading the page when `getStaticProps`, `getStaticPaths`, or `getServerSideProps` were changed for a page by triggering a reload when the server output for a page has changed but the client output has not since these methods aren't included in the client output. Closes: #13949
- Loading branch information
Showing
6 changed files
with
255 additions
and
3 deletions.
There are no files selected for viewing
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
36 changes: 36 additions & 0 deletions
36
test/integration/gssp-ssr-change-reloading/pages/gsp-blog/[post].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,36 @@ | ||
import { useRouter } from 'next/router' | ||
|
||
export default function Gsp(props) { | ||
if (useRouter().isFallback) { | ||
return 'Loading...' | ||
} | ||
|
||
return ( | ||
<> | ||
<p id="change">change me</p> | ||
<p id="props">{JSON.stringify(props)}</p> | ||
</> | ||
) | ||
} | ||
|
||
export const getStaticProps = ({ params }) => { | ||
const count = 1 | ||
|
||
return { | ||
props: { | ||
count, | ||
params, | ||
random: Math.random(), | ||
}, | ||
} | ||
} | ||
|
||
export const getStaticPaths = () => { | ||
/* eslint-disable-next-line no-unused-vars */ | ||
const paths = 1 | ||
|
||
return { | ||
paths: [{ params: { post: 'first' } }, { params: { post: 'second' } }], | ||
fallback: true, | ||
} | ||
} |
20 changes: 20 additions & 0 deletions
20
test/integration/gssp-ssr-change-reloading/pages/gssp-blog/[post].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,20 @@ | ||
export default function Gssp(props) { | ||
return ( | ||
<> | ||
<p id="change">change me</p> | ||
<p id="props">{JSON.stringify(props)}</p> | ||
</> | ||
) | ||
} | ||
|
||
export const getServerSideProps = ({ params }) => { | ||
const count = 1 | ||
|
||
return { | ||
props: { | ||
count, | ||
params, | ||
random: Math.random(), | ||
}, | ||
} | ||
} |
123 changes: 123 additions & 0 deletions
123
test/integration/gssp-ssr-change-reloading/test/index.test.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,123 @@ | ||
/* eslint-env jest */ | ||
|
||
import { join } from 'path' | ||
import webdriver from 'next-webdriver' | ||
import { killApp, findPort, launchApp, File, check } from 'next-test-utils' | ||
|
||
jest.setTimeout(1000 * 60 * 2) | ||
const appDir = join(__dirname, '..') | ||
|
||
let appPort | ||
let app | ||
|
||
describe('GS(S)P Server-Side Change Reloading', () => { | ||
beforeAll(async () => { | ||
appPort = await findPort() | ||
app = await launchApp(appDir, appPort) | ||
}) | ||
afterAll(() => killApp(app)) | ||
|
||
it('should not reload page when client-side is changed too GSP', async () => { | ||
const browser = await webdriver(appPort, '/gsp-blog/first') | ||
await browser.eval(() => (window.beforeChange = 'hi')) | ||
|
||
const props = JSON.parse(await browser.elementByCss('#props').text()) | ||
|
||
const page = new File(join(appDir, 'pages/gsp-blog/[post].js')) | ||
page.replace('change me', 'changed') | ||
|
||
await check(() => browser.elementByCss('#change').text(), 'changed') | ||
expect(await browser.eval(() => window.beforeChange)).toBe('hi') | ||
|
||
const props2 = JSON.parse(await browser.elementByCss('#props').text()) | ||
expect(props).toEqual(props2) | ||
|
||
page.restore() | ||
|
||
await check(() => browser.elementByCss('#change').text(), 'change me') | ||
}) | ||
|
||
it('should update page when getStaticProps is changed only', async () => { | ||
const browser = await webdriver(appPort, '/gsp-blog/first') | ||
await browser.eval(() => (window.beforeChange = 'hi')) | ||
|
||
const props = JSON.parse(await browser.elementByCss('#props').text()) | ||
expect(props.count).toBe(1) | ||
|
||
const page = new File(join(appDir, 'pages/gsp-blog/[post].js')) | ||
page.replace('count = 1', 'count = 2') | ||
|
||
await check( | ||
async () => | ||
JSON.parse(await browser.elementByCss('#props').text()).count + '', | ||
'2' | ||
) | ||
expect(await browser.eval(() => window.beforeChange)).toBe('hi') | ||
page.restore() | ||
|
||
await check( | ||
async () => | ||
JSON.parse(await browser.elementByCss('#props').text()).count + '', | ||
'1' | ||
) | ||
}) | ||
|
||
it('should update page when getStaticPaths is changed only', async () => { | ||
const browser = await webdriver(appPort, '/gsp-blog/first') | ||
await browser.eval(() => (window.beforeChange = 'hi')) | ||
|
||
const props = JSON.parse(await browser.elementByCss('#props').text()) | ||
expect(props.count).toBe(1) | ||
|
||
const page = new File(join(appDir, 'pages/gsp-blog/[post].js')) | ||
page.replace('paths = 1', 'paths = 2') | ||
|
||
expect(await browser.eval('window.beforeChange')).toBe('hi') | ||
page.restore() | ||
}) | ||
|
||
it('should not reload page when client-side is changed too GSSP', async () => { | ||
const browser = await webdriver(appPort, '/gssp-blog/first') | ||
await browser.eval(() => (window.beforeChange = 'hi')) | ||
|
||
const props = JSON.parse(await browser.elementByCss('#props').text()) | ||
|
||
const page = new File(join(appDir, 'pages/gssp-blog/[post].js')) | ||
page.replace('change me', 'changed') | ||
|
||
await check(() => browser.elementByCss('#change').text(), 'changed') | ||
expect(await browser.eval(() => window.beforeChange)).toBe('hi') | ||
|
||
const props2 = JSON.parse(await browser.elementByCss('#props').text()) | ||
expect(props).toEqual(props2) | ||
|
||
page.restore() | ||
|
||
await check(() => browser.elementByCss('#change').text(), 'change me') | ||
}) | ||
|
||
it('should update page when getServerSideProps is changed only', async () => { | ||
const browser = await webdriver(appPort, '/gssp-blog/first') | ||
await browser.eval(() => (window.beforeChange = 'hi')) | ||
|
||
const props = JSON.parse(await browser.elementByCss('#props').text()) | ||
expect(props.count).toBe(1) | ||
|
||
const page = new File(join(appDir, 'pages/gssp-blog/[post].js')) | ||
page.replace('count = 1', 'count = 2') | ||
|
||
await check( | ||
async () => | ||
JSON.parse(await browser.elementByCss('#props').text()).count + '', | ||
'2' | ||
) | ||
expect(await browser.eval(() => window.beforeChange)).toBe('hi') | ||
page.restore() | ||
|
||
await check( | ||
async () => | ||
JSON.parse(await browser.elementByCss('#props').text()).count + '', | ||
'1' | ||
) | ||
}) | ||
}) |