From 79884cdd731df89383883052522df7503fdbe42d Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Mon, 2 May 2022 14:20:50 +0200 Subject: [PATCH 1/3] Update findPagesDir Co-Authored-By: JJ Kasper <22380829+ijjk@users.noreply.github.com> --- packages/next/build/index.ts | 8 +++-- packages/next/lib/eslint/runLintCheck.ts | 3 +- packages/next/lib/find-pages-dir.ts | 35 +++++++++++++------ .../lib/typescript/getTypeScriptIntent.ts | 18 +++++----- packages/next/lib/verifyTypeScriptSetup.ts | 4 +-- packages/next/server/dev/next-dev-server.ts | 17 +++++++-- 6 files changed, 60 insertions(+), 25 deletions(-) diff --git a/packages/next/build/index.ts b/packages/next/build/index.ts index e096a315d190628..41af1eb15a0918d 100644 --- a/packages/next/build/index.ts +++ b/packages/next/build/index.ts @@ -196,7 +196,11 @@ export default async function build( setGlobal('telemetry', telemetry) const publicDir = path.join(dir, 'public') - const pagesDir = findPagesDir(dir) + const { pages: pagesDir, root: rootDir } = findPagesDir( + dir, + config.experimental.rootDir + ) + const hasPublicDir = await fileExists(publicDir) telemetry.record( @@ -230,7 +234,7 @@ export default async function build( .traceAsyncFn(() => verifyTypeScriptSetup( dir, - pagesDir, + [pagesDir, rootDir].filter(Boolean) as string[], !ignoreTypeScriptErrors, config, cacheDir diff --git a/packages/next/lib/eslint/runLintCheck.ts b/packages/next/lib/eslint/runLintCheck.ts index a7229a6f5911259..e994f8528680c22 100644 --- a/packages/next/lib/eslint/runLintCheck.ts +++ b/packages/next/lib/eslint/runLintCheck.ts @@ -171,7 +171,8 @@ async function lint( } } - const pagesDir = findPagesDir(baseDir) + // TODO: should we apply these rules to "root" dir as well? + const pagesDir = findPagesDir(baseDir).pages if (nextEslintPluginIsEnabled) { let updatedPagesDir = false diff --git a/packages/next/lib/find-pages-dir.ts b/packages/next/lib/find-pages-dir.ts index a4acde163903835..8528880012884a3 100644 --- a/packages/next/lib/find-pages-dir.ts +++ b/packages/next/lib/find-pages-dir.ts @@ -10,22 +10,37 @@ export const existsSync = (f: string): boolean => { } } -export function findPagesDir(dir: string): string { - // prioritize ./pages over ./src/pages - let curDir = path.join(dir, 'pages') +function findDir(dir: string, name: string): string | null { + // prioritize ./${name} over ./src/${name} + let curDir = path.join(dir, name) if (existsSync(curDir)) return curDir - curDir = path.join(dir, 'src/pages') + curDir = path.join(dir, 'src', name) if (existsSync(curDir)) return curDir - // Check one level up the tree to see if the pages directory might be there - if (existsSync(path.join(dir, '..', 'pages'))) { + return null +} + +export function findPagesDir( + dir: string, + root?: boolean +): { pages: string; root?: string } { + const pagesDir = findDir(dir, 'pages') + let rootDir: undefined | string + + if (root) { + rootDir = findDir(dir, 'root') || undefined + } + + // TODO: allow "root" dir without pages dir + if (pagesDir === null) { throw new Error( - '> No `pages` directory found. Did you mean to run `next` in the parent (`../`) directory?' + "> Couldn't find a `pages` directory. Please create one under the project root" ) } - throw new Error( - "> Couldn't find a `pages` directory. Please create one under the project root" - ) + return { + pages: pagesDir, + root: rootDir, + } } diff --git a/packages/next/lib/typescript/getTypeScriptIntent.ts b/packages/next/lib/typescript/getTypeScriptIntent.ts index dee44e1b1f1e74a..a8aa7ab69fb80a7 100644 --- a/packages/next/lib/typescript/getTypeScriptIntent.ts +++ b/packages/next/lib/typescript/getTypeScriptIntent.ts @@ -8,7 +8,7 @@ export type TypeScriptIntent = { firstTimeSetup: boolean } export async function getTypeScriptIntent( baseDir: string, - pagesDir: string, + intentDirs: string[], config: NextConfigComplete ): Promise { const tsConfigPath = path.join(baseDir, config.typescript.tsconfigPath) @@ -28,13 +28,15 @@ export async function getTypeScriptIntent( // project for the user when we detect TypeScript files. So, we need to check // the `pages/` directory for a TypeScript file. // Checking all directories is too slow, so this is a happy medium. - const typescriptFiles = await recursiveReadDir( - pagesDir, - /.*\.(ts|tsx)$/, - /(node_modules|.*\.d\.ts)/ - ) - if (typescriptFiles.length) { - return { firstTimeSetup: true } + for (const dir of intentDirs) { + const typescriptFiles = await recursiveReadDir( + dir, + /.*\.(ts|tsx)$/, + /(node_modules|.*\.d\.ts)/ + ) + if (typescriptFiles.length) { + return { firstTimeSetup: true } + } } return false diff --git a/packages/next/lib/verifyTypeScriptSetup.ts b/packages/next/lib/verifyTypeScriptSetup.ts index 01939302caae771..e4e47742c422878 100644 --- a/packages/next/lib/verifyTypeScriptSetup.ts +++ b/packages/next/lib/verifyTypeScriptSetup.ts @@ -32,7 +32,7 @@ const requiredPackages = [ export async function verifyTypeScriptSetup( dir: string, - pagesDir: string, + intentDirs: string[], typeCheckPreflight: boolean, config: NextConfigComplete, cacheDir?: string @@ -41,7 +41,7 @@ export async function verifyTypeScriptSetup( try { // Check if the project uses TypeScript: - const intent = await getTypeScriptIntent(dir, pagesDir, config) + const intent = await getTypeScriptIntent(dir, intentDirs, config) if (!intent) { return { version: null } } diff --git a/packages/next/server/dev/next-dev-server.ts b/packages/next/server/dev/next-dev-server.ts index d23353c1ceeefc6..c935563c58b0ae6 100644 --- a/packages/next/server/dev/next-dev-server.ts +++ b/packages/next/server/dev/next-dev-server.ts @@ -96,6 +96,8 @@ export default class DevServer extends Server { protected sortedRoutes?: string[] private addedUpgradeListener = false private pagesDir: string + // @ts-ignore TODO: add implementation + private rootDir?: string protected staticPathsWorker?: { [key: string]: any } & { loadStaticPaths: typeof import('./static-paths-worker').loadStaticPaths @@ -175,7 +177,13 @@ export default class DevServer extends Server { } this.isCustomServer = !options.isNextDevCommand - this.pagesDir = findPagesDir(this.dir) + // TODO: hot-reload root/pages dirs? + const { pages: pagesDir, root: rootDir } = findPagesDir( + this.dir, + this.nextConfig.experimental.rootDir + ) + this.pagesDir = pagesDir + this.rootDir = rootDir } protected getBuildId(): string { @@ -361,7 +369,12 @@ export default class DevServer extends Server { async prepare(): Promise { setGlobal('distDir', this.distDir) setGlobal('phase', PHASE_DEVELOPMENT_SERVER) - await verifyTypeScriptSetup(this.dir, this.pagesDir, false, this.nextConfig) + await verifyTypeScriptSetup( + this.dir, + [this.pagesDir!, this.rootDir].filter(Boolean) as string[], + false, + this.nextConfig + ) this.customRoutes = await loadCustomRoutes(this.nextConfig) From b4af8fdfaa7cd030fa276ddddaca09828601fae5 Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Mon, 2 May 2022 14:30:39 +0200 Subject: [PATCH 2/3] Rename isFlightPage -> isServerComponentPage Co-Authored-By: JJ Kasper <22380829+ijjk@users.noreply.github.com> --- packages/next/build/entries.ts | 7 +++++-- packages/next/build/index.ts | 4 ++-- packages/next/build/utils.ts | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/packages/next/build/entries.ts b/packages/next/build/entries.ts index 7181d6f8c971818..7aa7b83f6230e47 100644 --- a/packages/next/build/entries.ts +++ b/packages/next/build/entries.ts @@ -17,7 +17,7 @@ import { __ApiPreviewProps } from '../server/api-utils' import { isTargetLikeServerless } from '../server/utils' import { warn } from './output/log' import { parse } from '../build/swc' -import { isFlightPage, withoutRSCExtensions } from './utils' +import { isServerComponentPage, withoutRSCExtensions } from './utils' import { normalizePathSep } from '../shared/lib/page-path/normalize-path-sep' import { normalizePagePath } from '../shared/lib/page-path/normalize-page-path' @@ -251,7 +251,10 @@ export function getEdgeServerEntry(opts: { absolutePagePath: opts.absolutePagePath, buildId: opts.buildId, dev: opts.isDev, - isServerComponent: isFlightPage(opts.config, opts.absolutePagePath), + isServerComponent: isServerComponentPage( + opts.config, + opts.absolutePagePath + ), page: opts.page, stringifiedConfig: JSON.stringify(opts.config), } diff --git a/packages/next/build/index.ts b/packages/next/build/index.ts index 41af1eb15a0918d..4171a17f1983102 100644 --- a/packages/next/build/index.ts +++ b/packages/next/build/index.ts @@ -100,7 +100,7 @@ import { copyTracedFiles, isReservedPage, isCustomErrorPage, - isFlightPage, + isServerComponentPage, } from './utils' import getBaseWebpackConfig from './webpack-config' import { PagesManifest } from './webpack/plugins/pages-manifest-plugin' @@ -977,7 +977,7 @@ export default async function build( : undefined if (hasServerComponents && pagePath) { - if (isFlightPage(config, pagePath)) { + if (isServerComponentPage(config, pagePath)) { isServerComponent = true } } diff --git a/packages/next/build/utils.ts b/packages/next/build/utils.ts index 74e29050550be44..70e29d4f8b874a1 100644 --- a/packages/next/build/utils.ts +++ b/packages/next/build/utils.ts @@ -1101,7 +1101,7 @@ export function withoutRSCExtensions(pageExtensions: string[]): string[] { ) } -export function isFlightPage( +export function isServerComponentPage( nextConfig: NextConfigComplete, filePath: string ): boolean { From a4004df8e2e9f1c47c36751a4e14f7c2e845170b Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Mon, 2 May 2022 14:33:02 +0200 Subject: [PATCH 3/3] Update find-pages-dir.ts Co-Authored-By: Jiachi Liu <4800338+huozhi@users.noreply.github.com> --- packages/next/lib/find-pages-dir.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/next/lib/find-pages-dir.ts b/packages/next/lib/find-pages-dir.ts index 8528880012884a3..862849fd00dec1c 100644 --- a/packages/next/lib/find-pages-dir.ts +++ b/packages/next/lib/find-pages-dir.ts @@ -10,7 +10,7 @@ export const existsSync = (f: string): boolean => { } } -function findDir(dir: string, name: string): string | null { +function findDir(dir: string, name: 'pages' | 'root'): string | null { // prioritize ./${name} over ./src/${name} let curDir = path.join(dir, name) if (existsSync(curDir)) return curDir