Skip to content

Commit

Permalink
Merge branch 'canary' into fix/buffer-unusable-on-edge
Browse files Browse the repository at this point in the history
  • Loading branch information
feugy committed Aug 1, 2022
2 parents 5388736 + e9d23d7 commit e910314
Show file tree
Hide file tree
Showing 15 changed files with 111 additions and 111 deletions.
2 changes: 1 addition & 1 deletion docs/basic-features/data-fetching/get-static-paths.md
Expand Up @@ -68,7 +68,7 @@ In development (`next dev`), `getStaticPaths` will be called on every request.

## Generating paths on-demand

`getStaticProps` allows you to control which pages are generated during the build instead of on-demand with [`fallback`](/docs/api-reference/data-fetching/get-static-paths.md#fallback-blocking). Generating more pages during a build will cause slower builds.
`getStaticPaths` allows you to control which pages are generated during the build instead of on-demand with [`fallback`](/docs/api-reference/data-fetching/get-static-paths.md#fallback-blocking). Generating more pages during a build will cause slower builds.

You can defer generating all pages on-demand by returning an empty array for `paths`. This can be especially helpful when deploying your Next.js application to multiple environments. For example, you can have faster builds by generating all pages on-demand for previews (but not production builds). This is helpful for sites with hundreds/thousands of static pages.

Expand Down
4 changes: 3 additions & 1 deletion packages/next/bin/next.ts
Expand Up @@ -2,7 +2,6 @@
import * as log from '../build/output/log'
import arg from 'next/dist/compiled/arg/index.js'
import { NON_STANDARD_NODE_ENV } from '../lib/constants'
import { shouldUseReactRoot } from '../server/utils'
;['react', 'react-dom'].forEach((dependency) => {
try {
// When 'npm link' is used it checks the clone location. Not the project.
Expand Down Expand Up @@ -107,6 +106,9 @@ if (process.env.NODE_ENV) {
;(process.env as any).NODE_ENV = process.env.NODE_ENV || defaultEnv
;(process.env as any).NEXT_RUNTIME = 'nodejs'

// In node.js runtime, react has to be required after NODE_ENV is set,
// so that the correct dev/prod bundle could be loaded into require.cache.
const { shouldUseReactRoot } = require('../server/utils')
if (shouldUseReactRoot) {
;(process.env as any).__NEXT_REACT_ROOT = 'true'
}
Expand Down
14 changes: 6 additions & 8 deletions packages/next/client/page-loader.ts
Expand Up @@ -11,7 +11,7 @@ import { createRouteLoader, getClientBuildManifest } from './route-loader'

declare global {
interface Window {
__DEV_MIDDLEWARE_MANIFEST?: [location: string, isSSR: boolean][]
__DEV_MIDDLEWARE_MANIFEST?: { location?: string }
__DEV_PAGES_MANIFEST?: { pages: string[] }
__SSG_MANIFEST_CB?: () => void
__SSG_MANIFEST?: Set<string>
Expand All @@ -30,9 +30,7 @@ export default class PageLoader {
private assetPrefix: string
private promisedSsgManifest: Promise<Set<string>>
private promisedDevPagesManifest?: Promise<string[]>
private promisedMiddlewareManifest?: Promise<
[location: string, isSSR: boolean][]
>
private promisedMiddlewareManifest?: Promise<{ location: string }>

public routeLoader: RouteLoader

Expand Down Expand Up @@ -81,12 +79,12 @@ export default class PageLoader {
}
}

getMiddlewareList() {
getMiddleware() {
if (process.env.NODE_ENV === 'production') {
const middlewareRegex = process.env.__NEXT_MIDDLEWARE_REGEX
window.__MIDDLEWARE_MANIFEST = middlewareRegex
? [[middlewareRegex, false]]
: []
? { location: middlewareRegex }
: undefined
return window.__MIDDLEWARE_MANIFEST
} else {
if (window.__DEV_MIDDLEWARE_MANIFEST) {
Expand All @@ -99,7 +97,7 @@ export default class PageLoader {
`${this.assetPrefix}/_next/static/${this.buildId}/_devMiddlewareManifest.json`
)
.then((res) => res.json())
.then((manifest: [location: string, isSSR: boolean][]) => {
.then((manifest: { location?: string }) => {
window.__DEV_MIDDLEWARE_MANIFEST = manifest
return manifest
})
Expand Down
2 changes: 1 addition & 1 deletion packages/next/client/route-loader.ts
Expand Up @@ -13,7 +13,7 @@ declare global {
interface Window {
__BUILD_MANIFEST?: Record<string, string[]>
__BUILD_MANIFEST_CB?: Function
__MIDDLEWARE_MANIFEST?: [location: string, isSSR: boolean][]
__MIDDLEWARE_MANIFEST?: { location: string }
__MIDDLEWARE_MANIFEST_CB?: Function
}
}
Expand Down
9 changes: 5 additions & 4 deletions packages/next/server/dev/next-dev-server.ts
Expand Up @@ -964,15 +964,16 @@ export default class DevServer extends Server {
type: 'route',
name: `_next/${CLIENT_STATIC_FILES_PATH}/${this.buildId}/${DEV_MIDDLEWARE_MANIFEST}`,
fn: async (_req, res) => {
const edgeRoutes = this.getEdgeFunctions().concat(
this.middleware ? [this.middleware] : []
)
res.statusCode = 200
res.setHeader('Content-Type', 'application/json; charset=utf-8')
res
.body(
JSON.stringify(
edgeRoutes.map((edgeRoute) => [edgeRoute.re!.source])
this.middleware
? {
location: this.middleware.re!.source,
}
: {}
)
)
.send()
Expand Down
15 changes: 7 additions & 8 deletions packages/next/shared/lib/router/router.ts
Expand Up @@ -1159,7 +1159,7 @@ export default class Router implements BaseRouter {
;[pages, { __rewrites: rewrites }] = await Promise.all([
this.pageLoader.getPageList(),
getClientBuildManifest(),
this.pageLoader.getMiddlewareList(),
this.pageLoader.getMiddleware(),
])
} catch (err) {
// If we fail to resolve the page list or client-build manifest, we must
Expand Down Expand Up @@ -2267,18 +2267,17 @@ interface MiddlewareEffectParams<T extends FetchDataOutput> {
function matchesMiddleware<T extends FetchDataOutput>(
options: MiddlewareEffectParams<T>
): Promise<boolean> {
return Promise.resolve(options.router.pageLoader.getMiddlewareList()).then(
(items) => {
return Promise.resolve(options.router.pageLoader.getMiddleware()).then(
(middleware) => {
const { pathname: asPathname } = parsePath(options.asPath)
const cleanedAs = hasBasePath(asPathname)
? removeBasePath(asPathname)
: asPathname

return !!items?.some(([regex, ssr]) => {
return (
!ssr && new RegExp(regex).test(addLocale(cleanedAs, options.locale))
)
})
const regex = middleware?.location
return (
!!regex && new RegExp(regex).test(addLocale(cleanedAs, options.locale))
)
}
)
}
Expand Down
9 changes: 9 additions & 0 deletions test/e2e/middleware-general/test/index.test.ts
Expand Up @@ -95,6 +95,15 @@ describe('Middleware Runtime', () => {
await browser.close()
}
})

it('should only contain middleware route in dev middleware manifest', async () => {
const res = await fetchViaHTTP(
next.url,
`/_next/static/${next.buildId}/_devMiddlewareManifest.json`
)
const { location } = await res.json()
expect(location).toBe('.*')
})
}

if ((global as any).isNextStart) {
Expand Down
25 changes: 13 additions & 12 deletions test/e2e/middleware-matcher/index.test.ts
Expand Up @@ -90,11 +90,12 @@ describe('Middleware can set the matcher in its config', () => {
: 'window.__MIDDLEWARE_MANIFEST'
)

return Array.isArray(manifest) &&
manifest?.[0]?.[0].includes('with-middleware') &&
manifest?.[0]?.[0].includes('another-middleware')
const { location } = manifest
return location &&
location.includes('with-middleware') &&
location.includes('another-middleware')
? 'success'
: manifest
: 'failed'
}, 'success')
})

Expand Down Expand Up @@ -141,12 +142,12 @@ describe('using a single matcher', () => {
next = await createNext({
files: {
'pages/[...route].js': `
export default function Page({ message }) {
export default function Page({ message }) {
return <div>
<p>root page</p>
<p>{message}</p>
</div>
}
}
export const getServerSideProps = ({ params }) => {
return {
Expand Down Expand Up @@ -222,11 +223,11 @@ describe('using a single matcher with i18n', () => {
next = await createNext({
files: {
'pages/index.js': `
export default function Page({ message }) {
export default function Page({ message }) {
return <div>
<p>{message}</p>
</div>
}
}
export const getServerSideProps = ({ params, locale }) => ({
props: { message: \`(\${locale}) Hello from /\` }
})
Expand All @@ -237,7 +238,7 @@ describe('using a single matcher with i18n', () => {
<p>catchall page</p>
<p>{message}</p>
</div>
}
}
export const getServerSideProps = ({ params, locale }) => ({
props: { message: \`(\${locale}) Hello from /\` + params.route.join("/") }
})
Expand Down Expand Up @@ -311,12 +312,12 @@ describe('using a single matcher with i18n and basePath', () => {
next = await createNext({
files: {
'pages/index.js': `
export default function Page({ message }) {
export default function Page({ message }) {
return <div>
<p>root page</p>
<p>{message}</p>
</div>
}
}
export const getServerSideProps = ({ params, locale }) => ({
props: { message: \`(\${locale}) Hello from /\` }
})
Expand All @@ -327,7 +328,7 @@ describe('using a single matcher with i18n and basePath', () => {
<p>catchall page</p>
<p>{message}</p>
</div>
}
}
export const getServerSideProps = ({ params, locale }) => ({
props: { message: \`(\${locale}) Hello from /\` + params.route.join("/") }
})
Expand Down
File renamed without changes.
File renamed without changes.
17 changes: 17 additions & 0 deletions test/e2e/ssr-react-context/app/pages/consumer.js
@@ -0,0 +1,17 @@
import React from 'react'

const NumberContext = React.createContext(0)

export default function page() {
return (
<NumberContext.Provider value={12345}>
<NumberContext.Consumer>
{(value) => <p>Value: {value}</p>}
</NumberContext.Consumer>
</NumberContext.Provider>
)
}

export async function getServerSideProps() {
return { props: {} }
}
File renamed without changes.
46 changes: 46 additions & 0 deletions test/e2e/ssr-react-context/index.test.ts
@@ -0,0 +1,46 @@
import { join } from 'path'
import { renderViaHTTP, check } from 'next-test-utils'
import { NextInstance } from 'test/lib/next-modes/base'
import { createNext, FileRef } from 'e2e-utils'

describe('React Context', () => {
let next: NextInstance

beforeAll(async () => {
next = await createNext({
files: {
pages: new FileRef(join(__dirname, 'app/pages')),
'context.js': new FileRef(join(__dirname, 'app/context.js')),
},
})
})
afterAll(() => next.destroy())

it('should render a page with context', async () => {
const html = await renderViaHTTP(next.url, '/')
expect(html).toMatch(/Value: .*?hello world/)
})

it('should render correctly with context consumer', async () => {
const html = await renderViaHTTP(next.url, '/consumer')
expect(html).toMatch(/Value: .*?12345/)
})

if ((globalThis as any).isNextDev) {
it('should render with context after change', async () => {
const aboutAppPagePath = 'pages/_app.js'
const originalContent = await next.readFile(aboutAppPagePath)
await next.patchFile(
aboutAppPagePath,
originalContent.replace('hello world', 'new value')
)

try {
await check(() => renderViaHTTP(next.url, '/'), /Value: .*?new value/)
} finally {
await next.patchFile(aboutAppPagePath, originalContent)
}
await check(() => renderViaHTTP(next.url, '/'), /Value: .*?hello world/)
})
}
})
14 changes: 3 additions & 11 deletions test/e2e/switchable-runtime/index.test.ts
Expand Up @@ -61,21 +61,13 @@ describe('Switchable runtime', () => {

if ((global as any).isNextDev) {
describe('Switchable runtime (dev)', () => {
it('should include edge api routes and edge ssr routes into dev middleware manifest', async () => {
it('should not include edge api routes and edge ssr routes into dev middleware manifest', async () => {
const res = await fetchViaHTTP(
next.url,
`/_next/static/${next.buildId}/_devMiddlewareManifest.json`
)
const routesMatchers = await res.json()

expect(
routesMatchers.some((matcher) =>
matcher[0].startsWith('^\\/api\\/edge')
)
).toBe(true)
expect(
routesMatchers.some((matcher) => matcher[0].startsWith('^\\/edge'))
).toBe(true)
const devMiddlewareManifest = await res.json()
expect(devMiddlewareManifest).toEqual({})
})

it.skip('should support client side navigation to ssr rsc pages', async () => {
Expand Down
65 changes: 0 additions & 65 deletions test/integration/ssr-ctx/test/index.test.js

This file was deleted.

0 comments on commit e910314

Please sign in to comment.