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

Use esbuild lib instead of npx #7395

Merged
merged 9 commits into from
Aug 2, 2024
36 changes: 16 additions & 20 deletions src/frameworks/next/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { execSync } from "child_process";
import { spawn, sync as spawnSync } from "cross-spawn";
import { spawn } from "cross-spawn";
import { mkdir, copyFile } from "fs/promises";
import { basename, dirname, join } from "path";
import type { NextConfig } from "next";
Expand All @@ -16,6 +16,7 @@
import { pick } from "stream-json/filters/Pick";
import { streamObject } from "stream-json/streamers/StreamObject";
import { fileExistsSync } from "../../fsutils";
import * as esbuild from "esbuild";
jamesdaniels marked this conversation as resolved.
Show resolved Hide resolved

import { promptOnce } from "../../prompt";
import { FirebaseError } from "../../error";
Expand Down Expand Up @@ -74,7 +75,6 @@
ROUTES_MANIFEST,
APP_PATH_ROUTES_MANIFEST,
APP_PATHS_MANIFEST,
ESBUILD_VERSION,
SERVER_REFERENCE_MANIFEST,
} from "./constants";
import { getAllSiteDomains, getDeploymentDomain } from "../../hosting/api";
Expand All @@ -90,17 +90,16 @@
export const type = FrameworkType.MetaFramework;
export const docsUrl = "https://firebase.google.com/docs/hosting/frameworks/nextjs";

const BUNDLE_NEXT_CONFIG_TIMEOUT = 60_000;
const DEFAULT_NUMBER_OF_REASONS_TO_LIST = 5;

function getReactVersion(cwd: string): string | undefined {
return findDependency("react-dom", { cwd, omitDev: false })?.version;

Check warning on line 96 in src/frameworks/next/index.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unsafe return of an `any` typed value

Check warning on line 96 in src/frameworks/next/index.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unsafe member access .version on an `any` value
}

/**
* Returns whether this codebase is a Next.js backend.
*/
export async function discover(dir: string) {

Check warning on line 102 in src/frameworks/next/index.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Missing return type on function
if (!(await pathExists(join(dir, "package.json")))) return;
const version = getNextVersion(dir);
if (!(await whichNextConfigFile(dir)) && !version) return;
Expand Down Expand Up @@ -145,10 +144,10 @@

const nextBuild = new Promise((resolve, reject) => {
const buildProcess = spawn(cli, ["build"], { cwd: dir, env });
buildProcess.stdout?.on("data", (data) => logger.info(data.toString()));

Check warning on line 147 in src/frameworks/next/index.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unsafe argument of type `any` assigned to a parameter of type `Error`

Check warning on line 147 in src/frameworks/next/index.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unsafe member access .toString on an `any` value

Check warning on line 147 in src/frameworks/next/index.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unsafe call of an `any` typed value
buildProcess.stderr?.on("data", (data) => logger.info(data.toString()));

Check warning on line 148 in src/frameworks/next/index.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unsafe argument of type `any` assigned to a parameter of type `Error`

Check warning on line 148 in src/frameworks/next/index.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unsafe member access .toString on an `any` value

Check warning on line 148 in src/frameworks/next/index.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Unsafe call of an `any` typed value
buildProcess.on("error", (err) => {
reject(new FirebaseError(`Unable to build your Next.js app: ${err}`));

Check warning on line 150 in src/frameworks/next/index.ts

View workflow job for this annotation

GitHub Actions / lint (20)

Invalid type "Error" of template literal expression
});
buildProcess.on("exit", (code) => {
resolve(code);
Expand Down Expand Up @@ -595,27 +594,24 @@
});
// Mark all production deps as externals, so they aren't bundled
// DevDeps won't be included in the Cloud Function, so they should be bundled
const esbuildArgs = productionDeps
.map((it) => `--external:${it}`)
.concat("--bundle", "--platform=node", `--target=node${NODE_VERSION}`, "--log-level=error");

const esbuildArgs: esbuild.BuildOptions = {
entryPoints: [join(sourceDir, configFile)],
outfile: join(destDir, configFile),
bundle: true,
platform: "node",
target: `node${NODE_VERSION}`,
logLevel: "error",
external: productionDeps,
};
if (configFile === "next.config.mjs") {
// ensure generated file is .mjs if the config is .mjs
esbuildArgs.push(...[`--outfile=${join(destDir, configFile)}`, "--format=esm"]);
} else {
esbuildArgs.push(`--outfile=${join(destDir, configFile)}`);
esbuildArgs.format = "esm";
}

const bundle = spawnSync(
"npx",
["--yes", `esbuild@${ESBUILD_VERSION}`, configFile, ...esbuildArgs],
{
cwd: sourceDir,
timeout: BUNDLE_NEXT_CONFIG_TIMEOUT,
},
);
if (bundle.status !== 0) {
throw new FirebaseError(bundle.stderr.toString());
const bundle = await esbuild.build(esbuildArgs);

if (bundle.errors.length > 0) {
throw new FirebaseError(bundle.errors.toString());
}
} catch (e: any) {
console.warn(
Expand Down
Loading