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

Tweak routing tests #36667

Merged
merged 14 commits into from May 5, 2022
58 changes: 19 additions & 39 deletions packages/next/build/entries.ts
Expand Up @@ -14,8 +14,7 @@ import {
API_ROUTE,
DOT_NEXT_ALIAS,
PAGES_DIR_ALIAS,
ROOT_ALIAS,
ROOT_DIR_ALIAS,
VIEWS_DIR_ALIAS,
} from '../lib/constants'
import {
CLIENT_STATIC_FILES_RUNTIME_AMP,
Expand All @@ -40,11 +39,7 @@ type ObjectValue<T> = T extends { [key: string]: infer V } ? V : never
* special case because it is the only page where we want to preserve the RSC
* server extension.
*/
export function getPageFromPath(
pagePath: string,
pageExtensions: string[],
isRoot?: boolean
) {
export function getPageFromPath(pagePath: string, pageExtensions: string[]) {
const extensions = pagePath.includes('/_app.server.')
? withoutRSCExtensions(pageExtensions)
: pageExtensions
Expand All @@ -53,36 +48,34 @@ export function getPageFromPath(
pagePath.replace(new RegExp(`\\.+(${extensions.join('|')})$`), '')
)

if (!isRoot) {
page = page.replace(/\/index$/, '')
}
page = page.replace(/\/index$/, '')

return page === '' ? '/' : page
}

export function createPagesMapping({
hasServerComponents,
isDev,
isRoot,
isViews,
pageExtensions,
pagePaths,
}: {
hasServerComponents: boolean
isDev: boolean
isRoot?: boolean
isViews?: boolean
pageExtensions: string[]
pagePaths: string[]
}): { [page: string]: string } {
const previousPages: { [key: string]: string } = {}
const pathAlias = isRoot ? ROOT_DIR_ALIAS : PAGES_DIR_ALIAS
const pathAlias = isViews ? VIEWS_DIR_ALIAS : PAGES_DIR_ALIAS
const pages = pagePaths.reduce<{ [key: string]: string }>(
(result, pagePath) => {
// Do not process .d.ts files inside the `pages` folder
if (pagePath.endsWith('.d.ts') && pageExtensions.includes('ts')) {
return result
}

const pageKey = getPageFromPath(pagePath, pageExtensions, isRoot)
const pageKey = getPageFromPath(pagePath, pageExtensions)

// Assume that if there's a Client Component, that there is
// a matching Server Component that will map to the page.
Expand All @@ -103,11 +96,7 @@ export function createPagesMapping({
previousPages[pageKey] = pagePath
}

if (pageKey === 'root') {
result['root'] = normalizePathSep(join(ROOT_ALIAS, pagePath))
} else {
result[pageKey] = normalizePathSep(join(pathAlias, pagePath))
}
result[pageKey] = normalizePathSep(join(pathAlias, pagePath))
return result
},
{}
Expand All @@ -117,12 +106,7 @@ export function createPagesMapping({
// the correct source file so that HMR can work properly when a file is
// added or removed.

if (isRoot) {
if (isDev) {
pages['root'] = `${ROOT_ALIAS}/root`
} else {
pages['root'] = pages['root'] || 'next/dist/pages/root'
}
if (isViews) {
return pages
}

Expand Down Expand Up @@ -259,8 +243,8 @@ interface CreateEntrypointsParams {
pagesDir: string
previewMode: __ApiPreviewProps
target: 'server' | 'serverless' | 'experimental-serverless-trace'
rootDir?: string
rootPaths?: Record<string, string>
viewsDir?: string
viewPaths?: Record<string, string>
}

export function getEdgeServerEntry(opts: {
Expand Down Expand Up @@ -365,18 +349,18 @@ export function getClientEntry(opts: {
}

export async function createEntrypoints(params: CreateEntrypointsParams) {
const { config, pages, pagesDir, isDev, target, rootDir, rootPaths } = params
const { config, pages, pagesDir, isDev, target, viewsDir, viewPaths } = params
const edgeServer: webpack5.EntryObject = {}
const server: webpack5.EntryObject = {}
const client: webpack5.EntryObject = {}

const getEntryHandler =
(mappings: Record<string, string>, isRoot: boolean) =>
(mappings: Record<string, string>, isViews: boolean) =>
async (page: string) => {
const bundleFile = normalizePagePath(page)
const clientBundlePath = posix.join('pages', bundleFile)
const serverBundlePath = posix.join(
isRoot ? (bundleFile === '/root' ? './' : 'root') : 'pages',
isViews ? 'views' : 'pages',
bundleFile
)

Expand All @@ -387,12 +371,8 @@ export async function createEntrypoints(params: CreateEntrypointsParams) {
return absolutePagePath.replace(PAGES_DIR_ALIAS, pagesDir)
}

if (absolutePagePath.startsWith(ROOT_DIR_ALIAS) && rootDir) {
return absolutePagePath.replace(ROOT_DIR_ALIAS, rootDir)
}

if (absolutePagePath.startsWith(ROOT_ALIAS) && rootDir) {
return absolutePagePath.replace(ROOT_ALIAS, join(rootDir, '..'))
if (absolutePagePath.startsWith(VIEWS_DIR_ALIAS) && viewsDir) {
return absolutePagePath.replace(VIEWS_DIR_ALIAS, viewsDir)
}

return require.resolve(absolutePagePath)
Expand Down Expand Up @@ -432,9 +412,9 @@ export async function createEntrypoints(params: CreateEntrypointsParams) {
})
}

if (rootDir && rootPaths) {
const entryHandler = getEntryHandler(rootPaths, true)
await Promise.all(Object.keys(rootPaths).map(entryHandler))
if (viewsDir && viewPaths) {
const entryHandler = getEntryHandler(viewPaths, true)
await Promise.all(Object.keys(viewPaths).map(entryHandler))
}
await Promise.all(Object.keys(pages).map(getEntryHandler(pages, false)))

Expand Down
42 changes: 17 additions & 25 deletions packages/next/build/index.ts
Expand Up @@ -114,7 +114,6 @@ import { MiddlewareManifest } from './webpack/plugins/middleware-plugin'
import { recursiveCopy } from '../lib/recursive-copy'
import { recursiveReadDir } from '../lib/recursive-readdir'
import { lockfilePatchPromise, teardownTraceSubscriber } from './swc'
import { findPageFile } from '../server/lib/find-page-file'

export type SsgRoute = {
initialRevalidateSeconds: number | false
Expand Down Expand Up @@ -207,9 +206,9 @@ export default async function build(
setGlobal('telemetry', telemetry)

const publicDir = path.join(dir, 'public')
const { pages: pagesDir, root: rootDir } = findPagesDir(
const { pages: pagesDir, views: viewsDir } = findPagesDir(
dir,
config.experimental.rootDir
config.experimental.viewsDir
)

const hasPublicDir = await fileExists(publicDir)
Expand Down Expand Up @@ -245,7 +244,7 @@ export default async function build(
.traceAsyncFn(() =>
verifyTypeScriptSetup(
dir,
[pagesDir, rootDir].filter(Boolean) as string[],
[pagesDir, viewsDir].filter(Boolean) as string[],
!ignoreTypeScriptErrors,
config,
cacheDir
Expand Down Expand Up @@ -311,24 +310,17 @@ export default async function build(
)
)

let rootPaths: string[] | undefined
let viewPaths: string[] | undefined

if (rootDir) {
rootPaths = await nextBuildSpan
.traceChild('collect-root-paths')
if (viewsDir) {
viewPaths = await nextBuildSpan
.traceChild('collect-view-paths')
.traceAsyncFn(() =>
recursiveReadDir(
rootDir,
viewsDir,
new RegExp(`\\.(?:${config.pageExtensions.join('|')})$`)
)
)

const rootFile = await findPageFile(
path.join(rootDir, '..'),
'root',
config.pageExtensions
)
if (rootFile) rootPaths.push(rootFile)
}
// needed for static exporting since we want to replace with HTML
// files
Expand All @@ -353,17 +345,17 @@ export default async function build(
})
)

let mappedRootPaths: ReturnType<typeof createPagesMapping> | undefined
let mappedViewPaths: ReturnType<typeof createPagesMapping> | undefined

if (rootPaths && rootDir) {
mappedRootPaths = nextBuildSpan
.traceChild('create-root-mapping')
if (viewPaths && viewsDir) {
mappedViewPaths = nextBuildSpan
.traceChild('create-views-mapping')
.traceFn(() =>
createPagesMapping({
pagePaths: rootPaths!,
pagePaths: viewPaths!,
hasServerComponents,
isDev: false,
isRoot: true,
isViews: true,
pageExtensions: config.pageExtensions,
})
)
Expand All @@ -381,8 +373,8 @@ export default async function build(
pagesDir,
previewMode: previewProps,
target,
rootDir,
rootPaths: mappedRootPaths,
viewsDir,
viewPaths: mappedViewPaths,
})
)

Expand Down Expand Up @@ -688,7 +680,7 @@ export default async function build(
rewrites,
runWebpackSpan,
target,
rootDir,
viewsDir,
}

const configs = await runWebpackSpan
Expand Down
29 changes: 9 additions & 20 deletions packages/next/build/webpack-config.ts
Expand Up @@ -10,8 +10,7 @@ import {
NEXT_PROJECT_ROOT,
NEXT_PROJECT_ROOT_DIST_CLIENT,
PAGES_DIR_ALIAS,
ROOT_ALIAS,
ROOT_DIR_ALIAS,
VIEWS_DIR_ALIAS,
} from '../lib/constants'
import { fileExists } from '../lib/file-exists'
import { CustomRoutes } from '../lib/load-custom-routes.js'
Expand Down Expand Up @@ -315,7 +314,7 @@ export default async function getBaseWebpackConfig(
rewrites,
runWebpackSpan,
target = 'server',
rootDir,
viewsDir,
}: {
buildId: string
config: NextConfigComplete
Expand All @@ -329,7 +328,7 @@ export default async function getBaseWebpackConfig(
rewrites: CustomRoutes['rewrites']
runWebpackSpan: Span
target?: string
rootDir?: string
viewsDir?: string
}
): Promise<webpack.Configuration> {
const isClient = compilerType === 'client'
Expand Down Expand Up @@ -542,7 +541,7 @@ export default async function getBaseWebpackConfig(
)
)
.replace(/\\/g, '/'),
...(config.experimental.rootDir
...(config.experimental.viewsDir
? {
[CLIENT_STATIC_FILES_RUNTIME_MAIN_ROOT]:
`./` +
Expand Down Expand Up @@ -607,16 +606,6 @@ export default async function getBaseWebpackConfig(
}, [] as string[]),
`next/dist/pages/_document.js`,
]

if (config.experimental.rootDir && rootDir) {
customRootAliases[`${ROOT_ALIAS}/root`] = [
...config.pageExtensions.reduce((prev, ext) => {
prev.push(path.join(rootDir, `root.${ext}`))
return prev
}, [] as string[]),
'next/dist/pages/root.js',
]
}
}

const resolveConfig = {
Expand Down Expand Up @@ -651,10 +640,9 @@ export default async function getBaseWebpackConfig(
...customRootAliases,

[PAGES_DIR_ALIAS]: pagesDir,
...(rootDir
...(viewsDir
? {
[ROOT_DIR_ALIAS]: rootDir,
[ROOT_ALIAS]: path.join(rootDir, '..'),
[VIEWS_DIR_ALIAS]: viewsDir,
}
: {}),
[DOT_NEXT_ALIAS]: distDir,
Expand Down Expand Up @@ -1190,6 +1178,7 @@ export default async function getBaseWebpackConfig(
'next-middleware-loader',
'next-middleware-ssr-loader',
'next-middleware-wasm-loader',
'next-view-loader',
].reduce((alias, loader) => {
// using multiple aliases to replace `resolveLoader.modules`
alias[loader] = path.join(__dirname, 'webpack', 'loaders', loader)
Expand Down Expand Up @@ -1560,7 +1549,7 @@ export default async function getBaseWebpackConfig(
serverless: isLikeServerless,
dev,
isEdgeRuntime: isEdgeServer,
rootEnabled: !!config.experimental.rootDir,
rootEnabled: !!config.experimental.viewsDir,
}),
// MiddlewarePlugin should be after DefinePlugin so NEXT_PUBLIC_*
// replacement is done before its process.env.* handling
Expand All @@ -1571,7 +1560,7 @@ export default async function getBaseWebpackConfig(
rewrites,
isDevFallback,
exportRuntime: hasConcurrentFeatures,
rootEnabled: !!config.experimental.rootDir,
rootEnabled: !!config.experimental.viewsDir,
}),
new ProfilingPlugin({ runWebpackSpan }),
config.optimizeFonts &&
Expand Down
17 changes: 17 additions & 0 deletions packages/next/build/webpack/loaders/next-view-loader.ts
@@ -0,0 +1,17 @@
import type webpack from 'webpack5'

const nextViewLoader: webpack.LoaderDefinitionFunction<{
components: string[]
}> = function nextViewLoader() {
const loaderOptions = this.getOptions() || {}

return `
export const components = {
${loaderOptions.components
.map((component) => `'${component}': () => import('${component}')`)
.join(',\n')}
}
`
}

export default nextViewLoader
@@ -1,7 +1,7 @@
import { webpack, sources } from 'next/dist/compiled/webpack/webpack'
import {
PAGES_MANIFEST,
ROOT_PATHS_MANIFEST,
VIEW_PATHS_MANIFEST,
} from '../../../shared/lib/constants'
import getRouteFromEntrypoint from '../../../server/get-route-from-entrypoint'
import { normalizePathSep } from '../../../shared/lib/page-path/normalize-path-sep'
Expand Down Expand Up @@ -74,7 +74,7 @@ export default class PagesManifestPlugin implements webpack.Plugin {
}
file = normalizePathSep(file)

if (entrypoint.name.startsWith('root/')) {
if (entrypoint.name.startsWith('views/')) {
rootPaths[pagePath] = file
} else {
pages[pagePath] = file
Expand Down Expand Up @@ -106,7 +106,7 @@ export default class PagesManifestPlugin implements webpack.Plugin {

if (this.rootEnabled) {
assets[
`${!this.dev && !this.isEdgeRuntime ? '../' : ''}` + ROOT_PATHS_MANIFEST
`${!this.dev && !this.isEdgeRuntime ? '../' : ''}` + VIEW_PATHS_MANIFEST
] = new sources.RawSource(
JSON.stringify(
{
Expand Down