forked from netlify/next-on-netlify
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathallNextJsPages.js
124 lines (98 loc) · 3.69 KB
/
allNextJsPages.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
const { join } = require('path')
const { readFileSync, readJSONSync } = require('fs-extra')
const { NEXT_DIST_DIR } = require('./config')
// Return all NextJS pages with route, file, type, and any other params
const getAllPages = () => {
const pages = []
// Read pages manifest that tells us which SSR and HTML pages exist
const ssrAndHtmlPages = readJSONSync(
join(NEXT_DIST_DIR, "serverless", "pages-manifest.json")
)
// Read prerender manifest that tells us which SSG pages exist
const { routes: staticSsgPages, dynamicRoutes: dynamicSsgPages } = readJSONSync(
join(NEXT_DIST_DIR, "prerender-manifest.json")
)
// Read routes manifest that tells us which data routes should exist
const routesManifest = readJSONSync(
join(NEXT_DIST_DIR, "routes-manifest.json")
)
const dataRoutes = routesManifest.dataRoutes || []
// Get build ID that is used for data routes, e.g. /_next/data/BUILD_ID/...
const fileContents = readFileSync(join(NEXT_DIST_DIR, "BUILD_ID"))
const buildId = fileContents.toString()
// Parse SSR and HTML pages
Object.entries(ssrAndHtmlPages).forEach(([route, filePath]) => {
// Skip framework pages, such as _app and _error
if(["/_app", "/_document", "/_error"].includes(route))
return
// Skip page if it is actually an SSG page
const normalizedRoute = route === "/index" ? "/" : route
if(normalizedRoute in staticSsgPages || normalizedRoute in dynamicSsgPages)
return
// Check if we already have a page pointing to this file
// If so, just add the route
const existingPage = pages.find(page => page.filePath == filePath)
if(existingPage) {
existingPage.alternativeRoutes.push(route)
return
}
// Otherwise, create new page
const type = filePath.endsWith(".html") ? "html" : "ssr"
const alternativeRoutes = []
// Check if we have a data route for this page
// This is relevant only for pages with getServerSideProps.
// We need to add a second route for redirecting requests for
// the JSON data to the Netlify Function.
const dataRoute = dataRoutes.find(({ page }) => page === route)
if(dataRoute)
alternativeRoutes.push(join('/_next/data', buildId, `${route}.json`))
pages.push(new Page({ route, type, filePath, alternativeRoutes }))
})
// Parse SSG pages
Object.entries(staticSsgPages).forEach(([ route, { dataRoute }]) => {
pages.push(new Page({ route, type: "ssg", dataRoute, alternativeRoutes: route === "/" ? ["/index"] : [] }))
})
Object.entries(dynamicSsgPages).forEach(([ route, { dataRoute, fallback }]) => {
// Ignore pages without fallback, these are already handled by the
// static SSG page block above
if(fallback === false)
return
const filePath = join("pages", `${route}.js`)
pages.push(new Page({ route, filePath, type: "ssg-fallback", alternativeRoutes: [dataRoute] }))
})
return pages
}
// Represent a NextJS page
class Page {
constructor({ route, type, ...otherParams }) {
this.alternativeRoutes = []
Object.assign(this, { route, type, ...otherParams })
}
isSsr() {
return this.type === "ssr"
}
isHtml() {
return this.type === "html"
}
isSsg() {
return this.type === "ssg"
}
isSsgFallback() {
return this.type === "ssg-fallback"
}
routeFile(ext) {
return `${this.route.replace(/^\/$/, '/index')}${ext}`
}
get htmlFile() {
return this.routeFile(".html")
}
get jsonFile() {
return this.routeFile(".json")
}
// Return route and alternative routes as array
get routesAsArray() {
return [this.route, ...this.alternativeRoutes]
}
}
const allNextJsPages = getAllPages()
module.exports = allNextJsPages