Skip to content

Commit e8067bf

Browse files
authoredFeb 3, 2022
fix: correctly disable ISR disk flushing (#1190)
* chore: add blocking ISR demo * fix: ensure all files are patched correctly
·
1 parent 7e2a7d3 commit e8067bf

File tree

5 files changed

+182
-23
lines changed

5 files changed

+182
-23
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import Link from 'next/link'
2+
3+
const Show = ({ show, time }) => (
4+
<div>
5+
<p>This page uses getStaticProps() to pre-fetch a TV show.</p>
6+
<p>Ids 1 and 2 are prerendered</p>
7+
<hr />
8+
9+
<h1>Show #{show.id}</h1>
10+
<p>{show.name}</p>
11+
<p>Rendered at {time} </p>
12+
<hr />
13+
14+
<Link href="/">
15+
<a>Go back home</a>
16+
</Link>
17+
</div>
18+
)
19+
20+
export async function getStaticPaths() {
21+
// Set the paths we want to pre-render
22+
const paths = [{ params: { id: '1' } }, { params: { id: '2' } }]
23+
24+
// We'll pre-render only these paths at build time.
25+
26+
return { paths, fallback: 'blocking' }
27+
}
28+
29+
export async function getStaticProps({ params }) {
30+
// The ID to render
31+
const { id } = params
32+
33+
const res = await fetch(`https://api.tvmaze.com/shows/${id}`)
34+
const data = await res.json()
35+
const time = new Date().toLocaleTimeString()
36+
return {
37+
props: {
38+
show: data,
39+
time,
40+
},
41+
revalidate: 60,
42+
}
43+
}
44+
45+
export default Show

‎src/helpers/files.ts

+30-20
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { MINIMUM_REVALIDATE_SECONDS, DIVIDER } from '../constants'
1515

1616
import { NextConfig } from './config'
1717
import { Rewrites, RoutesManifest } from './types'
18+
import { findModuleFromBase } from './utils'
1819

1920
const TEST_ROUTE = /(|\/)\[[^/]+?](\/|\.html|$)/
2021

@@ -272,47 +273,56 @@ export const moveStaticPages = async ({
272273
}
273274
}
274275

275-
const patchFile = async ({ file, from, to }: { file: string; from: string; to: string }): Promise<void> => {
276+
/**
277+
* Attempt to patch a source file, preserving a backup
278+
*/
279+
const patchFile = async ({ file, from, to }: { file: string; from: string; to: string }): Promise<boolean> => {
276280
if (!existsSync(file)) {
277-
return
281+
console.warn('File was not found')
282+
283+
return false
278284
}
279285
const content = await readFile(file, 'utf8')
280286
if (content.includes(to)) {
281-
return
287+
console.log('File already patched')
288+
return false
282289
}
283290
const newContent = content.replace(from, to)
291+
if (newContent === content) {
292+
console.warn('File was not changed')
293+
return false
294+
}
284295
await writeFile(`${file}.orig`, content)
285296
await writeFile(file, newContent)
297+
console.log('Done')
298+
return true
286299
}
287300

301+
/**
302+
* The file we need has moved around a bit over the past few versions,
303+
* so we iterate through the options until we find it
304+
*/
288305
const getServerFile = (root) => {
289-
let serverFile
290-
try {
291-
serverFile = require.resolve('next/dist/server/next-server', { paths: [root] })
292-
} catch {
293-
// Ignore
294-
}
295-
if (!serverFile) {
296-
try {
297-
// eslint-disable-next-line node/no-missing-require
298-
serverFile = require.resolve('next/dist/next-server/server/next-server', { paths: [root] })
299-
} catch {
300-
// Ignore
301-
}
302-
}
303-
return serverFile
306+
const candidates = [
307+
'next/dist/server/base-server',
308+
'next/dist/server/next-server',
309+
'next/dist/next-server/server/next-server',
310+
]
311+
312+
return findModuleFromBase({ candidates, paths: [root] })
304313
}
305314

306-
export const patchNextFiles = async (root: string): Promise<void> => {
315+
export const patchNextFiles = (root: string): Promise<boolean> | boolean => {
307316
const serverFile = getServerFile(root)
308317
console.log(`Patching ${serverFile}`)
309318
if (serverFile) {
310-
await patchFile({
319+
return patchFile({
311320
file: serverFile,
312321
from: `let ssgCacheKey = `,
313322
to: `let ssgCacheKey = process.env._BYPASS_SSG || `,
314323
})
315324
}
325+
return false
316326
}
317327

318328
export const unpatchNextFiles = async (root: string): Promise<void> => {

‎src/helpers/utils.ts

+17
Original file line numberDiff line numberDiff line change
@@ -157,3 +157,20 @@ export const shouldSkip = (): boolean =>
157157
process.env.NEXT_PLUGIN_FORCE_RUN === '0' ||
158158
process.env.NETLIFY_NEXT_PLUGIN_SKIP === 'true' ||
159159
process.env.NETLIFY_NEXT_PLUGIN_SKIP === '1'
160+
161+
/**
162+
* Given an array of base paths and candidate modules, return the first one that exists
163+
*/
164+
export const findModuleFromBase = ({ paths, candidates }): string | null => {
165+
for (const candidate of candidates) {
166+
try {
167+
const modulePath = require.resolve(candidate, { paths })
168+
if (modulePath) {
169+
return modulePath
170+
}
171+
} catch (error) {
172+
console.error(error)
173+
}
174+
}
175+
return null
176+
}

‎test/__snapshots__/index.js.snap

+64
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ exports.resolvePages = () => {
2929
require.resolve('../../../.next/server/pages/getStaticProps/withFallbackBlocking/[id].js')
3030
require.resolve('../../../.next/server/pages/getStaticProps/withRevalidate/[id].js')
3131
require.resolve('../../../.next/server/pages/getStaticProps/withRevalidate/withFallback/[id].js')
32+
require.resolve('../../../.next/server/pages/getStaticProps/withRevalidate/withFallbackBlocking/[id].js')
3233
require.resolve('../../../.next/server/pages/index.js')
3334
require.resolve('../../../.next/server/pages/middle/_middleware.js')
3435
require.resolve('../../../.next/server/pages/previewTest.js')
@@ -67,6 +68,7 @@ exports.resolvePages = () => {
6768
require.resolve('../../../.next/server/pages/getStaticProps/withFallbackBlocking/[id].js')
6869
require.resolve('../../../.next/server/pages/getStaticProps/withRevalidate/[id].js')
6970
require.resolve('../../../.next/server/pages/getStaticProps/withRevalidate/withFallback/[id].js')
71+
require.resolve('../../../.next/server/pages/getStaticProps/withRevalidate/withFallbackBlocking/[id].js')
7072
require.resolve('../../../.next/server/pages/index.js')
7173
require.resolve('../../../.next/server/pages/middle/_middleware.js')
7274
require.resolve('../../../.next/server/pages/previewTest.js')
@@ -105,6 +107,7 @@ exports.resolvePages = () => {
105107
require.resolve('../../../web/.next/server/pages/getStaticProps/withFallbackBlocking/[id].js')
106108
require.resolve('../../../web/.next/server/pages/getStaticProps/withRevalidate/[id].js')
107109
require.resolve('../../../web/.next/server/pages/getStaticProps/withRevalidate/withFallback/[id].js')
110+
require.resolve('../../../web/.next/server/pages/getStaticProps/withRevalidate/withFallbackBlocking/[id].js')
108111
require.resolve('../../../web/.next/server/pages/index.js')
109112
require.resolve('../../../web/.next/server/pages/middle/_middleware.js')
110113
require.resolve('../../../web/.next/server/pages/previewTest.js')
@@ -143,6 +146,7 @@ exports.resolvePages = () => {
143146
require.resolve('../../../web/.next/server/pages/getStaticProps/withFallbackBlocking/[id].js')
144147
require.resolve('../../../web/.next/server/pages/getStaticProps/withRevalidate/[id].js')
145148
require.resolve('../../../web/.next/server/pages/getStaticProps/withRevalidate/withFallback/[id].js')
149+
require.resolve('../../../web/.next/server/pages/getStaticProps/withRevalidate/withFallbackBlocking/[id].js')
146150
require.resolve('../../../web/.next/server/pages/index.js')
147151
require.resolve('../../../web/.next/server/pages/middle/_middleware.js')
148152
require.resolve('../../../web/.next/server/pages/previewTest.js')
@@ -647,6 +651,30 @@ Array [
647651
"status": 200,
648652
"to": "/.netlify/builders/___netlify-odb-handler",
649653
},
654+
Object {
655+
"force": true,
656+
"from": "/_next/data/build-id/en/getStaticProps/withRevalidate/withFallbackBlocking/1.json",
657+
"status": 200,
658+
"to": "/.netlify/builders/___netlify-odb-handler",
659+
},
660+
Object {
661+
"force": true,
662+
"from": "/getStaticProps/withRevalidate/withFallbackBlocking/1",
663+
"status": 200,
664+
"to": "/.netlify/builders/___netlify-odb-handler",
665+
},
666+
Object {
667+
"force": true,
668+
"from": "/_next/data/build-id/en/getStaticProps/withRevalidate/withFallbackBlocking/2.json",
669+
"status": 200,
670+
"to": "/.netlify/builders/___netlify-odb-handler",
671+
},
672+
Object {
673+
"force": true,
674+
"from": "/getStaticProps/withRevalidate/withFallbackBlocking/2",
675+
"status": 200,
676+
"to": "/.netlify/builders/___netlify-odb-handler",
677+
},
650678
Object {
651679
"force": false,
652680
"from": "/_next/data/build-id/en/index.json",
@@ -1367,6 +1395,42 @@ Array [
13671395
"status": 200,
13681396
"to": "/.netlify/builders/___netlify-odb-handler",
13691397
},
1398+
Object {
1399+
"force": false,
1400+
"from": "/_next/data/build-id/en/getStaticProps/withRevalidate/withFallbackBlocking/:id.json",
1401+
"status": 200,
1402+
"to": "/.netlify/builders/___netlify-odb-handler",
1403+
},
1404+
Object {
1405+
"force": false,
1406+
"from": "/getStaticProps/withRevalidate/withFallbackBlocking/:id",
1407+
"status": 200,
1408+
"to": "/.netlify/builders/___netlify-odb-handler",
1409+
},
1410+
Object {
1411+
"force": false,
1412+
"from": "/_next/data/build-id/es/getStaticProps/withRevalidate/withFallbackBlocking/:id.json",
1413+
"status": 200,
1414+
"to": "/.netlify/builders/___netlify-odb-handler",
1415+
},
1416+
Object {
1417+
"force": false,
1418+
"from": "/es/getStaticProps/withRevalidate/withFallbackBlocking/:id",
1419+
"status": 200,
1420+
"to": "/.netlify/builders/___netlify-odb-handler",
1421+
},
1422+
Object {
1423+
"force": false,
1424+
"from": "/_next/data/build-id/fr/getStaticProps/withRevalidate/withFallbackBlocking/:id.json",
1425+
"status": 200,
1426+
"to": "/.netlify/builders/___netlify-odb-handler",
1427+
},
1428+
Object {
1429+
"force": false,
1430+
"from": "/fr/getStaticProps/withRevalidate/withFallbackBlocking/:id",
1431+
"status": 200,
1432+
"to": "/.netlify/builders/___netlify-odb-handler",
1433+
},
13701434
Object {
13711435
"force": false,
13721436
"from": "/_next/data/build-id/en/getStaticProps/withRevalidate/:id.json",

‎test/index.js

+26-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
const { writeJSON, unlink, existsSync, readFileSync, copy, ensureDir, readJson, writeFile } = require('fs-extra')
1+
const { writeJSON, unlink, existsSync, readFileSync, copy, ensureDir, readJson } = require('fs-extra')
22
const path = require('path')
33
const process = require('process')
44
const os = require('os')
@@ -10,10 +10,16 @@ const plugin = require('../src')
1010

1111
const { HANDLER_FUNCTION_NAME, ODB_FUNCTION_NAME } = require('../src/constants')
1212
const { join } = require('pathe')
13-
const { matchMiddleware, stripLocale, matchesRedirect, matchesRewrite } = require('../src/helpers/files')
13+
const {
14+
matchMiddleware,
15+
stripLocale,
16+
matchesRedirect,
17+
matchesRewrite,
18+
patchNextFiles,
19+
unpatchNextFiles,
20+
} = require('../src/helpers/files')
1421
const { dirname } = require('path')
1522
const { getProblematicUserRewrites } = require('../src/helpers/verification')
16-
const { outdent } = require('outdent')
1723

1824
const FIXTURES_DIR = `${__dirname}/fixtures`
1925
const SAMPLE_PROJECT_DIR = `${__dirname}/../demos/default`
@@ -659,6 +665,23 @@ describe('utility functions', () => {
659665
expect(matchesRewrite(path, REWRITES)).toBeTruthy()
660666
})
661667
})
668+
669+
test('patches Next server files', async () => {
670+
const root = path.resolve(dirname(__dirname))
671+
await copy(join(root, 'package.json'), path.join(process.cwd(), 'package.json'))
672+
await ensureDir(path.join(process.cwd(), 'node_modules'))
673+
await copy(path.join(root, 'node_modules', 'next'), path.join(process.cwd(), 'node_modules', 'next'))
674+
675+
expect(await patchNextFiles(process.cwd())).toBeTruthy()
676+
const serverFile = path.resolve(process.cwd(), 'node_modules', 'next', 'dist', 'server', 'base-server.js')
677+
const patchedData = await readFileSync(serverFile, 'utf8')
678+
expect(patchedData.includes('_BYPASS_SSG')).toBeTruthy()
679+
680+
await unpatchNextFiles(process.cwd())
681+
682+
const unPatchedData = await readFileSync(serverFile, 'utf8')
683+
expect(unPatchedData.includes('_BYPASS_SSG')).toBeFalsy()
684+
})
662685
})
663686

664687
describe('function helpers', () => {

0 commit comments

Comments
 (0)
Please sign in to comment.