From 73884ece27bdacaea8b16bd8217d89ee4a0cf4d1 Mon Sep 17 00:00:00 2001 From: Thomas Bouldin Date: Mon, 17 Oct 2022 18:54:13 -0700 Subject: [PATCH] We don't need no public dir (#5142) * We don't need no public dir * Add docs * Add changelog --- CHANGELOG.md | 1 + src/frameworks/next/index.ts | 29 ++++++++++++++++++++++++++--- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e69de29bb2d..8574c68ed0c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -0,0 +1 @@ +Fix a bug where next.js applications would fail to deploy if they did not have a public dir (#5142) diff --git a/src/frameworks/next/index.ts b/src/frameworks/next/index.ts index a24d30db5b5..b79c5a0510f 100644 --- a/src/frameworks/next/index.ts +++ b/src/frameworks/next/index.ts @@ -51,6 +51,9 @@ function getNextVersion(cwd: string) { return findDependency("next", { cwd, depth: 0, omitDev: false })?.version; } +/** + * Returns whether this codebase is a Next.js backend. + */ export async function discover(dir: string) { if (!(await pathExists(join(dir, "package.json")))) return; if (!(await pathExists("next.config.js")) && !getNextVersion(dir)) return; @@ -58,6 +61,9 @@ export async function discover(dir: string) { return { mayWantBackend: true, publicDirectory: join(dir, "public") }; } +/** + * Build a next.js application. + */ export async function build(dir: string): Promise { const { default: nextBuild } = relativeRequire(dir, "next/dist/build"); @@ -133,6 +139,9 @@ export async function build(dir: string): Promise { return { wantsBackend, headers, redirects, rewrites }; } +/** + * Utility method used during project initialization. + */ export async function init(setup: any) { const language = await promptOnce({ type: "list", @@ -148,6 +157,9 @@ export async function init(setup: any) { ); } +/** + * Create a directory for SSG content. + */ export async function ɵcodegenPublicDirectory(sourceDir: string, destDir: string) { const { distDir } = await getConfig(sourceDir); const exportDetailPath = join(sourceDir, distDir, "export-detail.json"); @@ -157,8 +169,11 @@ export async function ɵcodegenPublicDirectory(sourceDir: string, destDir: strin if (exportDetailJson?.success) { copy(exportDetailJson.outDirectory, destDir); } else { + const publicPath = join(sourceDir, "public"); await mkdir(join(destDir, "_next", "static"), { recursive: true }); - await copy(join(sourceDir, "public"), destDir); + if (await pathExists(publicPath)) { + await copy(publicPath, destDir); + } await copy(join(sourceDir, distDir, "static"), join(destDir, "_next", "static")); const serverPagesDir = join(sourceDir, distDir, "server", "pages"); @@ -202,6 +217,9 @@ export async function ɵcodegenPublicDirectory(sourceDir: string, destDir: strin } } +/** + * Create a directory for SSR content. + */ export async function ɵcodegenFunctionsDirectory(sourceDir: string, destDir: string) { const { distDir } = await getConfig(sourceDir); const packageJsonBuffer = await readFile(join(sourceDir, "package.json")); @@ -227,13 +245,18 @@ export async function ɵcodegenFunctionsDirectory(sourceDir: string, destDir: st platform: "node", }); } - await mkdir(join(destDir, "public")); + if (await pathExists(join(sourceDir, "public"))) { + await mkdir(join(destDir, "public")); + await copy(join(sourceDir, "public"), join(destDir, "public")); + } await mkdirp(join(destDir, distDir)); - await copy(join(sourceDir, "public"), join(destDir, "public")); await copy(join(sourceDir, distDir), join(destDir, distDir)); return { packageJson, frameworksEntry: "next.js" }; } +/** + * Create a dev server. + */ export async function getDevModeHandle(dir: string) { const { default: next } = relativeRequire(dir, "next"); const nextApp = next({