Skip to content

Commit 9719c22

Browse files
authored
Angular use spec (#261)
* add output bundle spec to common module * bump common module version * use new output bundle spec * resolve merge * copy over all resources * add packagejson update * fix lint * refactor angular to use spec * undo nextjs changes * fix lint * lint * fix e2e test * bump versions
1 parent 717eded commit 9719c22

File tree

10 files changed

+59
-87
lines changed

10 files changed

+59
-87
lines changed

package-lock.json

Lines changed: 2 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@apphosting/adapter-angular/e2e/run-local.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ const tests = await Promise.all(
7373

7474
const bundleYaml = parseYaml(readFileSync(join(cwd, ".apphosting/bundle.yaml")).toString());
7575

76-
const runCommand = bundleYaml.runCommand;
76+
const runCommand = bundleYaml.serverConfig.runCommand;
7777

7878
if (typeof runCommand !== "string") {
7979
throw new Error("runCommand must be a string");

packages/@apphosting/adapter-angular/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@apphosting/adapter-angular",
3-
"version": "17.2.8",
3+
"version": "17.2.9",
44
"main": "dist/index.js",
55
"description": "Experimental addon to the Firebase CLI to add web framework support",
66
"repository": {

packages/@apphosting/adapter-angular/src/bin/build.spec.ts

Lines changed: 21 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -13,38 +13,32 @@ describe("build commands", () => {
1313
beforeEach(() => {
1414
tmpDir = generateTmpDir();
1515
outputBundleOptions = {
16-
baseDirectory: resolve(tmpDir, "dist", "test"),
17-
browserDirectory: resolve(tmpDir, ".apphosting", "dist", "browser"),
16+
browserDirectory: resolve(tmpDir, "dist", "test", "browser"),
1817
bundleYamlPath: resolve(tmpDir, ".apphosting", "bundle.yaml"),
19-
outputBaseDirectory: resolve(tmpDir, ".apphosting", "dist"),
20-
outputDirectory: resolve(tmpDir, ".apphosting"),
21-
serverFilePath: resolve(tmpDir, ".apphosting", "dist", "server", "server.mjs"),
18+
serverFilePath: resolve(tmpDir, "dist", "test", "server", "server.mjs"),
2219
needsServerGenerated: false,
2320
};
2421
defaultAngularVersion = "17.3.8";
2522
});
2623

2724
it("expects all output bundle files to be generated", async () => {
28-
const { generateOutputDirectory, validateOutputDirectory, createMetadata } = await importUtils;
25+
const { generateBuildOutput, validateOutputDirectory, createMetadata } = await importUtils;
2926
const files = {
3027
"dist/test/browser/browserfile": "",
3128
"dist/test/server/server.mjs": "",
3229
};
3330
const packageVersion = createMetadata(defaultAngularVersion).adapterVersion;
3431
generateTestFiles(tmpDir, files);
35-
await generateOutputDirectory(tmpDir, outputBundleOptions, defaultAngularVersion);
32+
await generateBuildOutput(tmpDir, outputBundleOptions, defaultAngularVersion);
3633
await validateOutputDirectory(outputBundleOptions);
3734

3835
const expectedFiles = {
39-
".apphosting/dist/browser/browserfile": "",
40-
".apphosting/dist/server/server.mjs": "",
41-
".apphosting/bundle.yaml": `
42-
runCommand: node .apphosting/dist/server/server.mjs
43-
neededDirs:
44-
- .apphosting
45-
staticAssets:
46-
- .apphosting/dist/browser
47-
env: []
36+
"dist/test/browser/browserfile": "",
37+
"dist/test/server/server.mjs": "",
38+
".apphosting/bundle.yaml": `version: v1
39+
serverConfig:
40+
runCommand: node dist/test/server/server.mjs
41+
environmentVariables: []
4842
metadata:
4943
adapterPackageName: "@apphosting/adapter-angular"
5044
adapterVersion: ${packageVersion}
@@ -56,43 +50,40 @@ metadata:
5650
});
5751

5852
it("expects SSR_PORT variable is added to bundle.yaml for Angular v17.3.2", async () => {
59-
const { generateOutputDirectory } = await importUtils;
53+
const { generateBuildOutput } = await importUtils;
6054
const files = {
6155
"dist/test/browser/browserfile": "",
6256
"dist/test/server/server.mjs": "",
6357
};
6458
generateTestFiles(tmpDir, files);
65-
await generateOutputDirectory(tmpDir, outputBundleOptions, "17.3.2");
59+
await generateBuildOutput(tmpDir, outputBundleOptions, "17.3.2");
6660

67-
const expectedContents = `env:
68-
- variable: SSR_PORT
69-
value: "8080"
70-
availability: RUNTIME
71-
`;
61+
const expectedContents = ` environmentVariables:
62+
- variable: SSR_PORT
63+
value: "8080"
64+
availability:
65+
- RUNTIME`;
7266
validateFileExistsAndContains(tmpDir, ".apphosting/bundle.yaml", expectedContents);
7367
});
7468

7569
it("test failed validateOutputDirectory", async () => {
76-
const { generateOutputDirectory, validateOutputDirectory } = await importUtils;
70+
const { generateBuildOutput, validateOutputDirectory } = await importUtils;
7771
const files = {
7872
"dist/test/browser/browserfile": "",
7973
"dist/test/server/notserver.mjs": "",
8074
};
8175
generateTestFiles(tmpDir, files);
82-
await generateOutputDirectory(tmpDir, outputBundleOptions, defaultAngularVersion);
76+
await generateBuildOutput(tmpDir, outputBundleOptions, defaultAngularVersion);
8377
assert.rejects(async () => await validateOutputDirectory(outputBundleOptions));
8478
});
8579

8680
it("test populate output bundle options", async () => {
8781
const { populateOutputBundleOptions } = await importUtils;
8882
const expectedOutputBundleOptions = {
89-
baseDirectory: "/test",
90-
browserDirectory: resolve(".apphosting", "browser"),
83+
browserDirectory: "/browser",
9184
bundleYamlPath: resolve(".apphosting", "bundle.yaml"),
92-
outputBaseDirectory: resolve(".apphosting", "dist"),
93-
outputDirectory: resolve("", ".apphosting"),
9485
needsServerGenerated: false,
95-
serverFilePath: resolve(".apphosting", "server", "server.mjs"),
86+
serverFilePath: path.join("/server", "server.mjs"),
9687
};
9788
const outputPaths = {
9889
root: new URL("file:///test"),

packages/@apphosting/adapter-angular/src/bin/build.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
#! /usr/bin/env node
22
import {
3-
generateOutputDirectory,
3+
generateBuildOutput,
44
checkBuildConditions,
55
validateOutputDirectory,
66
parseOutputBundleOptions,
77
} from "../utils.js";
88
import { getBuildOptions, runBuild } from "@apphosting/common";
99

10-
const root = process.cwd();
1110
const opts = getBuildOptions();
1211

1312
// Check build conditions, which vary depending on your project structure (standalone or monorepo)
@@ -23,6 +22,7 @@ if (!output) {
2322
throw new Error("No output from Angular build command, expecting a build manifest file.");
2423
}
2524
const outputBundleOptions = parseOutputBundleOptions(output);
26-
await generateOutputDirectory(root, outputBundleOptions, process.env.FRAMEWORK_VERSION);
25+
const root = process.cwd();
26+
await generateBuildOutput(root, outputBundleOptions, process.env.FRAMEWORK_VERSION);
2727

2828
await validateOutputDirectory(outputBundleOptions);

packages/@apphosting/adapter-angular/src/interface.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@ import { URL } from "node:url";
44
// options to help generate output directory
55
export interface OutputBundleOptions {
66
bundleYamlPath: string;
7-
outputDirectory: string;
8-
baseDirectory: string;
9-
outputBaseDirectory: string;
107
serverFilePath: string;
118
browserDirectory: string;
129
needsServerGenerated: boolean;

packages/@apphosting/adapter-angular/src/utils.ts

Lines changed: 27 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,16 @@ import { fileURLToPath } from "url";
55
import { execSync } from "child_process";
66
import { resolve, normalize, relative, dirname, join } from "path";
77
import { stringify as yamlStringify } from "yaml";
8-
import {
9-
Availability,
10-
EnvironmentVariable,
11-
Metadata,
12-
OutputBundleOptions,
13-
OutputPaths,
14-
buildManifestSchema,
15-
} from "./interface.js";
8+
import { OutputBundleOptions, OutputPaths, buildManifestSchema } from "./interface.js";
169
import { createRequire } from "node:module";
1710
import stripAnsi from "strip-ansi";
18-
import { BuildOptions } from "@apphosting/common";
11+
import {
12+
BuildOptions,
13+
OutputBundleConfig,
14+
EnvVarConfig,
15+
Metadata,
16+
Availability,
17+
} from "@apphosting/common";
1918

2019
// fs-extra is CJS, readJson can't be imported using shorthand
2120
export const { writeFile, move, readJson, mkdir, copyFile, readFileSync, existsSync } = fsExtra;
@@ -95,14 +94,10 @@ export function populateOutputBundleOptions(outputPaths: OutputPaths): OutputBun
9594
serverRelativePath = relative(baseDirectory, fileURLToPath(outputPaths["server"]));
9695
needsServerGenerated = false;
9796
}
98-
9997
return {
10098
bundleYamlPath: resolve(outputBundleDir, "bundle.yaml"),
101-
outputDirectory: outputBundleDir,
102-
baseDirectory,
103-
outputBaseDirectory: resolve(outputBundleDir, "dist"),
104-
serverFilePath: resolve(outputBundleDir, "dist", serverRelativePath, "server.mjs"),
105-
browserDirectory: resolve(outputBundleDir, "dist", browserRelativePath),
99+
serverFilePath: resolve(baseDirectory, serverRelativePath, "server.mjs"),
100+
browserDirectory: resolve(baseDirectory, browserRelativePath),
106101
needsServerGenerated,
107102
};
108103
}
@@ -161,32 +156,28 @@ export function createMetadata(angularVersion: string): Metadata {
161156
}
162157

163158
/**
164-
* Move the base output directory, which contains the server and browser bundle directory, and prerendered routes
165-
* as well as generating bundle.yaml.
159+
* Generate the bundle.yaml
166160
*/
167-
export async function generateOutputDirectory(
161+
export async function generateBuildOutput(
168162
cwd: string,
169163
outputBundleOptions: OutputBundleOptions,
170164
angularVersion: string,
171165
): Promise<void> {
172-
await move(outputBundleOptions.baseDirectory, outputBundleOptions.outputBaseDirectory, {
173-
overwrite: true,
174-
});
175166
if (outputBundleOptions.needsServerGenerated) {
176167
await generateServer(outputBundleOptions);
177168
}
178169
await generateBundleYaml(outputBundleOptions, cwd, angularVersion);
179170
}
180171

181172
// add environment variable to bundle.yaml if needed for specific versions
182-
function generateEnvVars(angularVersion: string): EnvironmentVariable[] {
183-
const runtimeEnvVars: EnvironmentVariable[] = [];
173+
function generateEnvVars(angularVersion: string): EnvVarConfig[] {
174+
const runtimeEnvVars: EnvVarConfig[] = [];
184175
// add env var to solve angular port issue, existing only for Angular v17.3.2 (b/332896115)
185176
if (angularVersion === "17.3.2") {
186-
const ssrPortEnvVar: EnvironmentVariable = {
177+
const ssrPortEnvVar: EnvVarConfig = {
187178
variable: "SSR_PORT",
188179
value: "8080",
189-
availability: Availability.Runtime,
180+
availability: [Availability.Runtime],
190181
};
191182
runtimeEnvVars.push(ssrPortEnvVar);
192183
}
@@ -195,20 +186,20 @@ function generateEnvVars(angularVersion: string): EnvironmentVariable[] {
195186

196187
// Generate bundle.yaml
197188
async function generateBundleYaml(
198-
outputBundleOptions: OutputBundleOptions,
189+
opts: OutputBundleOptions,
199190
cwd: string,
200191
angularVersion: string,
201192
): Promise<void> {
202-
await writeFile(
203-
outputBundleOptions.bundleYamlPath,
204-
yamlStringify({
205-
runCommand: `node ${normalize(relative(cwd, outputBundleOptions.serverFilePath))}`,
206-
neededDirs: [normalize(relative(cwd, outputBundleOptions.outputDirectory))],
207-
staticAssets: [normalize(relative(cwd, outputBundleOptions.browserDirectory))],
208-
env: generateEnvVars(angularVersion),
209-
metadata: createMetadata(angularVersion),
210-
}),
211-
);
193+
await mkdir(dirname(opts.bundleYamlPath));
194+
const outputBundle: OutputBundleConfig = {
195+
version: "v1",
196+
serverConfig: {
197+
runCommand: `node ${normalize(relative(cwd, opts.serverFilePath))}`,
198+
environmentVariables: generateEnvVars(angularVersion),
199+
},
200+
metadata: createMetadata(angularVersion),
201+
};
202+
await writeFile(opts.bundleYamlPath, yamlStringify(outputBundle));
212203
}
213204

214205
// Generate server file for CSR apps
@@ -222,7 +213,6 @@ export async function validateOutputDirectory(
222213
outputBundleOptions: OutputBundleOptions,
223214
): Promise<void> {
224215
if (
225-
!(await fsExtra.exists(outputBundleOptions.outputDirectory)) ||
226216
!(await fsExtra.exists(outputBundleOptions.browserDirectory)) ||
227217
!(await fsExtra.exists(outputBundleOptions.serverFilePath)) ||
228218
!(await fsExtra.exists(outputBundleOptions.bundleYamlPath))

packages/@apphosting/adapter-nextjs/e2e/app.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ describe("app", () => {
9696
const initialResponse = await fetch(posix.join(host, "isr", "demand"));
9797
assert.ok(initialResponse.ok);
9898
const initialText = await initialResponse.text();
99-
const initialUUID = initialText.match(/UUID<\/p>\s*<h2>([^<]+)<\/h2>/)?.[1];
99+
const initialUUID = /UUID<\/p>\s*<h2>([^<]+)<\/h2>/.exec(initialText)?.[1];
100100

101101
// Trigger revalidation
102102
const revalidateResponse = await fetch(posix.join(host, "isr", "demand", "revalidate"), {
@@ -108,7 +108,7 @@ describe("app", () => {
108108
const newResponse = await fetch(posix.join(host, "isr", "demand"));
109109
assert.ok(newResponse.ok);
110110
const newText = await newResponse.text();
111-
const newUUID = newText.match(/UUID<\/p>\s*<h2>([^<]+)<\/h2>/)?.[1];
111+
const newUUID = /UUID<\/p>\s*<h2>([^<]+)<\/h2>/.exec(newText)?.[1];
112112

113113
// Check if the UUID has changed, indicating successful revalidation
114114
assert.notEqual(initialUUID, newUUID, "UUID should change after revalidation");

packages/@apphosting/common/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@apphosting/common",
3-
"version": "0.0.3",
3+
"version": "0.0.4",
44
"description": "Shared library code for App Hosting framework adapters",
55
"author": {
66
"name": "Firebase",

packages/@apphosting/common/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ export interface EnvVarConfig {
5151
// Represents where environment variables are made available
5252
export enum Availability {
5353
// Runtime environment variables are available on the server when the app is run
54-
Runtime,
54+
Runtime = "RUNTIME",
5555
}
5656

5757
// Options to configure the build of a framework application

0 commit comments

Comments
 (0)