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

refactor: share utils and optimize segments normalization #54611

Merged
merged 10 commits into from
Aug 29, 2023
Merged
5 changes: 1 addition & 4 deletions packages/next/src/build/webpack/loaders/next-app-loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { MiddlewareConfig } from '../../analysis/get-page-static-info'
import { getFilenameAndExtension } from './next-metadata-route-loader'
import { isAppBuiltinNotFoundPage } from '../../utils'
import { loadEntrypoint } from '../../load-entrypoint'
import { isGroupSegment } from '../../../shared/lib/segment'

export type AppLoaderOptions = {
name: string
Expand Down Expand Up @@ -76,10 +77,6 @@ export type ComponentsType = {
readonly defaultPage?: ModuleReference
}

function isGroupSegment(segment: string) {
return segment.startsWith('(') && segment.endsWith(')')
}

async function createAppRouteCode({
name,
page,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { FlightRouterState, Segment } from '../../../server/app-render/types'
import { INTERCEPTION_ROUTE_MARKERS } from '../../../server/future/helpers/interception-routes'
import { isGroupSegment } from '../../../shared/lib/segment'
import { matchSegment } from '../match-segments'

const removeLeadingSlash = (segment: string): string => {
return segment[0] === '/' ? segment.slice(1) : segment
}

const segmentToPathname = (segment: Segment): string => {
if (typeof segment === 'string') {
return segment
Expand All @@ -10,13 +15,11 @@ const segmentToPathname = (segment: Segment): string => {
return segment[1]
}

function normalizePathname(pathname: string): string {
function normalizeSegments(segments: string[]): string {
return (
pathname.split('/').reduce((acc, segment) => {
if (
segment === '' ||
(segment.startsWith('(') && segment.endsWith(')'))
) {
segments.reduce((acc, segment) => {
segment = removeLeadingSlash(segment)
if (segment === '' || isGroupSegment(segment)) {
return acc
}

Expand All @@ -40,30 +43,28 @@ export function extractPathFromFlightRouterState(

if (segment.startsWith('__PAGE__')) return ''

const path = [segment]

const segments = [segment]
const parallelRoutes = flightRouterState[1] ?? {}

const childrenPath = parallelRoutes.children
? extractPathFromFlightRouterState(parallelRoutes.children)
: undefined

if (childrenPath !== undefined) {
path.push(childrenPath)
segments.push(childrenPath)
} else {
for (const [key, value] of Object.entries(parallelRoutes)) {
if (key === 'children') continue

const childPath = extractPathFromFlightRouterState(value)

if (childPath !== undefined) {
path.push(childPath)
segments.push(childPath)
}
}
}

// TODO-APP: optimise this, it's not ideal to join and split
return normalizePathname(path.join('/'))
return normalizeSegments(segments)
}

function computeChangedPathImpl(
Expand Down Expand Up @@ -116,5 +117,5 @@ export function computeChangedPath(
}

// lightweight normalization to remove route groups
return normalizePathname(changedPath)
return normalizeSegments(changedPath.split('/'))
}
3 changes: 2 additions & 1 deletion packages/next/src/shared/lib/router/utils/app-paths.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { ensureLeadingSlash } from '../../page-path/ensure-leading-slash'
import { isGroupSegment } from '../../segment'

/**
* Normalizes an app route so it represents the actual request path. Essentially
Expand Down Expand Up @@ -28,7 +29,7 @@ export function normalizeAppPath(route: string) {
}

// Groups are ignored.
if (segment[0] === '(' && segment.endsWith(')')) {
if (isGroupSegment(segment)) {
return pathname
}

Expand Down
4 changes: 4 additions & 0 deletions packages/next/src/shared/lib/segment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export function isGroupSegment(segment: string) {
// Use array[0] for performant purpose
return segment[0] === '(' && segment.endsWith(')')
}