1
+ /* eslint-disable max-lines-per-function, max-lines */
1
2
const { promises, createWriteStream, existsSync } = require ( 'fs' )
2
3
const { Server } = require ( 'http' )
3
4
const { tmpdir } = require ( 'os' )
@@ -11,7 +12,8 @@ const fetch = require('node-fetch')
11
12
const makeHandler =
12
13
( ) =>
13
14
// We return a function and then call `toString()` on it to serialise it as the launcher function
14
- ( conf , app , pageRoot , staticManifest = [ ] ) => {
15
+ // eslint-disable-next-line max-params
16
+ ( conf , app , pageRoot , staticManifest = [ ] , mode = 'ssr' ) => {
15
17
// This is just so nft knows about the page entrypoints. It's not actually used
16
18
try {
17
19
// eslint-disable-next-line node/no-missing-require
@@ -33,16 +35,24 @@ const makeHandler =
33
35
const cacheDir = path . join ( tmpdir ( ) , 'next-static-cache' )
34
36
// Grab the real fs.promises.readFile...
35
37
const readfileOrig = promises . readFile
38
+ const writeFileOrig = promises . writeFile
39
+ const mkdirOrig = promises . mkdir
36
40
// ...then money-patch it to see if it's requesting a CDN file
37
41
promises . readFile = async ( file , options ) => {
38
42
// We only care about page files
39
43
if ( file . startsWith ( pageRoot ) ) {
40
44
// We only want the part after `pages/`
41
45
const filePath = file . slice ( pageRoot . length + 1 )
46
+ const cacheFile = path . join ( cacheDir , filePath )
47
+
48
+ if ( existsSync ( cacheFile ) ) {
49
+ console . log ( 'returning from cache' , cacheFile )
50
+ return readfileOrig ( cacheFile , options )
51
+ }
52
+
42
53
// Is it in the CDN and not local?
43
54
if ( staticFiles . has ( filePath ) && ! existsSync ( file ) ) {
44
55
// This name is safe to use, because it's one that was already created by Next
45
- const cacheFile = path . join ( cacheDir , filePath )
46
56
// Have we already cached it? We ignore the cache if running locally to avoid staleness
47
57
if ( ( ! existsSync ( cacheFile ) || process . env . NETLIFY_DEV ) && base ) {
48
58
await promises . mkdir ( path . dirname ( cacheFile ) , { recursive : true } )
@@ -65,6 +75,29 @@ const makeHandler =
65
75
66
76
return readfileOrig ( file , options )
67
77
}
78
+
79
+ promises . writeFile = async ( file , data , options ) => {
80
+ if ( file . startsWith ( pageRoot ) ) {
81
+ const filePath = file . slice ( pageRoot . length + 1 )
82
+ const cacheFile = path . join ( cacheDir , filePath )
83
+ console . log ( 'writing' , cacheFile )
84
+ await promises . mkdir ( path . dirname ( cacheFile ) , { recursive : true } )
85
+ return writeFileOrig ( cacheFile , data , options )
86
+ }
87
+
88
+ return writeFileOrig ( file , data , options )
89
+ }
90
+
91
+ promises . mkdir = async ( dir , options ) => {
92
+ if ( dir . startsWith ( pageRoot ) ) {
93
+ const filePath = dir . slice ( pageRoot . length + 1 )
94
+ const cachePath = path . join ( cacheDir , filePath )
95
+ console . log ( 'creating' , cachePath )
96
+ return mkdirOrig ( cachePath , options )
97
+ }
98
+
99
+ return mkdirOrig ( dir , options )
100
+ }
68
101
}
69
102
let NextServer
70
103
try {
@@ -139,9 +172,11 @@ const makeHandler =
139
172
}
140
173
141
174
// Sending SWR headers causes undefined behaviour with the Netlify CDN
142
- if ( multiValueHeaders [ 'cache-control' ] ?. [ 0 ] ?. includes ( 'stale-while-revalidate' ) ) {
175
+ const cacheHeader = multiValueHeaders [ 'cache-control' ] ?. [ 0 ]
176
+ if ( cacheHeader ?. includes ( 'stale-while-revalidate' ) ) {
143
177
multiValueHeaders [ 'cache-control' ] = [ 'public, max-age=0, must-revalidate' ]
144
178
}
179
+ multiValueHeaders [ 'x-render-mode' ] = [ mode ]
145
180
146
181
return {
147
182
...result ,
@@ -171,9 +206,10 @@ const path = require("path");
171
206
const pageRoot = path.resolve(path.join(__dirname, "${ publishDir } ", config.target === "server" ? "server" : "serverless", "pages"));
172
207
exports.handler = ${
173
208
isODB
174
- ? `builder((${ makeHandler ( ) . toString ( ) } )(config, "${ appDir } ", pageRoot, staticManifest));`
175
- : `(${ makeHandler ( ) . toString ( ) } )(config, "${ appDir } ", pageRoot, staticManifest);`
209
+ ? `builder((${ makeHandler ( ) . toString ( ) } )(config, "${ appDir } ", pageRoot, staticManifest, 'odb' ));`
210
+ : `(${ makeHandler ( ) . toString ( ) } )(config, "${ appDir } ", pageRoot, staticManifest, 'ssr' );`
176
211
}
177
212
`
178
213
179
214
module . exports = getHandler
215
+ /* eslint-enable max-lines-per-function, max-lines */
0 commit comments