Skip to content

Commit 31a2588

Browse files
authored
Add well known version ranges to Web Frameworks (#6562)
1 parent 2ccd9d9 commit 31a2588

File tree

18 files changed

+119
-41
lines changed

18 files changed

+119
-41
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
- Fixed an issue preventing Angular apps using ng-deploy from being emulated or deployed. (#6584)
2+
- Warn if a Web Framework is outside a well known version range on deploy/emulate. (#6562)
3+
- Use Web Framework's well known version range in `firebase init hosting`. (#6562)

src/frameworks/angular/index.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020
} from "../utils";
2121
import {
2222
getAllTargets,
23+
getAngularVersion,
2324
getBrowserConfig,
2425
getBuildConfig,
2526
getContext,
@@ -35,15 +36,18 @@ export const docsUrl = "https://firebase.google.com/docs/hosting/frameworks/angu
3536

3637
const DEFAULT_BUILD_SCRIPT = ["ng build"];
3738

39+
export const supportedRange = "14 - 17";
40+
3841
export async function discover(dir: string): Promise<Discovery | undefined> {
3942
if (!(await pathExists(join(dir, "package.json")))) return;
4043
if (!(await pathExists(join(dir, "angular.json")))) return;
41-
return { mayWantBackend: true, publicDirectory: join(dir, "src", "assets") };
44+
const version = getAngularVersion(dir);
45+
return { mayWantBackend: true, publicDirectory: join(dir, "src", "assets"), version };
4246
}
4347

4448
export function init(setup: any, config: any) {
4549
execSync(
46-
`npx --yes -p @angular/cli@latest ng new ${setup.projectId} --directory ${setup.hosting.source} --skip-git`,
50+
`npx --yes -p @angular/cli@"${supportedRange}" ng new ${setup.projectId} --directory ${setup.hosting.source} --skip-git`,
4751
{
4852
stdio: "inherit",
4953
cwd: config.projectDir,

src/frameworks/angular/utils.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@ import type { ProjectDefinition } from "@angular-devkit/core/src/workspace";
33
import type { WorkspaceNodeModulesArchitectHost } from "@angular-devkit/architect/node";
44

55
import { AngularI18nConfig } from "./interfaces";
6-
import { relativeRequire, validateLocales } from "../utils";
6+
import { findDependency, relativeRequire, validateLocales } from "../utils";
77
import { FirebaseError } from "../../error";
88
import { join, posix, sep } from "path";
99
import { BUILD_TARGET_PURPOSE } from "../interfaces";
1010
import { AssertionError } from "assert";
1111
import { assertIsString } from "../../utils";
12+
import { coerce } from "semver";
1213

1314
async function localesForTarget(
1415
dir: string,
@@ -539,3 +540,17 @@ export async function getBuildConfig(sourceDir: string, configuration: string) {
539540
ssr,
540541
};
541542
}
543+
544+
/**
545+
* Get Angular version in the following format: `major.minor.patch`, ignoring
546+
* canary versions as it causes issues with semver comparisons.
547+
*/
548+
export function getAngularVersion(cwd: string): string | undefined {
549+
const dependency = findDependency("@angular/core", { cwd, depth: 0, omitDev: false });
550+
if (!dependency) return undefined;
551+
552+
const angularVersionSemver = coerce(dependency.version);
553+
if (!angularVersionSemver) return dependency.version;
554+
555+
return angularVersionSemver.toString();
556+
}

src/frameworks/astro/index.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,17 @@ import { getAstroVersion, getBootstrapScript, getConfig } from "./utils";
99
export const name = "Astro";
1010
export const support = SupportLevel.Experimental;
1111
export const type = FrameworkType.MetaFramework;
12+
export const supportedRange = "2 - 3";
1213

1314
export async function discover(dir: string): Promise<Discovery | undefined> {
1415
if (!existsSync(join(dir, "package.json"))) return;
15-
if (!getAstroVersion(dir)) return;
16+
const version = getAstroVersion(dir);
17+
if (!version) return;
1618
const { output, publicDir: publicDirectory } = await getConfig(dir);
1719
return {
1820
mayWantBackend: output !== "static",
1921
publicDirectory,
22+
version,
2023
};
2124
}
2225

src/frameworks/constants.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ export const SupportLevelWarnings = {
88
[SupportLevel.Experimental]: (framework: string) => `Thank you for trying our ${clc.italic(
99
"experimental"
1010
)} support for ${framework} on Firebase Hosting.
11-
${clc.yellow(`While this integration is maintained by Googlers it is not a supported Firebase product.
11+
${clc.red(`While this integration is maintained by Googlers it is not a supported Firebase product.
1212
Issues filed on GitHub will be addressed on a best-effort basis by maintainers and other community members.`)}`,
1313
[SupportLevel.Preview]: (framework: string) => `Thank you for trying our ${clc.italic(
1414
"early preview"
1515
)} of ${framework} support on Firebase Hosting.
16-
${clc.yellow(
16+
${clc.red(
1717
"During the preview, support is best-effort and breaking changes can be expected. Proceed with caution."
1818
)}`,
1919
};

src/frameworks/docs/nextjs.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ Using the {{firebase_cli}}, you can deploy your Next.js Web apps to Firebase and
1414
serve them with {{firebase_hosting}}. The {{cli}} respects your Next.js settings and
1515
translates them to Firebase settings with zero or minimal extra configuration on
1616
your part. If your app includes dynamic server-side logic, the {{cli}} deploys that
17-
logic to {{cloud_functions_full}}. The latest supported Next.js version is 13.4.7.
17+
logic to {{cloud_functions_full}}.
1818

1919
<<_includes/_preview-disclaimer.md>>
2020

src/frameworks/index.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,11 +261,21 @@ export async function prepareFrameworks(
261261
name,
262262
support,
263263
docsUrl,
264+
supportedRange,
264265
getValidBuildTargets = GET_DEFAULT_BUILD_TARGETS,
265266
shouldUseDevModeHandle = DEFAULT_SHOULD_USE_DEV_MODE_HANDLE,
266267
} = WebFrameworks[framework];
268+
267269
logger.info(
268-
`\n${frameworksCallToAction(SupportLevelWarnings[support](name), docsUrl, " ")}\n`
270+
`\n${frameworksCallToAction(
271+
SupportLevelWarnings[support](name),
272+
docsUrl,
273+
" ",
274+
name,
275+
results.version,
276+
supportedRange,
277+
results.vite
278+
)}\n`
269279
);
270280

271281
const hostingEmulatorInfo = emulators.find((e) => e.name === Emulators.HOSTING);

src/frameworks/interfaces.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ export const enum SupportLevel {
2323
export interface Discovery {
2424
mayWantBackend: boolean;
2525
publicDirectory: string;
26+
version?: string;
27+
vite?: boolean;
2628
}
2729

2830
export interface BuildResult {
@@ -53,6 +55,7 @@ export type FrameworkContext = {
5355
};
5456

5557
export interface Framework {
58+
supportedRange?: string;
5659
discover: (dir: string) => Promise<Discovery | undefined>;
5760
type: FrameworkType;
5861
name: string;

src/frameworks/next/index.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ import { logger } from "../../logger";
7373
const DEFAULT_BUILD_SCRIPT = ["next build"];
7474
const PUBLIC_DIR = "public";
7575

76+
export const supportedRange = "12 - 14.0";
77+
7678
export const name = "Next.js";
7779
export const support = SupportLevel.Preview;
7880
export const type = FrameworkType.MetaFramework;
@@ -90,9 +92,10 @@ function getReactVersion(cwd: string): string | undefined {
9092
*/
9193
export async function discover(dir: string) {
9294
if (!(await pathExists(join(dir, "package.json")))) return;
93-
if (!(await pathExists("next.config.js")) && !getNextVersion(dir)) return;
95+
const version = getNextVersion(dir);
96+
if (!(await pathExists("next.config.js")) && !version) return;
9497

95-
return { mayWantBackend: true, publicDirectory: join(dir, PUBLIC_DIR) };
98+
return { mayWantBackend: true, publicDirectory: join(dir, PUBLIC_DIR), version };
9699
}
97100

98101
/**
@@ -317,9 +320,9 @@ export async function init(setup: any, config: any) {
317320
choices: ["JavaScript", "TypeScript"],
318321
});
319322
execSync(
320-
`npx --yes create-next-app@latest -e hello-world ${setup.hosting.source} --use-npm ${
321-
language === "TypeScript" ? "--ts" : "--js"
322-
}`,
323+
`npx --yes create-next-app@"${supportedRange}" -e hello-world ${
324+
setup.hosting.source
325+
} --use-npm ${language === "TypeScript" ? "--ts" : "--js"}`,
323326
{ stdio: "inherit", cwd: config.projectDir }
324327
);
325328
}

src/frameworks/nuxt/index.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { getNuxtVersion } from "./utils";
1010
export const name = "Nuxt";
1111
export const support = SupportLevel.Experimental;
1212
export const type = FrameworkType.Toolchain;
13+
export const supportedRange = "3";
1314

1415
import { nuxtConfigFilesExist } from "./utils";
1516
import type { NuxtOptions } from "./interfaces";
@@ -27,16 +28,16 @@ export async function discover(dir: string) {
2728

2829
const anyConfigFileExists = await nuxtConfigFilesExist(dir);
2930

30-
const nuxtVersion = getNuxtVersion(dir);
31-
if (!anyConfigFileExists && !nuxtVersion) return;
32-
if (nuxtVersion && lt(nuxtVersion, "3.0.0-0")) return;
31+
const version = getNuxtVersion(dir);
32+
if (!anyConfigFileExists && !version) return;
33+
if (version && lt(version, "3.0.0-0")) return;
3334

3435
const {
3536
dir: { public: publicDirectory },
3637
ssr: mayWantBackend,
3738
} = await getConfig(dir);
3839

39-
return { publicDirectory, mayWantBackend };
40+
return { publicDirectory, mayWantBackend, version };
4041
}
4142

4243
export async function build(cwd: string) {

0 commit comments

Comments
 (0)