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

Add separate entry per layout/page. #39611

Merged
merged 14 commits into from Aug 16, 2022
123 changes: 57 additions & 66 deletions packages/next/build/webpack/plugins/flight-client-entry-plugin.ts
Expand Up @@ -3,8 +3,6 @@ import path from 'path'
import { webpack, sources } from 'next/dist/compiled/webpack/webpack'
import type { webpack5 } from 'next/dist/compiled/webpack/webpack'
import { clientComponentRegex } from '../loaders/utils'
import { normalizePagePath } from '../../../shared/lib/page-path/normalize-page-path'
import { denormalizePagePath } from '../../../shared/lib/page-path/denormalize-page-path'
import {
getInvalidator,
entries,
Expand Down Expand Up @@ -91,53 +89,46 @@ export class FlightClientEntryPlugin {
}

// TODO-APP: create client-side entrypoint per layout/page.
// const entryModule: webpack5.NormalModule =
// compilation.moduleGraph.getResolvedModule(entryDependency)

// for (const connection of compilation.moduleGraph.getOutgoingConnections(
// entryModule
// )) {
// const layoutOrPageDependency = connection.dependency
// // const layoutOrPageRequest = connection.dependency.request

// const [clientComponentImports, cssImports] =
// this.collectClientComponentsAndCSSForDependency(
// compiler.context,
// compilation,
// layoutOrPageDependency
// )

// Object.assign(serverCSSManifest, cssImports)

// promises.push(
// this.injectClientEntryAndSSRModules(
// compiler,
// compilation,
// name,
// entryDependency,
// clientComponentImports
// )
// )
// }
const entryModule: webpack5.NormalModule =
compilation.moduleGraph.getResolvedModule(entryDependency)

const [clientComponentImports, cssImports] =
this.collectClientComponentsAndCSSForDependency(
compiler.context,
compilation,
entryDependency
)
for (const connection of compilation.moduleGraph.getOutgoingConnections(
entryModule
)) {
const layoutOrPageDependency = connection.dependency
const layoutOrPageRequest = connection.dependency.request

Object.assign(flightCSSManifest, cssImports)
const isAbsoluteRequest = layoutOrPageRequest[0] === '/'

promises.push(
this.injectClientEntryAndSSRModules(
compiler,
compilation,
name,
entryDependency,
clientComponentImports
const relativeRequest = isAbsoluteRequest
? path.relative(compilation.options.context, layoutOrPageRequest)
: layoutOrPageRequest

// Replace file suffix as `.js` will be added.
const bundlePath = relativeRequest.replace(
/(\.server|\.client)?\.(js|ts)x?$/,
''
)
)

const [clientComponentImports, cssImports] =
this.collectClientComponentsAndCSSForDependency({
context: compiler.context,
compilation,
dependency: layoutOrPageDependency,
})

Object.assign(flightCSSManifest, cssImports)

promises.push(
this.injectClientEntryAndSSRModules({
compiler,
compilation,
entryName: name,
clientComponentImports,
bundlePath,
})
)
}
}

compilation.hooks.processAssets.tap(
Expand Down Expand Up @@ -165,11 +156,15 @@ export class FlightClientEntryPlugin {
}
}

collectClientComponentsAndCSSForDependency(
context: string,
compilation: any,
collectClientComponentsAndCSSForDependency({
context,
compilation,
dependency,
}: {
context: string
compilation: any
dependency: any /* Dependency */
): [ClientComponentImports, CssImports] {
}): [ClientComponentImports, CssImports] {
/**
* Keep track of checked modules to avoid infinite loops with recursive imports.
*/
Expand Down Expand Up @@ -252,22 +247,21 @@ export class FlightClientEntryPlugin {
return [clientComponentImports, serverCSSImports]
}

async injectClientEntryAndSSRModules(
compiler: any,
compilation: any,
entryName: string,
entryDependency: any,
async injectClientEntryAndSSRModules({
compiler,
compilation,
entryName,
clientComponentImports,
bundlePath,
}: {
compiler: any
compilation: any
entryName: string
clientComponentImports: ClientComponentImports
): Promise<boolean> {
bundlePath: string
}): Promise<boolean> {
let shouldInvalidate = false

const entryModule =
compilation.moduleGraph.getResolvedModule(entryDependency)
const routeInfo = entryModule.buildInfo.route || {
page: denormalizePagePath(entryName.replace(/^pages/, '')),
absolutePagePath: entryModule.resource,
}

const loaderOptions: NextFlightClientEntryLoaderOptions = {
modules: clientComponentImports,
server: false,
Expand All @@ -280,18 +274,15 @@ export class FlightClientEntryPlugin {
server: true,
})}!`

const bundlePath = 'app' + normalizePagePath(routeInfo.page)

// Add for the client compilation
// Inject the entry to the client compiler.
if (this.dev) {
const pageKey = COMPILER_NAMES.client + routeInfo.page
const pageKey = COMPILER_NAMES.client + bundlePath
if (!entries[pageKey]) {
entries[pageKey] = {
type: EntryTypes.CHILD_ENTRY,
parentEntries: new Set([entryName]),
bundlePath,
// absolutePagePath: routeInfo.absolutePagePath,
request: clientLoader,
dispose: false,
lastActiveTime: Date.now(),
Expand Down