Skip to content

Commit

Permalink
Ensure module require is awaited in app-render (#38860)
Browse files Browse the repository at this point in the history
Fixes a bug where `import { nanoid } from 'nanoid'` broke the tests. 



## Bug

- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Errors have helpful link attached, see `contributing.md`

## Feature

- [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR.
- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have helpful link attached, see `contributing.md`

## Documentation / Examples

- [ ] Make sure the linting passes by running `pnpm lint`
- [ ] The examples guidelines are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing.md#adding-examples)
  • Loading branch information
timneutkens committed Jul 21, 2022
1 parent adf40a6 commit 5752d4a
Showing 1 changed file with 70 additions and 56 deletions.
126 changes: 70 additions & 56 deletions packages/next/server/app-render.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -538,7 +538,7 @@ export async function renderToHTML(
return segmentTree
}

const createComponentTree = ({
const createComponentTree = async ({
createSegmentPath,
tree: [segment, parallelRoutes, { layout, loading, page }],
parentParams,
Expand All @@ -550,11 +550,15 @@ export async function renderToHTML(
parentParams: { [key: string]: any }
rootLayoutIncluded?: boolean
firstItem?: boolean
}): { Component: React.ComponentType } => {
const Loading = loading ? interopDefault(loading()) : undefined
}): Promise<{ Component: React.ComponentType }> => {
const Loading = loading ? await interopDefault(loading()) : undefined
const isLayout = typeof layout !== 'undefined'
const isPage = typeof page !== 'undefined'
const layoutOrPageMod = isLayout ? layout() : isPage ? page() : undefined
const layoutOrPageMod = isLayout
? await layout()
: isPage
? await page()
: undefined
const rootLayoutAtThisLevel = isLayout && !rootLayoutIncluded
const rootLayoutIncludedAtThisLevelOrAbove =
rootLayoutIncluded || rootLayoutAtThisLevel
Expand Down Expand Up @@ -594,45 +598,53 @@ export async function renderToHTML(
: segment

// This happens outside of rendering in order to eagerly kick off data fetching for layouts / the page further down
const parallelRouteComponents = Object.keys(parallelRoutes).reduce(
(list, currentValue) => {
const currentSegmentPath = firstItem
? [currentValue]
: [actualSegment, currentValue]

const { Component: ChildComponent } = createComponentTree({
createSegmentPath: (child) => {
return createSegmentPath([...currentSegmentPath, ...child])
},
tree: parallelRoutes[currentValue],
parentParams: currentParams,
rootLayoutIncluded: rootLayoutIncludedAtThisLevelOrAbove,
})

const childSegmentParam = getDynamicParamFromSegment(
parallelRoutes[currentValue][0]
)
const childProp: ChildProp = {
current: <ChildComponent />,
segment: childSegmentParam
? [
childSegmentParam.param,
childSegmentParam.treeValue,
childSegmentParam.type,
]
: parallelRoutes[currentValue][0],
}
const parallelRouteMap = await Promise.all(
Object.keys(parallelRoutes).map(
async (parallelRouteKey): Promise<[string, React.ReactNode]> => {
const currentSegmentPath = firstItem
? [parallelRouteKey]
: [actualSegment, parallelRouteKey]

const { Component: ChildComponent } = await createComponentTree({
createSegmentPath: (child) => {
return createSegmentPath([...currentSegmentPath, ...child])
},
tree: parallelRoutes[parallelRouteKey],
parentParams: currentParams,
rootLayoutIncluded: rootLayoutIncludedAtThisLevelOrAbove,
})

const childSegmentParam = getDynamicParamFromSegment(
parallelRoutes[parallelRouteKey][0]
)
const childProp: ChildProp = {
current: <ChildComponent />,
segment: childSegmentParam
? [
childSegmentParam.param,
childSegmentParam.treeValue,
childSegmentParam.type,
]
: parallelRoutes[parallelRouteKey][0],
}

list[currentValue] = (
<LayoutRouter
parallelRouterKey={currentValue}
segmentPath={createSegmentPath(currentSegmentPath)}
loading={Loading ? <Loading /> : undefined}
childProp={childProp}
rootLayoutIncluded={rootLayoutIncludedAtThisLevelOrAbove}
/>
)
return [
parallelRouteKey,
<LayoutRouter
parallelRouterKey={parallelRouteKey}
segmentPath={createSegmentPath(currentSegmentPath)}
loading={Loading ? <Loading /> : undefined}
childProp={childProp}
rootLayoutIncluded={rootLayoutIncludedAtThisLevelOrAbove}
/>,
]
}
)
)

const parallelRouteComponents = parallelRouteMap.reduce(
(list, [parallelRouteKey, Comp]) => {
list[parallelRouteKey] = Comp
return list
},
{} as { [key: string]: React.ReactNode }
Expand Down Expand Up @@ -759,12 +771,12 @@ export async function renderToHTML(

if (isFlight) {
// TODO-APP: throw on invalid flightRouterState
const walkTreeWithFlightRouterState = (
const walkTreeWithFlightRouterState = async (
treeToFilter: LoaderTree,
parentParams: { [key: string]: string | string[] },
flightRouterState?: FlightRouterState,
parentRendered?: boolean
): FlightDataPath => {
): Promise<FlightDataPath> => {
const [segment, parallelRoutes] = treeToFilter
const parallelRoutesKeys = Object.keys(parallelRoutes)

Expand Down Expand Up @@ -794,22 +806,24 @@ export async function renderToHTML(
actualSegment,
createFlightRouterStateFromLoaderTree(treeToFilter),
React.createElement(
createComponentTree(
// This ensures flightRouterPath is valid and filters down the tree
{
createSegmentPath: (child) => child,
tree: treeToFilter,
parentParams: currentParams,
firstItem: true,
}
(
await createComponentTree(
// This ensures flightRouterPath is valid and filters down the tree
{
createSegmentPath: (child) => child,
tree: treeToFilter,
parentParams: currentParams,
firstItem: true,
}
)
).Component
),
]
}

for (const parallelRouteKey of parallelRoutesKeys) {
const parallelRoute = parallelRoutes[parallelRouteKey]
const path = walkTreeWithFlightRouterState(
const path = await walkTreeWithFlightRouterState(
parallelRoute,
currentParams,
flightRouterState && flightRouterState[1][parallelRouteKey],
Expand All @@ -831,9 +845,9 @@ export async function renderToHTML(
)
const flightData: FlightData = [
// TODO-APP: change walk to output without ''
walkTreeWithFlightRouterState(tree, {}, providedFlightRouterState).slice(
1
),
(
await walkTreeWithFlightRouterState(tree, {}, providedFlightRouterState)
).slice(1),
]

return new RenderResult(
Expand All @@ -858,7 +872,7 @@ export async function renderToHTML(
dev
)

const { Component: ComponentTree } = createComponentTree({
const { Component: ComponentTree } = await createComponentTree({
createSegmentPath: (child) => child,
tree,
parentParams: {},
Expand Down

0 comments on commit 5752d4a

Please sign in to comment.