Skip to content

Commit

Permalink
Add dataRoutes field to routes-manifest for SSG and serverProps routes (
Browse files Browse the repository at this point in the history
#10622)

* Add dataRoutes field to routes-manifest for SSG and serverProps routes

* Update routes-manifest test
  • Loading branch information
ijjk committed Feb 26, 2020
1 parent 395714a commit 6dea45b
Show file tree
Hide file tree
Showing 4 changed files with 169 additions and 52 deletions.
15 changes: 8 additions & 7 deletions packages/next/build/index.ts
Expand Up @@ -569,20 +569,21 @@ export default async function build(dir: string, conf = null): Promise<void> {
)
staticCheckWorkers.end()

if (serverPropsPages.size > 0) {
if (serverPropsPages.size > 0 || ssgPages.size > 0) {
// We update the routes manifest after the build with the
// serverProps routes since we can't determine this until after build
routesManifest.serverPropsRoutes = {}

for (const page of serverPropsPages) {
// data routes since we can't determine these until after build
routesManifest.dataRoutes = getSortedRoutes([
...serverPropsPages,
...ssgPages,
]).map(page => {
const pagePath = normalizePagePath(page)
const dataRoute = path.posix.join(
'/_next/data',
buildId,
`${pagePath}.json`
)

routesManifest.serverPropsRoutes[page] = {
return {
page,
dataRouteRegex: isDynamicRoute(page)
? getRouteRegex(dataRoute.replace(/\.json$/, '')).re.source.replace(
Expand All @@ -597,7 +598,7 @@ export default async function build(dir: string, conf = null): Promise<void> {
)}$`
).source,
}
}
})

await fsWriteFile(
routesManifestPath,
Expand Down
31 changes: 31 additions & 0 deletions test/integration/dynamic-routing/test/index.test.js
Expand Up @@ -15,6 +15,7 @@ import {
normalizeRegEx,
} from 'next-test-utils'
import cheerio from 'cheerio'
import escapeRegex from 'escape-string-regexp'

jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000 * 60 * 2

Expand Down Expand Up @@ -485,13 +486,43 @@ function runTests(dev) {
route.regex = normalizeRegEx(route.regex)
}

for (const route of manifest.dataRoutes) {
route.dataRouteRegex = normalizeRegEx(route.dataRouteRegex)
}

expect(manifest).toEqual({
version: 1,
pages404: true,
basePath: '',
headers: [],
rewrites: [],
redirects: [],
dataRoutes: [
{
dataRouteRegex: normalizeRegEx(
`^\\/_next\\/data\\/${escapeRegex(
buildId
)}\\/p1\\/p2\\/all\\-ssg\\/(.+?)\\.json$`
),
page: '/p1/p2/all-ssg/[...rest]',
},
{
dataRouteRegex: normalizeRegEx(
`^\\/_next\\/data\\/${escapeRegex(
buildId
)}\\/p1\\/p2\\/nested\\-all\\-ssg\\/(.+?)\\.json$`
),
page: '/p1/p2/nested-all-ssg/[...rest]',
},
{
dataRouteRegex: normalizeRegEx(
`^\\/_next\\/data\\/${escapeRegex(
buildId
)}\\/p1\\/p2\\/predefined\\-ssg\\/(.+?)\\.json$`
),
page: '/p1/p2/predefined-ssg/[...rest]',
},
],
dynamicRoutes: [
{
page: '/blog/[name]/comment/[id]',
Expand Down
98 changes: 53 additions & 45 deletions test/integration/getserverprops/test/index.test.js
Expand Up @@ -25,72 +25,72 @@ let appPort
let buildId
let stderr

const expectedManifestRoutes = () => ({
'/something': {
page: '/something',
const expectedManifestRoutes = () => [
{
dataRouteRegex: normalizeRegEx(
`^\\/_next\\/data\\/${escapeRegex(buildId)}\\/something.json$`
`^\\/_next\\/data\\/${escapeRegex(buildId)}\\/index.json$`
),
page: '/',
},
'/blog/[post]': {
page: '/blog/[post]',
{
dataRouteRegex: normalizeRegEx(
`^\\/_next\\/data\\/${escapeRegex(buildId)}\\/blog\\/([^/]+?)\\.json$`
`^\\/_next\\/data\\/${escapeRegex(buildId)}\\/another.json$`
),
page: '/another',
},
'/': {
page: '/',
{
dataRouteRegex: normalizeRegEx(
`^\\/_next\\/data\\/${escapeRegex(buildId)}\\/index.json$`
`^\\/_next\\/data\\/${escapeRegex(buildId)}\\/blog.json$`
),
page: '/blog',
},
'/default-revalidate': {
page: '/default-revalidate',
{
dataRouteRegex: normalizeRegEx(
`^\\/_next\\/data\\/${escapeRegex(buildId)}\\/default-revalidate.json$`
`^\\/_next\\/data\\/${escapeRegex(buildId)}\\/blog\\/([^\\/]+?)\\.json$`
),
page: '/blog/[post]',
},
'/catchall/[...path]': {
page: '/catchall/[...path]',
{
dataRouteRegex: normalizeRegEx(
`^\\/_next\\/data\\/${escapeRegex(buildId)}\\/catchall\\/(.+?)\\.json$`
`^\\/_next\\/data\\/${escapeRegex(
buildId
)}\\/blog\\/([^\\/]+?)\\/([^\\/]+?)\\.json$`
),
page: '/blog/[post]/[comment]',
},
'/blog': {
page: '/blog',
{
dataRouteRegex: normalizeRegEx(
`^\\/_next\\/data\\/${escapeRegex(buildId)}\\/blog.json$`
`^\\/_next\\/data\\/${escapeRegex(buildId)}\\/catchall\\/(.+?)\\.json$`
),
page: '/catchall/[...path]',
},
'/blog/[post]/[comment]': {
page: '/blog/[post]/[comment]',
{
dataRouteRegex: normalizeRegEx(
`^\\/_next\\/data\\/${escapeRegex(
buildId
)}\\/blog\\/([^/]+?)\\/([^/]+?)\\.json$`
`^\\/_next\\/data\\/${escapeRegex(buildId)}\\/default-revalidate.json$`
),
page: '/default-revalidate',
},
'/user/[user]/profile': {
page: '/user/[user]/profile',
{
dataRouteRegex: normalizeRegEx(
`^\\/_next\\/data\\/${escapeRegex(
buildId
)}\\/user\\/([^/]+?)\\/profile\\.json$`
`^\\/_next\\/data\\/${escapeRegex(buildId)}\\/invalid-keys.json$`
),
page: '/invalid-keys',
},
'/another': {
page: '/another',
{
dataRouteRegex: normalizeRegEx(
`^\\/_next\\/data\\/${escapeRegex(buildId)}\\/another.json$`
`^\\/_next\\/data\\/${escapeRegex(buildId)}\\/something.json$`
),
page: '/something',
},
'/invalid-keys': {
{
dataRouteRegex: normalizeRegEx(
`^\\/_next\\/data\\/${escapeRegex(buildId)}\\/invalid-keys.json$`
`^\\/_next\\/data\\/${escapeRegex(
buildId
)}\\/user\\/([^\\/]+?)\\/profile\\.json$`
),
page: '/invalid-keys',
page: '/user/[user]/profile',
},
})
]

const navigateTest = (dev = false) => {
it('should navigate between pages successfully', async () => {
Expand Down Expand Up @@ -209,15 +209,21 @@ const runTests = (dev = false) => {
expect(JSON.parse(query)).toEqual({ path: ['first'] })

const data = JSON.parse(
await renderViaHTTP(appPort, `/_next/data/${buildId}/catchall/first.json`)
await renderViaHTTP(
appPort,
`/_next/data/${escapeRegex(buildId)}/catchall/first.json`
)
)

expect(data.pageProps.params).toEqual({ path: ['first'] })
})

it('should return data correctly', async () => {
const data = JSON.parse(
await renderViaHTTP(appPort, `/_next/data/${buildId}/something.json`)
await renderViaHTTP(
appPort,
`/_next/data/${escapeRegex(buildId)}/something.json`
)
)
expect(data.pageProps.world).toBe('world')
})
Expand All @@ -226,15 +232,18 @@ const runTests = (dev = false) => {
const data = JSON.parse(
await renderViaHTTP(
appPort,
`/_next/data/${buildId}/something.json?another=thing`
`/_next/data/${escapeRegex(buildId)}/something.json?another=thing`
)
)
expect(data.pageProps.query.another).toBe('thing')
})

it('should return data correctly for dynamic page', async () => {
const data = JSON.parse(
await renderViaHTTP(appPort, `/_next/data/${buildId}/blog/post-1.json`)
await renderViaHTTP(
appPort,
`/_next/data/${escapeRegex(buildId)}/blog/post-1.json`
)
)
expect(data.pageProps.post).toBe('post-1')
})
Expand Down Expand Up @@ -367,15 +376,14 @@ const runTests = (dev = false) => {
})

it('should output routes-manifest correctly', async () => {
const { serverPropsRoutes } = await fs.readJSON(
const { dataRoutes } = await fs.readJSON(
join(appDir, '.next/routes-manifest.json')
)
for (const key of Object.keys(serverPropsRoutes)) {
const val = serverPropsRoutes[key].dataRouteRegex
serverPropsRoutes[key].dataRouteRegex = normalizeRegEx(val)
for (const route of dataRoutes) {
route.dataRouteRegex = normalizeRegEx(route.dataRouteRegex)
}

expect(serverPropsRoutes).toEqual(expectedManifestRoutes())
expect(dataRoutes).toEqual(expectedManifestRoutes())
})

it('should set no-cache, no-store, must-revalidate header', async () => {
Expand Down
77 changes: 77 additions & 0 deletions test/integration/prerender/test/index.test.js
Expand Up @@ -589,6 +589,83 @@ const runTests = (dev = false, looseMode = false) => {
})
}

it('outputs dataRoutes in routes-manifest correctly', async () => {
const { dataRoutes } = JSON.parse(
await fs.readFile(join(appDir, '.next/routes-manifest.json'), 'utf8')
)

for (const route of dataRoutes) {
route.dataRouteRegex = normalizeRegEx(route.dataRouteRegex)
}

expect(dataRoutes).toEqual([
{
dataRouteRegex: normalizeRegEx(
`^\\/_next\\/data\\/${escapeRegex(buildId)}\\/index.json$`
),
page: '/',
},
{
dataRouteRegex: normalizeRegEx(
`^\\/_next\\/data\\/${escapeRegex(buildId)}\\/another.json$`
),
page: '/another',
},
{
dataRouteRegex: normalizeRegEx(
`^\\/_next\\/data\\/${escapeRegex(buildId)}\\/blog.json$`
),
page: '/blog',
},
{
dataRouteRegex: normalizeRegEx(
`^\\/_next\\/data\\/${escapeRegex(
buildId
)}\\/blog\\/([^\\/]+?)\\.json$`
),
page: '/blog/[post]',
},
{
dataRouteRegex: normalizeRegEx(
`^\\/_next\\/data\\/${escapeRegex(
buildId
)}\\/blog\\/([^\\/]+?)\\/([^\\/]+?)\\.json$`
),
page: '/blog/[post]/[comment]',
},
{
dataRouteRegex: normalizeRegEx(
`^\\/_next\\/data\\/${escapeRegex(
buildId
)}\\/catchall\\/(.+?)\\.json$`
),
page: '/catchall/[...slug]',
},
{
dataRouteRegex: normalizeRegEx(
`^\\/_next\\/data\\/${escapeRegex(
buildId
)}\\/default-revalidate.json$`
),
page: '/default-revalidate',
},
{
dataRouteRegex: normalizeRegEx(
`^\\/_next\\/data\\/${escapeRegex(buildId)}\\/something.json$`
),
page: '/something',
},
{
dataRouteRegex: normalizeRegEx(
`^\\/_next\\/data\\/${escapeRegex(
buildId
)}\\/user\\/([^\\/]+?)\\/profile\\.json$`
),
page: '/user/[user]/profile',
},
])
})

it('outputs a prerender-manifest correctly', async () => {
const manifest = JSON.parse(
await fs.readFile(join(appDir, '.next/prerender-manifest.json'), 'utf8')
Expand Down

0 comments on commit 6dea45b

Please sign in to comment.