From a9295388a56a9a1bbbb219838c5e1bb3142d014e Mon Sep 17 00:00:00 2001 From: Chalo Salvador Date: Wed, 13 Nov 2024 18:11:40 +0100 Subject: [PATCH 1/4] Increase memory for server function on Next.js wiht image optimization --- src/frameworks/index.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/frameworks/index.ts b/src/frameworks/index.ts index cac8731d93e..e300f748a1c 100644 --- a/src/frameworks/index.ts +++ b/src/frameworks/index.ts @@ -55,6 +55,7 @@ import { resolveProjectPath } from "../projectPath"; import { logger } from "../logger"; import { WebFrameworks } from "./frameworks"; import { constructDefaultWebSetup } from "../fetchWebSetup"; +import { isUsingImageOptimization } from "./next/utils"; export { WebFrameworks }; @@ -538,6 +539,12 @@ ${ // TODO move to templates + if (frameworksBackend && framework === "next") { + if (await isUsingImageOptimization(getProjectPath(), ".next")) { + frameworksBackend.memory = "512MiB"; + } + } + if (packageJson.type === "module") { await writeFile( join(functionsDist, "server.js"), From 2e88772ec73ebb0a78c3446a6a3dd63ddf5e6466 Mon Sep 17 00:00:00 2001 From: Chalo Salvador Date: Fri, 15 Nov 2024 12:28:16 +0100 Subject: [PATCH 2/4] Return frameworksBackend from Next files --- src/firebaseConfig.ts | 2 +- src/frameworks/index.ts | 21 +++++++-------------- src/frameworks/interfaces.ts | 24 ++++++++++++++++-------- src/frameworks/next/index.ts | 20 +++++++++++++++++++- 4 files changed, 43 insertions(+), 24 deletions(-) diff --git a/src/firebaseConfig.ts b/src/firebaseConfig.ts index dc0d59066ed..c2b8ca3e6c1 100644 --- a/src/firebaseConfig.ts +++ b/src/firebaseConfig.ts @@ -94,7 +94,7 @@ export type HostingHeaders = HostingSource & { // Allow only serializable options, since this is in firebase.json // TODO(jamesdaniels) look into allowing serialized CEL expressions, params, and regexp // and if we can build this interface automatically via Typescript silliness -interface FrameworksBackendOptions extends HttpsOptions { +export interface FrameworksBackendOptions extends HttpsOptions { omit?: boolean; cors?: string | boolean; memory?: MemoryOption; diff --git a/src/frameworks/index.ts b/src/frameworks/index.ts index e300f748a1c..164ba563311 100644 --- a/src/frameworks/index.ts +++ b/src/frameworks/index.ts @@ -55,7 +55,6 @@ import { resolveProjectPath } from "../projectPath"; import { logger } from "../logger"; import { WebFrameworks } from "./frameworks"; import { constructDefaultWebSetup } from "../fetchWebSetup"; -import { isUsingImageOptimization } from "./next/utils"; export { WebFrameworks }; @@ -410,6 +409,7 @@ export async function prepareFrameworks( frameworksEntry = framework, dotEnv = {}, rewriteSource, + frameworksBackend: functionsDirectoryFrameworksBackend, } = await codegenFunctionsDirectory( getProjectPath(), functionsDist, @@ -538,21 +538,16 @@ ${ if (bootstrapScript) await writeFile(join(functionsDist, "bootstrap.js"), bootstrapScript); // TODO move to templates - - if (frameworksBackend && framework === "next") { - if (await isUsingImageOptimization(getProjectPath(), ".next")) { - frameworksBackend.memory = "512MiB"; - } - } - + const mergedFrameworksBackend = { + ...functionsDirectoryFrameworksBackend, + ...frameworksBackend, + }; if (packageJson.type === "module") { await writeFile( join(functionsDist, "server.js"), `import { onRequest } from 'firebase-functions/v2/https'; const server = import('firebase-frameworks'); - export const ${functionId} = onRequest(${JSON.stringify( - frameworksBackend || {}, - )}, (req, res) => server.then(it => it.handle(req, res))); + export const ${functionId} = onRequest(${JSON.stringify(mergedFrameworksBackend)} || {}, (req, res) => server.then(it => it.handle(req, res))); `, ); } else { @@ -560,9 +555,7 @@ ${ join(functionsDist, "server.js"), `const { onRequest } = require('firebase-functions/v2/https'); const server = import('firebase-frameworks'); - exports.${functionId} = onRequest(${JSON.stringify( - frameworksBackend || {}, - )}, (req, res) => server.then(it => it.handle(req, res))); + exports.${functionId} = onRequest(${JSON.stringify(mergedFrameworksBackend)} || {}, (req, res) => server.then(it => it.handle(req, res))); `, ); } diff --git a/src/frameworks/interfaces.ts b/src/frameworks/interfaces.ts index 51344e751fc..f447fcc37e1 100644 --- a/src/frameworks/interfaces.ts +++ b/src/frameworks/interfaces.ts @@ -1,6 +1,11 @@ import { IncomingMessage, ServerResponse } from "http"; import { EmulatorInfo } from "../emulator/types"; -import { HostingHeaders, HostingRedirects, HostingRewrites } from "../firebaseConfig"; +import { + FrameworksBackendOptions, + HostingHeaders, + HostingRedirects, + HostingRewrites, +} from "../firebaseConfig"; import { HostingOptions } from "../hosting/options"; import { Options } from "../options"; @@ -54,6 +59,15 @@ export type FrameworkContext = { site?: string; }; +export type CodegenFunctionDirectoryResult = { + bootstrapScript?: string; + packageJson: any; + frameworksEntry?: string; + dotEnv?: Record; + rewriteSource?: string; + frameworksBackend?: FrameworksBackendOptions; +}; + export interface Framework { supportedRange?: string; discover: (dir: string) => Promise; @@ -82,13 +96,7 @@ export interface Framework { dest: string, target: string, context?: FrameworkContext, - ) => Promise<{ - bootstrapScript?: string; - packageJson: any; - frameworksEntry?: string; - dotEnv?: Record; - rewriteSource?: string; - }>; + ) => Promise; getValidBuildTargets?: (purpose: BUILD_TARGET_PURPOSE, dir: string) => Promise; shouldUseDevModeHandle?: (target: string, dir: string) => Promise; } diff --git a/src/frameworks/next/index.ts b/src/frameworks/next/index.ts index b4746cc8079..d6a3d16e335 100644 --- a/src/frameworks/next/index.ts +++ b/src/frameworks/next/index.ts @@ -31,6 +31,7 @@ import { } from "../utils"; import { BuildResult, + CodegenFunctionDirectoryResult, Framework, FrameworkContext, FrameworkType, @@ -83,6 +84,7 @@ import { import { getAllSiteDomains, getDeploymentDomain } from "../../hosting/api"; import { logger } from "../../logger"; import { parseStrict } from "../../functions/env"; +import { FrameworksBackendOptions } from "../../firebaseConfig"; const DEFAULT_BUILD_SCRIPT = ["next build"]; const PUBLIC_DIR = "public"; @@ -677,8 +679,14 @@ export async function ɵcodegenFunctionsDirectory( } // Add the `sharp` library if app is using image optimization + + let frameworksBackend: FrameworksBackendOptions | undefined; if (await isUsingImageOptimization(sourceDir, distDir)) { packageJson.dependencies["sharp"] = SHARP_VERSION; + // TODO check if it is only for Next 15 + frameworksBackend = { + memory: "512MiB", + }; } const dotEnv: Record = {}; @@ -710,7 +718,17 @@ export async function ɵcodegenFunctionsDirectory( ), ); - return { packageJson, frameworksEntry: "next.js", dotEnv }; + const result: CodegenFunctionDirectoryResult = { + packageJson, + frameworksEntry: "next.js", + dotEnv, + }; + + if (frameworksBackend) { + result.frameworksBackend = frameworksBackend; + } + + return result; } /** From 58faa2a3fa8c95011d74e7d1e51580d3d45c03ce Mon Sep 17 00:00:00 2001 From: Chalo Salvador Date: Wed, 4 Dec 2024 10:08:59 +0100 Subject: [PATCH 3/4] Move todo comment --- src/frameworks/index.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/frameworks/index.ts b/src/frameworks/index.ts index 164ba563311..c9d12f630fb 100644 --- a/src/frameworks/index.ts +++ b/src/frameworks/index.ts @@ -537,11 +537,12 @@ ${ if (bootstrapScript) await writeFile(join(functionsDist, "bootstrap.js"), bootstrapScript); - // TODO move to templates const mergedFrameworksBackend = { ...functionsDirectoryFrameworksBackend, ...frameworksBackend, }; + + // TODO move to templates if (packageJson.type === "module") { await writeFile( join(functionsDist, "server.js"), From c9939ab8b6bd1480032e7fcae526468a58d5d48f Mon Sep 17 00:00:00 2001 From: Chalo Salvador Date: Wed, 4 Dec 2024 10:09:16 +0100 Subject: [PATCH 4/4] Move memory value to a constant --- src/frameworks/next/constants.ts | 1 + src/frameworks/next/index.ts | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/frameworks/next/constants.ts b/src/frameworks/next/constants.ts index ef507a72189..78bd7e64429 100644 --- a/src/frameworks/next/constants.ts +++ b/src/frameworks/next/constants.ts @@ -22,6 +22,7 @@ export const ROUTES_MANIFEST: typeof ROUTES_MANIFEST_TYPE = "routes-manifest.jso export const APP_PATHS_MANIFEST: typeof APP_PATHS_MANIFEST_TYPE = "app-paths-manifest.json"; export const SERVER_REFERENCE_MANIFEST: `${typeof SERVER_REFERENCE_MANIFEST_TYPE}.json` = "server-reference-manifest.json"; +export const NEXTJS_IMAGE_OPTIMIZATION_MEMORY = "512MiB"; export const CONFIG_FILES = ["next.config.js", "next.config.mjs"] as const; diff --git a/src/frameworks/next/index.ts b/src/frameworks/next/index.ts index d6a3d16e335..c5cf14b67c3 100644 --- a/src/frameworks/next/index.ts +++ b/src/frameworks/next/index.ts @@ -80,6 +80,7 @@ import { APP_PATHS_MANIFEST, SERVER_REFERENCE_MANIFEST, ESBUILD_VERSION, + NEXTJS_IMAGE_OPTIMIZATION_MEMORY, } from "./constants"; import { getAllSiteDomains, getDeploymentDomain } from "../../hosting/api"; import { logger } from "../../logger"; @@ -679,13 +680,12 @@ export async function ɵcodegenFunctionsDirectory( } // Add the `sharp` library if app is using image optimization - let frameworksBackend: FrameworksBackendOptions | undefined; if (await isUsingImageOptimization(sourceDir, distDir)) { packageJson.dependencies["sharp"] = SHARP_VERSION; - // TODO check if it is only for Next 15 + frameworksBackend = { - memory: "512MiB", + memory: NEXTJS_IMAGE_OPTIMIZATION_MEMORY, }; }