Skip to content

Commit

Permalink
Merge branch 'canary' into feat/configurable-dynamic-guards
Browse files Browse the repository at this point in the history
  • Loading branch information
feugy committed Aug 31, 2022
2 parents 522af46 + 591f341 commit 109febe
Show file tree
Hide file tree
Showing 35 changed files with 797 additions and 364 deletions.
2 changes: 1 addition & 1 deletion docs/advanced-features/security-headers.md
Expand Up @@ -81,7 +81,7 @@ This header allows you to control which features and APIs can be used in the bro
```jsx
{
key: 'Permissions-Policy',
value: 'camera=(), microphone=(), geolocation=(), interest-cohort=()'
value: 'camera=(), microphone=(), geolocation=(), browsing-topics=()'
}
```

Expand Down
16 changes: 9 additions & 7 deletions docs/api-reference/next/image.md
Expand Up @@ -279,14 +279,16 @@ The Ref must point to a DOM element or a React component that [forwards the Ref]
import Image from 'next/image'
import React from 'react'

const lazyRoot = React.useRef(null)
const Example = () => {
const lazyRoot = React.useRef(null)

const Example = () => (
<div ref={lazyRoot} style={{ overflowX: 'scroll', width: '500px' }}>
<Image lazyRoot={lazyRoot} src="/one.jpg" width="500" height="500" />
<Image lazyRoot={lazyRoot} src="/two.jpg" width="500" height="500" />
</div>
)
return (
<div ref={lazyRoot} style={{ overflowX: 'scroll', width: '500px' }}>
<Image lazyRoot={lazyRoot} src="/one.jpg" width="500" height="500" />
<Image lazyRoot={lazyRoot} src="/two.jpg" width="500" height="500" />
</div>
)
}
```

**Example pointing to a React component**
Expand Down
1 change: 1 addition & 0 deletions docs/testing.md
Expand Up @@ -281,6 +281,7 @@ const createJestConfig = nextJest({
})

// Add any custom config to be passed to Jest
/** @type {import('jest').Config} */
const customJestConfig = {
// Add more setup options before each test is run
// setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
Expand Down
2 changes: 1 addition & 1 deletion lerna.json
Expand Up @@ -16,5 +16,5 @@
"registry": "https://registry.npmjs.org/"
}
},
"version": "12.2.6-canary.6"
"version": "12.2.6-canary.7"
}
2 changes: 1 addition & 1 deletion packages/create-next-app/package.json
@@ -1,6 +1,6 @@
{
"name": "create-next-app",
"version": "12.2.6-canary.6",
"version": "12.2.6-canary.7",
"keywords": [
"react",
"next",
Expand Down
4 changes: 2 additions & 2 deletions packages/eslint-config-next/package.json
@@ -1,6 +1,6 @@
{
"name": "eslint-config-next",
"version": "12.2.6-canary.6",
"version": "12.2.6-canary.7",
"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.2.6-canary.6",
"@next/eslint-plugin-next": "12.2.6-canary.7",
"@rushstack/eslint-patch": "^1.1.3",
"@typescript-eslint/parser": "^5.21.0",
"eslint-import-resolver-node": "^0.3.6",
Expand Down
2 changes: 1 addition & 1 deletion packages/eslint-plugin-next/package.json
@@ -1,6 +1,6 @@
{
"name": "@next/eslint-plugin-next",
"version": "12.2.6-canary.6",
"version": "12.2.6-canary.7",
"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
@@ -1,6 +1,6 @@
{
"name": "@next/bundle-analyzer",
"version": "12.2.6-canary.6",
"version": "12.2.6-canary.7",
"main": "index.js",
"types": "index.d.ts",
"license": "MIT",
Expand Down
2 changes: 1 addition & 1 deletion packages/next-codemod/package.json
@@ -1,6 +1,6 @@
{
"name": "@next/codemod",
"version": "12.2.6-canary.6",
"version": "12.2.6-canary.7",
"license": "MIT",
"dependencies": {
"chalk": "4.1.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/next-env/package.json
@@ -1,6 +1,6 @@
{
"name": "@next/env",
"version": "12.2.6-canary.6",
"version": "12.2.6-canary.7",
"keywords": [
"react",
"next",
Expand Down
2 changes: 1 addition & 1 deletion packages/next-mdx/package.json
@@ -1,6 +1,6 @@
{
"name": "@next/mdx",
"version": "12.2.6-canary.6",
"version": "12.2.6-canary.7",
"main": "index.js",
"license": "MIT",
"repository": {
Expand Down
2 changes: 1 addition & 1 deletion packages/next-plugin-storybook/package.json
@@ -1,6 +1,6 @@
{
"name": "@next/plugin-storybook",
"version": "12.2.6-canary.6",
"version": "12.2.6-canary.7",
"repository": {
"url": "vercel/next.js",
"directory": "packages/next-plugin-storybook"
Expand Down
2 changes: 1 addition & 1 deletion packages/next-polyfill-module/package.json
@@ -1,6 +1,6 @@
{
"name": "@next/polyfill-module",
"version": "12.2.6-canary.6",
"version": "12.2.6-canary.7",
"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
@@ -1,6 +1,6 @@
{
"name": "@next/polyfill-nomodule",
"version": "12.2.6-canary.6",
"version": "12.2.6-canary.7",
"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
@@ -1,6 +1,6 @@
{
"name": "@next/swc",
"version": "12.2.6-canary.6",
"version": "12.2.6-canary.7",
"private": true,
"scripts": {
"build-native": "napi build --platform -p next-swc-napi --cargo-name next_swc_napi native --features plugin",
Expand Down
59 changes: 42 additions & 17 deletions packages/next/build/index.ts
Expand Up @@ -1162,16 +1162,17 @@ export default async function build(
const errorPageStaticResult = nonStaticErrorPageSpan.traceAsyncFn(
async () =>
hasCustomErrorPage &&
staticWorkers.isPageStatic(
'/_error',
staticWorkers.isPageStatic({
page: '/_error',
distDir,
isLikeServerless,
serverless: isLikeServerless,
configFileName,
runtimeEnvConfig,
config.httpAgentOptions,
config.i18n?.locales,
config.i18n?.defaultLocale
)
httpAgentOptions: config.httpAgentOptions,
locales: config.i18n?.locales,
defaultLocale: config.i18n?.defaultLocale,
pageRuntime: config.experimental.runtime,
})
)

// we don't output _app in serverless mode so use _app export
Expand Down Expand Up @@ -1274,29 +1275,53 @@ export default async function build(
// Only calculate page static information if the page is not an
// app page.
pageType !== 'app' &&
!isReservedPage(page) &&
// We currently don't support static optimization in the Edge runtime.
pageRuntime !== SERVER_RUNTIME.edge
!isReservedPage(page)
) {
try {
let edgeInfo: any

if (pageRuntime === SERVER_RUNTIME.edge) {
const manifest = require(join(
distDir,
serverDir,
MIDDLEWARE_MANIFEST
))

edgeInfo = manifest.functions[page]
}

let isPageStaticSpan =
checkPageSpan.traceChild('is-page-static')
let workerResult = await isPageStaticSpan.traceAsyncFn(
() => {
return staticWorkers.isPageStatic(
return staticWorkers.isPageStatic({
page,
distDir,
isLikeServerless,
serverless: isLikeServerless,
configFileName,
runtimeEnvConfig,
config.httpAgentOptions,
config.i18n?.locales,
config.i18n?.defaultLocale,
isPageStaticSpan.id
)
httpAgentOptions: config.httpAgentOptions,
locales: config.i18n?.locales,
defaultLocale: config.i18n?.defaultLocale,
parentId: isPageStaticSpan.id,
pageRuntime,
edgeInfo,
})
}
)

if (pageRuntime === SERVER_RUNTIME.edge) {
if (workerResult.hasStaticProps) {
console.warn(
`"getStaticProps" is not yet supported fully with "experimental-edge", detected on ${page}`
)
}
// TODO: add handling for statically rendering edge
// pages and allow edge with Prerender outputs
workerResult.isStatic = false
workerResult.hasStaticProps = false
}

if (config.outputFileTracing) {
pageTraceIncludes.set(
page,
Expand Down
89 changes: 67 additions & 22 deletions packages/next/build/utils.ts
Expand Up @@ -34,7 +34,10 @@ import { removeTrailingSlash } from '../shared/lib/router/utils/remove-trailing-
import { UnwrapPromise } from '../lib/coalesced-function'
import { normalizeLocalePath } from '../shared/lib/i18n/normalize-locale-path'
import * as Log from './output/log'
import { loadComponents } from '../server/load-components'
import {
loadComponents,
LoadComponentsReturnType,
} from '../server/load-components'
import { trace } from '../trace'
import { setHttpAgentOptions } from '../server/config'
import { recursiveDelete } from '../lib/recursive-delete'
Expand All @@ -43,6 +46,7 @@ import { MiddlewareManifest } from './webpack/plugins/middleware-plugin'
import { denormalizePagePath } from '../shared/lib/page-path/denormalize-page-path'
import { normalizePagePath } from '../shared/lib/page-path/normalize-page-path'
import { AppBuildManifest } from './webpack/plugins/app-build-manifest-plugin'
import { getRuntimeContext } from '../server/web/sandbox'

export type ROUTER_TYPE = 'pages' | 'app'

Expand Down Expand Up @@ -1008,17 +1012,31 @@ export async function buildStaticPaths(
}
}

export async function isPageStatic(
page: string,
distDir: string,
serverless: boolean,
configFileName: string,
runtimeEnvConfig: any,
httpAgentOptions: NextConfigComplete['httpAgentOptions'],
locales?: string[],
defaultLocale?: string,
export async function isPageStatic({
page,
distDir,
serverless,
configFileName,
runtimeEnvConfig,
httpAgentOptions,
locales,
defaultLocale,
parentId,
pageRuntime,
edgeInfo,
}: {
page: string
distDir: string
serverless: boolean
configFileName: string
runtimeEnvConfig: any
httpAgentOptions: NextConfigComplete['httpAgentOptions']
locales?: string[]
defaultLocale?: string
parentId?: any
): Promise<{
edgeInfo?: any
pageRuntime: ServerRuntime
}): Promise<{
isStatic?: boolean
isAmpOnly?: boolean
isHybridAmp?: boolean
Expand All @@ -1037,24 +1055,51 @@ export async function isPageStatic(
require('../shared/lib/runtime-config').setConfig(runtimeEnvConfig)
setHttpAgentOptions(httpAgentOptions)

const mod = await loadComponents(distDir, page, serverless)
const Comp = mod.Component
let componentsResult: LoadComponentsReturnType

if (pageRuntime === SERVER_RUNTIME.edge) {
const runtime = await getRuntimeContext({
paths: edgeInfo.files.map((file: string) => path.join(distDir, file)),
env: edgeInfo.env,
edgeFunctionEntry: edgeInfo,
name: edgeInfo.name,
useCache: true,
distDir,
})
const mod =
runtime.context._ENTRIES[`middleware_${edgeInfo.name}`].ComponentMod

componentsResult = {
Component: mod.default,
ComponentMod: mod,
pageConfig: mod.config || {},
// @ts-expect-error this is not needed during require
buildManifest: {},
reactLoadableManifest: {},
getServerSideProps: mod.getServerSideProps,
getStaticPaths: mod.getStaticPaths,
getStaticProps: mod.getStaticProps,
}
} else {
componentsResult = await loadComponents(distDir, page, serverless)
}
const Comp = componentsResult.Component

if (!Comp || !isValidElementType(Comp) || typeof Comp === 'string') {
throw new Error('INVALID_DEFAULT_EXPORT')
}

const hasGetInitialProps = !!(Comp as any).getInitialProps
const hasStaticProps = !!mod.getStaticProps
const hasStaticPaths = !!mod.getStaticPaths
const hasServerProps = !!mod.getServerSideProps
const hasLegacyServerProps = !!(await mod.ComponentMod
const hasStaticProps = !!componentsResult.getStaticProps
const hasStaticPaths = !!componentsResult.getStaticPaths
const hasServerProps = !!componentsResult.getServerSideProps
const hasLegacyServerProps = !!(await componentsResult.ComponentMod
.unstable_getServerProps)
const hasLegacyStaticProps = !!(await mod.ComponentMod
const hasLegacyStaticProps = !!(await componentsResult.ComponentMod
.unstable_getStaticProps)
const hasLegacyStaticPaths = !!(await mod.ComponentMod
const hasLegacyStaticPaths = !!(await componentsResult.ComponentMod
.unstable_getStaticPaths)
const hasLegacyStaticParams = !!(await mod.ComponentMod
const hasLegacyStaticParams = !!(await componentsResult.ComponentMod
.unstable_getStaticParams)

if (hasLegacyStaticParams) {
Expand Down Expand Up @@ -1121,15 +1166,15 @@ export async function isPageStatic(
encodedPaths: encodedPrerenderRoutes,
} = await buildStaticPaths(
page,
mod.getStaticPaths!,
componentsResult.getStaticPaths!,
configFileName,
locales,
defaultLocale
))
}

const isNextImageImported = (global as any).__NEXT_IMAGE_IMPORTED
const config: PageConfig = mod.pageConfig
const config: PageConfig = componentsResult.pageConfig
return {
isStatic: !hasStaticProps && !hasGetInitialProps && !hasServerProps,
isHybridAmp: config.amp === 'hybrid',
Expand Down
Expand Up @@ -112,6 +112,8 @@ export default async function edgeSSRLoader(this: any) {
config: ${stringifiedConfig},
buildId: ${JSON.stringify(buildId)},
})
export const ComponentMod = pageMod
export default function(opts) {
return adapter({
Expand Down

0 comments on commit 109febe

Please sign in to comment.