Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revert "Revert "Make concurrent features independent from the global runtime option" #35405" #35490

Merged
merged 3 commits into from Mar 25, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 0 additions & 3 deletions packages/next/build/entries.ts
Expand Up @@ -187,9 +187,6 @@ export async function getPageRuntime(
if (!pageRuntime) {
if (isRuntimeRequired) {
pageRuntime = globalRuntimeFallback
} else {
// @TODO: Remove this branch to fully implement the RFC.
pageRuntime = globalRuntimeFallback
}
}

Expand Down
35 changes: 25 additions & 10 deletions packages/next/build/index.ts
Expand Up @@ -76,7 +76,11 @@ import {
} from '../telemetry/events'
import { Telemetry } from '../telemetry/storage'
import { CompilerResult, runCompiler } from './compiler'
import { createEntrypoints, createPagesMapping } from './entries'
import {
createEntrypoints,
createPagesMapping,
getPageRuntime,
} from './entries'
import { generateBuildId } from './generate-build-id'
import { isWriteable } from './is-writeable'
import * as Log from './output/log'
Expand Down Expand Up @@ -153,11 +157,10 @@ export default async function build(
setGlobal('phase', PHASE_PRODUCTION_BUILD)
setGlobal('distDir', distDir)

// Currently, when the runtime option is set (either `nodejs` or `edge`),
// we enable concurrent features (Fizz-related rendering architecture).
const runtime = config.experimental.runtime
// We enable concurrent features (Fizz-related rendering architecture) when
// using React 18 or experimental.
const hasReactRoot = shouldUseReactRoot()
const hasConcurrentFeatures = !!runtime
const hasConcurrentFeatures = hasReactRoot

const hasServerComponents =
hasReactRoot && !!config.experimental.serverComponents
Expand Down Expand Up @@ -622,6 +625,7 @@ export default async function build(
entrypoints: entrypoints.client,
rewrites,
runWebpackSpan,
hasReactRoot,
}),
getBaseWebpackConfig(dir, {
buildId,
Expand All @@ -633,6 +637,7 @@ export default async function build(
entrypoints: entrypoints.server,
rewrites,
runWebpackSpan,
hasReactRoot,
}),
hasReactRoot
? getBaseWebpackConfig(dir, {
Expand All @@ -646,6 +651,7 @@ export default async function build(
entrypoints: entrypoints.edgeServer,
rewrites,
runWebpackSpan,
hasReactRoot,
})
: null,
])
Expand Down Expand Up @@ -954,10 +960,22 @@ export default async function build(
let ssgPageRoutes: string[] | null = null
let isMiddlewareRoute = !!page.match(MIDDLEWARE_ROUTE)

const pagePath = pagePaths.find((_path) =>
_path.startsWith(actualPage + '.')
)
const pageRuntime =
hasConcurrentFeatures && pagePath
? await getPageRuntime(
join(pagesDir, pagePath),
config.experimental.runtime
)
: null

if (
!isMiddlewareRoute &&
!isReservedPage(page) &&
!hasConcurrentFeatures
// We currently don't support staic optimization in the Edge runtime.
pageRuntime !== 'edge'
) {
try {
let isPageStaticSpan =
Expand Down Expand Up @@ -1483,10 +1501,7 @@ export default async function build(

const combinedPages = [...staticPages, ...ssgPages]

if (
!hasConcurrentFeatures &&
(combinedPages.length > 0 || useStatic404 || useDefaultStatic500)
) {
if (combinedPages.length > 0 || useStatic404 || useDefaultStatic500) {
const staticGenerationSpan = nextBuildSpan.traceChild('static-generation')
await staticGenerationSpan.traceAsyncFn(async () => {
detectConflictingPaths(
Expand Down
13 changes: 7 additions & 6 deletions packages/next/build/webpack-config.ts
Expand Up @@ -48,7 +48,6 @@ import type { Span } from '../trace'
import { getRawPageExtensions } from './utils'
import browserslist from 'next/dist/compiled/browserslist'
import loadJsConfig from './load-jsconfig'
import { shouldUseReactRoot } from '../server/config'
import { getMiddlewareSourceMapPlugins } from './webpack/plugins/middleware-source-maps-plugin'

const watchOptions = Object.freeze({
Expand Down Expand Up @@ -310,6 +309,7 @@ export default async function getBaseWebpackConfig(
rewrites,
isDevFallback = false,
runWebpackSpan,
hasReactRoot,
}: {
buildId: string
config: NextConfigComplete
Expand All @@ -323,6 +323,7 @@ export default async function getBaseWebpackConfig(
rewrites: CustomRoutes['rewrites']
isDevFallback?: boolean
runWebpackSpan: Span
hasReactRoot: boolean
}
): Promise<webpack.Configuration> {
const { useTypeScript, jsConfig, resolvedBaseUrl } = await loadJsConfig(
Expand All @@ -335,10 +336,10 @@ export default async function getBaseWebpackConfig(
rewrites.afterFiles.length > 0 ||
rewrites.fallback.length > 0
const hasReactRefresh: boolean = dev && !isServer
const hasReactRoot = shouldUseReactRoot()

const runtime = config.experimental.runtime

// Make sure reactRoot is enabled when react 18 is detected
// Make sure `reactRoot` is enabled when React 18 or experimental is detected.
if (hasReactRoot) {
config.experimental.reactRoot = true
}
Expand All @@ -353,14 +354,14 @@ export default async function getBaseWebpackConfig(
'`experimental.runtime` requires `experimental.reactRoot` to be enabled along with React 18.'
)
}
if (config.experimental.serverComponents && !runtime) {
if (config.experimental.serverComponents && !hasReactRoot) {
throw new Error(
'`experimental.runtime` is required to be set along with `experimental.serverComponents`.'
'`experimental.serverComponents` requires React 18 to be installed.'
)
}

const targetWeb = isEdgeRuntime || !isServer
const hasConcurrentFeatures = !!runtime && hasReactRoot
const hasConcurrentFeatures = hasReactRoot
const hasServerComponents =
hasConcurrentFeatures && !!config.experimental.serverComponents
const disableOptimizedLoading = hasConcurrentFeatures
Expand Down
1 change: 1 addition & 0 deletions packages/next/export/index.ts
Expand Up @@ -588,6 +588,7 @@ export default async function exportApp(
nextConfig.experimental.disableOptimizedLoading,
parentSpanId: pageExportSpan.id,
httpAgentOptions: nextConfig.httpAgentOptions,
serverComponents: nextConfig.experimental.serverComponents,
})

for (const validation of result.ampValidations || []) {
Expand Down
11 changes: 9 additions & 2 deletions packages/next/export/worker.ts
Expand Up @@ -59,6 +59,7 @@ interface ExportPageInput {
disableOptimizedLoading: any
parentSpanId: any
httpAgentOptions: NextConfigComplete['httpAgentOptions']
serverComponents?: boolean
}

interface ExportPageResults {
Expand Down Expand Up @@ -106,6 +107,7 @@ export default async function exportPage({
optimizeCss,
disableOptimizedLoading,
httpAgentOptions,
serverComponents,
}: ExportPageInput): Promise<ExportPageResults> {
setHttpAgentOptions(httpAgentOptions)
const exportPageSpan = trace('export-page-worker', parentSpanId)
Expand Down Expand Up @@ -260,7 +262,7 @@ export default async function exportPage({
getServerSideProps,
getStaticProps,
pageConfig,
} = await loadComponents(distDir, page, serverless)
} = await loadComponents(distDir, page, serverless, serverComponents)
const ampState = {
ampFirst: pageConfig?.amp === true,
hasQuery: Boolean(query.amp),
Expand Down Expand Up @@ -321,7 +323,12 @@ export default async function exportPage({
throw new Error(`Failed to render serverless page`)
}
} else {
const components = await loadComponents(distDir, page, serverless)
const components = await loadComponents(
distDir,
page,
serverless,
serverComponents
)
const ampState = {
ampFirst: components.pageConfig?.amp === true,
hasQuery: Boolean(query.amp),
Expand Down
13 changes: 9 additions & 4 deletions packages/next/server/dev/hot-reloader.ts
Expand Up @@ -154,6 +154,7 @@ export default class HotReloader {
private config: NextConfigComplete
private runtime?: 'nodejs' | 'edge'
private hasServerComponents: boolean
private hasReactRoot: boolean
public clientStats: webpack5.Stats | null
public serverStats: webpack5.Stats | null
private clientError: Error | null = null
Expand Down Expand Up @@ -197,7 +198,9 @@ export default class HotReloader {

this.config = config
this.runtime = config.experimental.runtime
this.hasServerComponents = !!config.experimental.serverComponents
this.hasReactRoot = shouldUseReactRoot()
this.hasServerComponents =
this.hasReactRoot && !!config.experimental.serverComponents
this.previewProps = previewProps
this.rewrites = rewrites
this.hotReloaderSpan = trace('hot-reloader', undefined, {
Expand Down Expand Up @@ -340,8 +343,6 @@ export default class HotReloader {
)
)

const hasReactRoot = shouldUseReactRoot()

return webpackConfigSpan
.traceChild('generate-webpack-config')
.traceAsyncFn(() =>
Expand All @@ -356,6 +357,7 @@ export default class HotReloader {
rewrites: this.rewrites,
entrypoints: entrypoints.client,
runWebpackSpan: this.hotReloaderSpan,
hasReactRoot: this.hasReactRoot,
}),
getBaseWebpackConfig(this.dir, {
dev: true,
Expand All @@ -366,9 +368,10 @@ export default class HotReloader {
rewrites: this.rewrites,
entrypoints: entrypoints.server,
runWebpackSpan: this.hotReloaderSpan,
hasReactRoot: this.hasReactRoot,
}),
// The edge runtime is only supported with React root.
hasReactRoot
this.hasReactRoot
? getBaseWebpackConfig(this.dir, {
dev: true,
isServer: true,
Expand All @@ -379,6 +382,7 @@ export default class HotReloader {
rewrites: this.rewrites,
entrypoints: entrypoints.edgeServer,
runWebpackSpan: this.hotReloaderSpan,
hasReactRoot: this.hasReactRoot,
})
: null,
].filter(Boolean) as webpack.Configuration[]
Expand Down Expand Up @@ -417,6 +421,7 @@ export default class HotReloader {
this.pagesDir
)
).client,
hasReactRoot: this.hasReactRoot,
})
const fallbackCompiler = webpack(fallbackConfig)

Expand Down
18 changes: 13 additions & 5 deletions packages/next/server/load-components.ts
Expand Up @@ -6,6 +6,7 @@ import type {
import {
BUILD_MANIFEST,
REACT_LOADABLE_MANIFEST,
MIDDLEWARE_FLIGHT_MANIFEST,
} from '../shared/lib/constants'
import { join } from 'path'
import { requirePage } from './require'
Expand All @@ -30,6 +31,7 @@ export type LoadComponentsReturnType = {
pageConfig: PageConfig
buildManifest: BuildManifest
reactLoadableManifest: ReactLoadableManifest
serverComponentManifest?: any | null
Document: DocumentType
App: AppType
getStaticProps?: GetStaticProps
Expand Down Expand Up @@ -61,7 +63,8 @@ export async function loadDefaultErrorComponents(distDir: string) {
export async function loadComponents(
distDir: string,
pathname: string,
serverless: boolean
serverless: boolean,
serverComponents?: boolean
): Promise<LoadComponentsReturnType> {
if (serverless) {
const ComponentMod = await requirePage(pathname, distDir, serverless)
Expand Down Expand Up @@ -102,10 +105,14 @@ export async function loadComponents(
requirePage(pathname, distDir, serverless),
])

const [buildManifest, reactLoadableManifest] = await Promise.all([
require(join(distDir, BUILD_MANIFEST)),
require(join(distDir, REACT_LOADABLE_MANIFEST)),
])
const [buildManifest, reactLoadableManifest, serverComponentManifest] =
await Promise.all([
require(join(distDir, BUILD_MANIFEST)),
require(join(distDir, REACT_LOADABLE_MANIFEST)),
serverComponents
? require(join(distDir, 'server', MIDDLEWARE_FLIGHT_MANIFEST + '.json'))
: null,
])

const Component = interopDefault(ComponentMod)
const Document = interopDefault(DocumentMod)
Expand All @@ -125,5 +132,6 @@ export async function loadComponents(
getServerSideProps,
getStaticProps,
getStaticPaths,
serverComponentManifest,
}
}
2 changes: 1 addition & 1 deletion packages/next/server/next-server.ts
Expand Up @@ -696,7 +696,7 @@ export default class NextNodeServer extends BaseServer {
}

protected getServerComponentManifest() {
if (!this.nextConfig.experimental.runtime) return undefined
if (!this.nextConfig.experimental.serverComponents) return undefined
return require(join(
this.distDir,
'server',
Expand Down
17 changes: 9 additions & 8 deletions packages/next/server/render.tsx
Expand Up @@ -459,13 +459,13 @@ export async function renderToHTML(
devOnlyCacheBusterQueryString,
supportsDynamicHTML,
images,
// reactRoot,
runtime,
reactRoot,
runtime: globalRuntime,
ComponentMod,
AppMod,
} = renderOpts

const hasConcurrentFeatures = !!runtime
const hasConcurrentFeatures = reactRoot

let Document = renderOpts.Document
const OriginalComponent = renderOpts.Component
Expand All @@ -474,7 +474,7 @@ export async function renderToHTML(
const isServerComponent =
!!serverComponentManifest &&
hasConcurrentFeatures &&
ComponentMod.__next_rsc__
!!ComponentMod.__next_rsc__

let Component: React.ComponentType<{}> | ((props: any) => JSX.Element) =
renderOpts.Component
Expand Down Expand Up @@ -1253,7 +1253,7 @@ export async function renderToHTML(
| typeof Document
| undefined

if (runtime === 'edge' && Document.getInitialProps) {
if (process.browser && Document.getInitialProps) {
// In the Edge runtime, `Document.getInitialProps` isn't supported.
// We throw an error here if it's customized.
if (!builtinDocument) {
Expand Down Expand Up @@ -1339,7 +1339,8 @@ export async function renderToHTML(
) : (
<Body>
<AppContainerWithIsomorphicFiberStructure>
{renderOpts.serverComponents && AppMod.__next_rsc__ ? (
{isServerComponent && AppMod.__next_rsc__ ? (
// _app.server.js is used.
<Component {...props.pageProps} router={router} />
) : (
<App {...props} Component={Component} router={router} />
Expand Down Expand Up @@ -1371,7 +1372,6 @@ export async function renderToHTML(
),
generateStaticHTML: true,
})

const flushed = await streamToString(flushEffectStream)
return flushed
}
Expand Down Expand Up @@ -1499,7 +1499,8 @@ export async function renderToHTML(
optimizeCss: renderOpts.optimizeCss,
optimizeFonts: renderOpts.optimizeFonts,
nextScriptWorkers: renderOpts.nextScriptWorkers,
runtime,
runtime: globalRuntime,
hasConcurrentFeatures,
}

const document = (
Expand Down
1 change: 1 addition & 0 deletions packages/next/shared/lib/html-context.ts
Expand Up @@ -38,6 +38,7 @@ export type HtmlProps = {
optimizeFonts?: boolean
nextScriptWorkers?: boolean
runtime?: 'edge' | 'nodejs'
hasConcurrentFeatures?: boolean
}

export const HtmlContext = createContext<HtmlProps>(null as any)
Expand Down