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

Angular v17 support #6480

Merged
merged 17 commits into from
Nov 17, 2023
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Added the ability to deploy Angular apps using [the new application-builder](https://angular.dev/tools/cli/esbuild). (#6480)
50 changes: 27 additions & 23 deletions src/frameworks/angular/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
SupportLevel,
BUILD_TARGET_PURPOSE,
} from "../interfaces";
import { promptOnce } from "../../prompt";
import {
simpleProxy,
relativeRequire,
Expand All @@ -36,41 +35,30 @@

const DEFAULT_BUILD_SCRIPT = ["ng build"];

export async function discover(dir: string): Promise<Discovery | undefined> {

Check warning on line 38 in src/frameworks/angular/index.ts

View workflow job for this annotation

GitHub Actions / lint (18)

Missing JSDoc comment
if (!(await pathExists(join(dir, "package.json")))) return;
if (!(await pathExists(join(dir, "angular.json")))) return;
return { mayWantBackend: true, publicDirectory: join(dir, "src", "assets") };
}

export async function init(setup: any, config: any) {
export function init(setup: any, config: any) {

Check warning on line 44 in src/frameworks/angular/index.ts

View workflow job for this annotation

GitHub Actions / lint (18)

Missing return type on function

Check warning on line 44 in src/frameworks/angular/index.ts

View workflow job for this annotation

GitHub Actions / lint (18)

Missing JSDoc comment

Check warning on line 44 in src/frameworks/angular/index.ts

View workflow job for this annotation

GitHub Actions / lint (18)

Unexpected any. Specify a different type

Check warning on line 44 in src/frameworks/angular/index.ts

View workflow job for this annotation

GitHub Actions / lint (18)

Unexpected any. Specify a different type
execSync(
`npx --yes -p @angular/cli@latest ng new ${setup.projectId} --directory ${setup.hosting.source} --skip-git`,

Check warning on line 46 in src/frameworks/angular/index.ts

View workflow job for this annotation

GitHub Actions / lint (18)

Invalid type "any" of template literal expression

Check warning on line 46 in src/frameworks/angular/index.ts

View workflow job for this annotation

GitHub Actions / lint (18)

Unsafe member access .projectId on an `any` value

Check warning on line 46 in src/frameworks/angular/index.ts

View workflow job for this annotation

GitHub Actions / lint (18)

Invalid type "any" of template literal expression

Check warning on line 46 in src/frameworks/angular/index.ts

View workflow job for this annotation

GitHub Actions / lint (18)

Unsafe member access .hosting on an `any` value
{
stdio: "inherit",
cwd: config.projectDir,

Check warning on line 49 in src/frameworks/angular/index.ts

View workflow job for this annotation

GitHub Actions / lint (18)

Unsafe assignment of an `any` value
}
);
const useAngularUniversal = await promptOnce({
name: "useAngularUniversal",
type: "confirm",
default: false,
message: `Would you like to setup Angular Universal?`,
});
if (useAngularUniversal) {
execSync("ng add @nguniversal/express-engine --skip-confirmation", {
stdio: "inherit",
cwd: join(config.projectDir, setup.hosting.source),
});
}
return Promise.resolve();
}

export async function build(dir: string, configuration: string): Promise<BuildResult> {
Copy link
Contributor

@9kubczas4 9kubczas4 Nov 8, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should mark useAngularUniversal in the init function as legacy?

  const useAngularUniversal = await promptOnce({
    name: "useAngularUniversal",
    type: "confirm",
    default: false,
    message: `Would you like to setup Angular Universal?`,
  });
  if (useAngularUniversal) {
    execSync("ng add @nguniversal/express-engine --skip-confirmation", {
      stdio: "inherit",
      cwd: join(config.projectDir, setup.hosting.source),
    });
  }

Cause NG CLI in v17 is asking about Do you want to enable Server-Side Rendering (SSR) and Static Site Generation (SSG/Prerendering)?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, I should rework the bootstrap. It should be part of Angular's create routine now

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since you are using @angular/cli@latest, @nguniversal/express-engine should not be used as this is only supported for version 16 and before.

const {
targets,
serverTarget,
serveOptimizedImages,
locales,
baseHref: baseUrl,
ssr,
} = await getBuildConfig(dir, configuration);
await warnIfCustomBuildScript(dir, name, DEFAULT_BUILD_SCRIPT);
for (const target of targets) {
Expand All @@ -84,8 +72,8 @@
if (result.status !== 0) throw new FirebaseError(`Unable to build ${target}`);
}

const wantsBackend = !!serverTarget || serveOptimizedImages;
const rewrites = serverTarget
const wantsBackend = ssr || serveOptimizedImages;
const rewrites = ssr
? []
: [
{
Expand Down Expand Up @@ -149,8 +137,12 @@
export async function getValidBuildTargets(purpose: BUILD_TARGET_PURPOSE, dir: string) {
const validTargetNames = new Set(["development", "production"]);
try {
const { workspaceProject, browserTarget, serverTarget, serveTarget } = await getContext(dir);
const { target } = ((purpose === "emulate" && serveTarget) || serverTarget || browserTarget)!;
const { workspaceProject, buildTarget, browserTarget, prerenderTarget, serveTarget } =
await getContext(dir);
const { target } = ((purpose === "emulate" && serveTarget) ||
buildTarget ||
prerenderTarget ||
browserTarget)!;
const workspaceTarget = workspaceProject.targets.get(target)!;
Object.keys(workspaceTarget.configurations || {}).forEach((it) => validTargetNames.add(it));
} catch (e) {
Expand Down Expand Up @@ -182,6 +174,7 @@
externalDependencies,
baseHref,
serveOptimizedImages,
serverEntry,
} = await getServerConfig(sourceDir, configuration);

const dotEnv = { __NG_BROWSER_OUTPUT_PATH__: browserOutputPath };
Expand Down Expand Up @@ -232,14 +225,25 @@
if (localizedApps.has(locale)) {
localizedApps.get(locale)(req,res);
} else {
const app = require(\`./${serverOutputPath}/\${locale}/main.js\`).app(locale);
localizedApps.set(locale, app);
app(req,res);
${
serverEntry?.endsWith(".mjs")
? `import(\`./${serverOutputPath}/\${locale}/${serverEntry}\`)`
: `Promise.resolve(require(\`./${serverOutputPath}/\${locale}/${serverEntry}\`))`
}.then(server => {
const app = server.app(locale);
localizedApps.set(locale, app);
app(req,res);
});
}
});
};\n`;
} else if (serverOutputPath) {
bootstrapScript = `exports.handle = require('./${serverOutputPath}/main.js').app();\n`;
bootstrapScript = `const app = ${
serverEntry?.endsWith(".mjs")
? `import(\`./${serverOutputPath}/${serverEntry}\`)`
: `Promise.resolve(require('./${serverOutputPath}/${serverEntry}'))`
}.then(server => server.app());
exports.handle = (req,res) => app.then(it => it(req,res));\n`;
} else {
bootstrapScript = `exports.handle = (res, req) => req.sendStatus(404);\n`;
rewriteSource = posix.join(baseHref, "__image__");
Expand Down
Loading
Loading