Skip to content

Commit

Permalink
Merge branch 'canary' into shu/ee56
Browse files Browse the repository at this point in the history
  • Loading branch information
shuding authored Feb 8, 2022
2 parents 529656a + d416cd8 commit c6a8413
Show file tree
Hide file tree
Showing 29 changed files with 274 additions and 43 deletions.
2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@
"registry": "https://registry.npmjs.org/"
}
},
"version": "12.0.11-canary.7"
"version": "12.0.11-canary.8"
}
2 changes: 1 addition & 1 deletion packages/create-next-app/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "create-next-app",
"version": "12.0.11-canary.7",
"version": "12.0.11-canary.8",
"keywords": [
"react",
"next",
Expand Down
4 changes: 2 additions & 2 deletions packages/eslint-config-next/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "eslint-config-next",
"version": "12.0.11-canary.7",
"version": "12.0.11-canary.8",
"description": "ESLint configuration used by NextJS.",
"main": "index.js",
"license": "MIT",
Expand All @@ -9,7 +9,7 @@
"directory": "packages/eslint-config-next"
},
"dependencies": {
"@next/eslint-plugin-next": "12.0.11-canary.7",
"@next/eslint-plugin-next": "12.0.11-canary.8",
"@rushstack/eslint-patch": "^1.0.8",
"@typescript-eslint/parser": "^5.0.0",
"eslint-import-resolver-node": "^0.3.4",
Expand Down
2 changes: 1 addition & 1 deletion packages/eslint-plugin-next/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/eslint-plugin-next",
"version": "12.0.11-canary.7",
"version": "12.0.11-canary.8",
"description": "ESLint plugin for NextJS.",
"main": "lib/index.js",
"license": "MIT",
Expand Down
2 changes: 1 addition & 1 deletion packages/next-bundle-analyzer/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/bundle-analyzer",
"version": "12.0.11-canary.7",
"version": "12.0.11-canary.8",
"main": "index.js",
"license": "MIT",
"repository": {
Expand Down
2 changes: 1 addition & 1 deletion packages/next-codemod/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/codemod",
"version": "12.0.11-canary.7",
"version": "12.0.11-canary.8",
"license": "MIT",
"dependencies": {
"chalk": "4.1.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/next-env/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/env",
"version": "12.0.11-canary.7",
"version": "12.0.11-canary.8",
"keywords": [
"react",
"next",
Expand Down
2 changes: 1 addition & 1 deletion packages/next-mdx/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/mdx",
"version": "12.0.11-canary.7",
"version": "12.0.11-canary.8",
"main": "index.js",
"license": "MIT",
"repository": {
Expand Down
2 changes: 1 addition & 1 deletion packages/next-plugin-storybook/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/plugin-storybook",
"version": "12.0.11-canary.7",
"version": "12.0.11-canary.8",
"repository": {
"url": "vercel/next.js",
"directory": "packages/next-plugin-storybook"
Expand Down
2 changes: 1 addition & 1 deletion packages/next-polyfill-module/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/polyfill-module",
"version": "12.0.11-canary.7",
"version": "12.0.11-canary.8",
"description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)",
"main": "dist/polyfill-module.js",
"license": "MIT",
Expand Down
2 changes: 1 addition & 1 deletion packages/next-polyfill-nomodule/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/polyfill-nomodule",
"version": "12.0.11-canary.7",
"version": "12.0.11-canary.8",
"description": "A polyfill for non-dead, nomodule browsers.",
"main": "dist/polyfill-nomodule.js",
"license": "MIT",
Expand Down
2 changes: 1 addition & 1 deletion packages/next-swc/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/swc",
"version": "12.0.11-canary.7",
"version": "12.0.11-canary.8",
"private": true,
"scripts": {
"build-native": "napi build --platform --cargo-name next_swc_napi native",
Expand Down
9 changes: 8 additions & 1 deletion packages/next/build/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -554,7 +554,14 @@ export default async function build(
.traceChild('generate-required-server-files')
.traceFn(() => ({
version: 1,
config: { ...config, configFile: undefined },
config: {
...config,
configFile: undefined,
experimental: {
...config.experimental,
trustHostHeader: ciEnvironment.hasNextSupport,
},
},
appDir: dir,
files: [
ROUTES_MANIFEST,
Expand Down
4 changes: 2 additions & 2 deletions packages/next/client/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,7 @@ export async function initNext(
render(renderCtx)
}

export async function render(renderingProps: RenderRouteInfo): Promise<void> {
async function render(renderingProps: RenderRouteInfo): Promise<void> {
if (renderingProps.err) {
await renderError(renderingProps)
return
Expand Down Expand Up @@ -462,7 +462,7 @@ export async function render(renderingProps: RenderRouteInfo): Promise<void> {
// This method handles all runtime and debug errors.
// 404 and 500 errors are special kind of errors
// and they are still handle via the main render method.
export function renderError(renderErrorProps: RenderErrorProps): Promise<any> {
function renderError(renderErrorProps: RenderErrorProps): Promise<any> {
const { App, err } = renderErrorProps

// In development runtime errors are caught by our overlay
Expand Down
4 changes: 1 addition & 3 deletions packages/next/client/next-dev.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { initNext, version, router, emitter, render, renderError } from './'
import { initNext, version, router, emitter } from './'
import initOnDemandEntries from './dev/on-demand-entries-client'
import initWebpackHMR from './dev/webpack-hot-middleware-client'
import initializeBuildWatcher from './dev/dev-build-watcher'
Expand Down Expand Up @@ -44,8 +44,6 @@ window.next = {
return router
},
emitter,
render,
renderError,
}
initNext({ webpackHMR, beforeRender: displayContent })
.then(() => {
Expand Down
4 changes: 1 addition & 3 deletions packages/next/client/next.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { initNext, version, router, emitter, render, renderError } from './'
import { initNext, version, router, emitter } from './'

window.next = {
version,
Expand All @@ -7,8 +7,6 @@ window.next = {
return router
},
emitter,
render,
renderError,
}

initNext().catch(console.error)
14 changes: 7 additions & 7 deletions packages/next/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "next",
"version": "12.0.11-canary.7",
"version": "12.0.11-canary.8",
"description": "The React Framework",
"main": "./dist/server/next.js",
"license": "MIT",
Expand Down Expand Up @@ -69,7 +69,7 @@
]
},
"dependencies": {
"@next/env": "12.0.11-canary.7",
"@next/env": "12.0.11-canary.8",
"caniuse-lite": "^1.0.30001283",
"postcss": "8.4.5",
"styled-jsx": "5.0.0",
Expand Down Expand Up @@ -117,11 +117,11 @@
"@hapi/accept": "5.0.2",
"@napi-rs/cli": "1.2.1",
"@napi-rs/triples": "1.0.3",
"@next/polyfill-module": "12.0.11-canary.7",
"@next/polyfill-nomodule": "12.0.11-canary.7",
"@next/react-dev-overlay": "12.0.11-canary.7",
"@next/react-refresh-utils": "12.0.11-canary.7",
"@next/swc": "12.0.11-canary.7",
"@next/polyfill-module": "12.0.11-canary.8",
"@next/polyfill-nomodule": "12.0.11-canary.8",
"@next/react-dev-overlay": "12.0.11-canary.8",
"@next/react-refresh-utils": "12.0.11-canary.8",
"@next/swc": "12.0.11-canary.8",
"@peculiar/webcrypto": "1.1.7",
"@taskr/clear": "1.1.0",
"@taskr/esnext": "1.1.0",
Expand Down
44 changes: 43 additions & 1 deletion packages/next/server/api-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,11 @@ export async function apiResolver(
res: ServerResponse,
query: any,
resolverModule: any,
apiContext: __ApiPreviewProps,
apiContext: __ApiPreviewProps & {
trustHostHeader?: boolean
hostname?: string
port?: number
},
propagateError: boolean,
dev?: boolean,
page?: string
Expand Down Expand Up @@ -95,6 +99,8 @@ export async function apiResolver(
apiRes.setPreviewData = (data, options = {}) =>
setPreviewData(apiRes, data, Object.assign({}, apiContext, options))
apiRes.clearPreviewData = () => clearPreviewData(apiRes)
apiRes.unstable_revalidate = (urlPath: string) =>
unstable_revalidate(urlPath, req, apiContext)

const resolver = interopDefault(resolverModule)
let wasPiped = false
Expand Down Expand Up @@ -334,6 +340,42 @@ export function sendJson(res: NextApiResponse, jsonBody: any): void {
res.send(jsonBody)
}

const PRERENDER_REVALIDATE_HEADER = 'x-prerender-revalidate'

export function checkIsManualRevalidate(
req: IncomingMessage | BaseNextRequest,
previewProps: __ApiPreviewProps
): boolean {
return req.headers[PRERENDER_REVALIDATE_HEADER] === previewProps.previewModeId
}

async function unstable_revalidate(
urlPath: string,
req: IncomingMessage | BaseNextRequest,
context: {
hostname?: string
port?: number
previewModeId: string
trustHostHeader?: boolean
}
) {
if (!context.trustHostHeader && (!context.hostname || !context.port)) {
throw new Error(
`"hostname" and "port" must be provided when starting next to use "unstable_revalidate". See more here https://nextjs.org/docs/advanced-features/custom-server`
)
}

const baseUrl = context.trustHostHeader
? `https://${req.headers.host}`
: `http://${context.hostname}:${context.port}`

return fetch(`${baseUrl}${urlPath}`, {
headers: {
[PRERENDER_REVALIDATE_HEADER]: context.previewModeId,
},
})
}

const COOKIE_NAME_PRERENDER_BYPASS = `__prerender_bypass`
const COOKIE_NAME_PRERENDER_DATA = `__next_preview_data`

Expand Down
23 changes: 21 additions & 2 deletions packages/next/server/base-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ import { MIDDLEWARE_ROUTE } from '../lib/constants'
import { addRequestMeta, getRequestMeta } from './request-meta'
import { createHeaderRoute, createRedirectRoute } from './server-route-utils'
import { PrerenderManifest } from '../build'
import { checkIsManualRevalidate } from '../server/api-utils'

export type FindComponentsResult = {
components: LoadComponentsReturnType
Expand Down Expand Up @@ -1173,6 +1174,15 @@ export default abstract class Server {
isPreviewMode = previewData !== false
}

let isManualRevalidate = false

if (isSSG) {
isManualRevalidate = checkIsManualRevalidate(
req,
this.renderOpts.previewProps
)
}

// Compute the iSSG cache key. We use the rewroteUrl since
// pages with fallback: false are allowed to be rewritten to
// and we need to look up the path by the rewritten path
Expand Down Expand Up @@ -1238,7 +1248,7 @@ export default abstract class Server {

let ssgCacheKey =
isPreviewMode || !isSSG || this.minimalMode || opts.supportsDynamicHTML
? null // Preview mode bypasses the cache
? null // Preview mode and manual revalidate bypasses the cache
: `${locale ? `/${locale}` : ''}${
(pathname === '/' || resolvedUrlPathname === '/') && locale
? ''
Expand Down Expand Up @@ -1364,7 +1374,7 @@ export default abstract class Server {

const cacheEntry = await this.responseCache.get(
ssgCacheKey,
async (hasResolved) => {
async (hasResolved, hadCache) => {
const isProduction = !this.renderOpts.dev
const isDynamicPathname = isDynamicRoute(pathname)
const didRespond = hasResolved || res.sent
Expand All @@ -1380,6 +1390,12 @@ export default abstract class Server {
fallbackMode = 'blocking'
}

// only allow manual revalidate for fallback: true/blocking
// or for prerendered fallback: false paths
if (isManualRevalidate && (fallbackMode !== false || hadCache)) {
fallbackMode = 'blocking'
}

// When we did not respond from cache, we need to choose to block on
// rendering or return a skeleton.
//
Expand Down Expand Up @@ -1464,6 +1480,9 @@ export default abstract class Server {
? result.revalidate
: /* default to minimum revalidate (this should be an invariant) */ 1,
}
},
{
isManualRevalidate,
}
)

Expand Down
8 changes: 7 additions & 1 deletion packages/next/server/next-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -452,7 +452,13 @@ export default class NextNodeServer extends BaseServer {
res.originalResponse,
query,
pageModule,
this.renderOpts.previewProps,
{
...this.renderOpts.previewProps,
port: this.port,
hostname: this.hostname,
// internal config so is not typed
trustHostHeader: (this.nextConfig.experimental as any).trustHostHeader,
},
this.minimalMode,
this.renderOpts.dev,
page
Expand Down
14 changes: 10 additions & 4 deletions packages/next/server/response-cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ export type ResponseCacheEntry = {
}

type ResponseGenerator = (
hasResolved: boolean
hasResolved: boolean,
hadCache: boolean
) => Promise<ResponseCacheEntry | null>

export default class ResponseCache {
Expand All @@ -34,7 +35,8 @@ export default class ResponseCache {

public get(
key: string | null,
responseGenerator: ResponseGenerator
responseGenerator: ResponseGenerator,
context: { isManualRevalidate?: boolean }
): Promise<ResponseCacheEntry | null> {
const pendingResponse = key ? this.pendingResponses.get(key) : null
if (pendingResponse) {
Expand Down Expand Up @@ -71,7 +73,11 @@ export default class ResponseCache {
;(async () => {
try {
const cachedResponse = key ? await this.incrementalCache.get(key) : null
if (cachedResponse) {
if (
cachedResponse &&
(!context.isManualRevalidate ||
cachedResponse.revalidateAfter === false)
) {
resolve({
revalidate: cachedResponse.curRevalidate,
value:
Expand All @@ -90,7 +96,7 @@ export default class ResponseCache {
}
}

const cacheEntry = await responseGenerator(resolved)
const cacheEntry = await responseGenerator(resolved, !!cachedResponse)
resolve(cacheEntry)

if (key && cacheEntry && typeof cacheEntry.revalidate !== 'undefined') {
Expand Down
2 changes: 2 additions & 0 deletions packages/next/shared/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,8 @@ export type NextApiResponse<T = any> = ServerResponse & {
}
) => NextApiResponse<T>
clearPreviewData: () => NextApiResponse<T>

unstable_revalidate: (urlPath: string) => Promise<Response>
}

/**
Expand Down
Loading

0 comments on commit c6a8413

Please sign in to comment.