Skip to content

Commit

Permalink
Merge branch 'feat/angular-v19'
Browse files Browse the repository at this point in the history
  • Loading branch information
ocombe committed Nov 27, 2024
2 parents ee8657f + e378d69 commit dc8ebde
Show file tree
Hide file tree
Showing 178 changed files with 1,873 additions and 4,326 deletions.
262 changes: 194 additions & 68 deletions .bitmap

Large diffs are not rendered by default.

36 changes: 19 additions & 17 deletions angular/app-types/angular-app-type/angular.application.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import { VERSION } from '@angular/cli';
import {
ApplicationOptions,
getWorkspace,
NG_APP_NAME,
normalizePath
} from '@bitdev/angular.dev-services.common';
import { getWorkspace, NG_APP_NAME, normalizePath } from '@bitdev/angular.dev-services.common';
import { ApplicationBuilderOptions, SsrClass } from '@bitdev/angular.dev-services.ng-compat';
import { AngularPreview } from '@bitdev/angular.dev-services.preview.preview';
import {
AppBuildContext,
Expand Down Expand Up @@ -44,7 +40,7 @@ export class AngularApp implements Application {
readonly options: AngularAppOptions
) {
this.name = options.name || NG_APP_NAME;
this.idName = `bitdev.angular/${ this.name }`;
this.idName = `bitdev.angular/${this.name}`;
this.deploy = options.deploy;
}

Expand All @@ -59,19 +55,19 @@ export class AngularApp implements Application {
}

private getTsconfigPath(tempFolder: string): string {
return normalizePath(join(tempFolder, `tsconfig/tsconfig-${ Date.now() }.json`));
return normalizePath(join(tempFolder, `tsconfig/tsconfig-${Date.now()}.json`));
}

private getPublicDir(artifactsDir: string) {
return join(artifactsDir, this.name);
}

private getDevServerContext(context: AppContext, _appRootPath: string): DevServerContext {
private getDevServerContext(context: AppContext): DevServerContext {
// const ngEnvOptions = this.angularEnv.getNgEnvOptions();
return Object.assign(cloneDeep(context), {
entry: [],
rootPath: /*ngEnvOptions.devServer === 'vite' ? _appRootPath : */'',
publicPath: `${ this.publicDir }/${ this.options.name }`,
publicPath: `${this.publicDir}/${this.options.name}`,
title: this.options.name
});
}
Expand Down Expand Up @@ -122,9 +118,9 @@ export class AngularApp implements Application {
const pkgName = depsResolver.getPackageName(dep);
// TODO we should find a way to use the real entry file based on the component config because people can change it
if (fs.existsSync(join(componentDir, 'public-api.ts'))) {
tsconfigJSON.compilerOptions.paths[pkgName] = [`${ componentDir }/public-api.ts`, `${ componentDir }`];
tsconfigJSON.compilerOptions.paths[pkgName] = [`${componentDir}/public-api.ts`, `${componentDir}`];
}
tsconfigJSON.compilerOptions.paths[`${ pkgName }/*`] = [`${ componentDir }/*`];
tsconfigJSON.compilerOptions.paths[`${pkgName}/*`] = [`${componentDir}/*`];
}
});

Expand Down Expand Up @@ -181,7 +177,7 @@ export class AngularApp implements Application {
const envVars = await this.getEnvFile('development', appRootPath, context.envVariables as any);
await serveApplication({
angularOptions: {
...this.options.angularBuildOptions as ApplicationOptions,
...this.options.angularBuildOptions as ApplicationBuilderOptions,
tsConfig: tsconfigPath
},
sourceRoot: this.options.sourceRoot || 'src',
Expand All @@ -194,7 +190,7 @@ export class AngularApp implements Application {
}
});
} else {
const devServerContext = this.getDevServerContext(context, appRootPath);
const devServerContext = this.getDevServerContext(context);
const envContext = this.getEnvContext(context);
const preview = this.getPreview(tsconfigPath)(envContext);

Expand All @@ -216,8 +212,13 @@ export class AngularApp implements Application {
const outputPath = this.getPublicDir(context.artifactsDir);
const appRootPath = capsule.path;
const appTsconfigPath = join(appRootPath, this.options.angularBuildOptions.tsConfig);
const appOptions = this.options.angularBuildOptions as ApplicationOptions;
const entryServer = appOptions.ssr && Number(VERSION.major) >= 17 ? './entry.server.ts' : undefined;
const appOptions = this.options.angularBuildOptions as ApplicationBuilderOptions;
let entryServer: string | undefined;
if ((appOptions.ssr as SsrClass)?.entry) {
entryServer = (appOptions.ssr as SsrClass).entry;
} else if (appOptions.ssr && Number(VERSION.major) >= 17 && Number(VERSION.major) < 19) {
entryServer = './entry.server.ts';
}
const tempFolder = this.getTempFolder();
const tsconfigPath = this.getTsconfigPath(tempFolder);
this.generateTsConfig([capsule.component], appRootPath, appTsconfigPath, tsconfigPath, depsResolver, undefined, entryServer);
Expand All @@ -239,6 +240,7 @@ export class AngularApp implements Application {
'process.env': envVars
}
});
console.log('build done');
} else {
let bundler: Bundler;
if (this.options.bundler) {
Expand All @@ -260,7 +262,7 @@ export class AngularApp implements Application {
metadata: {
outputPath,
publicDir: join(outputPath, 'browser'),
ssrPublicDir: appOptions.ssr ? join(outputPath, 'ssr') : undefined
ssrPublicDir: appOptions.ssr ? join(outputPath, Number(VERSION.major) >= 19 ? 'server' : 'ssr') : undefined
}
};
}
Expand Down
56 changes: 26 additions & 30 deletions angular/app-types/angular-app-type/application.bundler.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,8 @@
/* eslint-disable no-param-reassign */
import { OutputHashing } from '@angular-devkit/build-angular';
import { VERSION } from '@angular/cli';
import {
ApplicationOptions,
dedupPaths,
getLoggerApi,
normalizePath
} from '@bitdev/angular.dev-services.common';
import {
type ApplicationBuilderOptions,
buildApplicationInternal
} from '@bitdev/angular.dev-services.ng-compat';
import { dedupPaths, getLoggerApi, normalizePath } from '@bitdev/angular.dev-services.common';
import { type ApplicationBuilderOptions, buildApplicationInternal } from '@bitdev/angular.dev-services.ng-compat';
import { Logger } from '@teambit/logger';
import assert from 'assert';
import fs from 'fs-extra';
Expand All @@ -22,7 +14,7 @@ import definePlugin from './plugins/define.plugin.js';
import { getIndexInputFile } from './utils.js';

export type BuildApplicationOptions = {
angularOptions: Partial<ApplicationOptions>;
angularOptions: Partial<ApplicationBuilderOptions>;
outputPath: string;
sourceRoot: string;
workspaceRoot: string;
Expand All @@ -36,10 +28,10 @@ export type BuildApplicationOptions = {
const BUILDER_NAME = '@angular-devkit/build-angular:application';

export async function buildApplication(options: BuildApplicationOptions): Promise<void> {
const { angularOptions: { tsConfig, ssr, define }, envVars } = options;
const { angularOptions: { tsConfig, server, define }, envVars } = options;
assert(tsConfig, 'tsConfig option is required');
const isSsr = !!ssr && Number(VERSION.major) >= 17;
if (isSsr) {
const isSsr = !!server && Number(VERSION.major) >= 17;
if (isSsr && Number(VERSION.major) < 19) {
addEntryServer(options);
}
const appOptions = getAppOptions(options, isSsr);
Expand All @@ -58,7 +50,8 @@ export async function buildApplication(options: BuildApplicationOptions): Promis
}
}

if (isSsr) {
// Versions of Angular <19 require a nitro middleware to support SSR API endpoints
if (isSsr && Number(VERSION.major) < 19) {
await buildNitro(options);
}
}
Expand All @@ -68,7 +61,7 @@ function addEntryServer(options: BuildApplicationOptions): void {
if (ssr && entryServer) {
const fileContent = `import type { ApplicationRef } from '@angular/core';
import { renderApplication, renderModule } from '@angular/platform-server';
import bootstrap from '${ server?.replace(extname(server), '') }';
import bootstrap from '${server?.replace(extname(server), '')}';
function isBootstrapFn(value: unknown): value is () => Promise<ApplicationRef> {
// We can differentiate between a module and a bootstrap function by reading compiler-generated "ɵmod" static property:
Expand All @@ -95,19 +88,20 @@ export default async function render(url: string, document: string) {
}
}

function getAppOptions(options: BuildApplicationOptions, isSsr: boolean): any {
function getAppOptions(options: BuildApplicationOptions, isSsr: boolean): ApplicationBuilderOptions {
const { entryServer, angularOptions, outputPath, sourceRoot, workspaceRoot } = options;

// declare constants for all reusable values here
const normalizedIndex = `./${ join(sourceRoot, 'index.html') }`;
const normalizedBrowser = `./${ join(sourceRoot, 'main.ts') }`;
const normalizedIndex = `./${join(sourceRoot, 'index.html')}`;
const normalizedBrowser = `./${join(sourceRoot, 'main.ts')}`;
const serverPath = `./${join(sourceRoot, 'main.server.ts')}`;

const dedupedAssets = dedupPaths([posix.join(sourceRoot, `assets/**/*`), ...(angularOptions.assets ?? [])]);
const dedupedStyles = dedupPaths([posix.join(sourceRoot, `styles.${ angularOptions.inlineStyleLanguage }`), ...(angularOptions.styles ?? [])]);
const dedupedStyles = dedupPaths([posix.join(sourceRoot, `styles.${angularOptions.inlineStyleLanguage}`), ...(angularOptions.styles ?? [])]);

return {
...angularOptions,
baseHref: angularOptions.baseHref ?? './',
baseHref: angularOptions.baseHref ?? '/',
preserveSymlinks: false,
outputPath,
index: angularOptions.index ?? normalizedIndex,
Expand All @@ -117,13 +111,14 @@ function getAppOptions(options: BuildApplicationOptions, isSsr: boolean): any {
styles: dedupedStyles,
scripts: angularOptions.scripts,
namedChunks: angularOptions.namedChunks ?? true,
optimization: angularOptions.optimization ?? true,
optimization: false,//angularOptions.optimization ?? true,
aot: true,
deleteOutputPath: true,
sourceMap: angularOptions.sourceMap ?? true,
outputHashing: angularOptions.outputHashing ?? OutputHashing.All,
outputHashing: OutputHashing.None,//angularOptions.outputHashing ?? OutputHashing.All,
watch: false,
server: isSsr ? angularOptions.server : undefined,
outputMode: angularOptions.outputMode ?? (isSsr ? 'server' : 'static'),
server: isSsr ? angularOptions.server ?? serverPath : undefined,
prerender: isSsr ? (angularOptions.prerender ?? !!angularOptions.server) : undefined,
ssr: isSsr ? {
entry: entryServer
Expand All @@ -149,14 +144,15 @@ function getBuilderContext(options: BuildApplicationOptions, appOptions: Applica
project: 'bit-ng-app-builder',
target: 'build'
},
getProjectMetadata: function(projectName: string): Promise<any> {
getProjectMetadata: function (): Promise<any> {
return Promise.resolve({
root: '',
sourceRoot,
cli: { cache: { enabled: true, path: resolve(tempFolder, 'angular/cache') } }
});
},
addTeardown: () => {},
addTeardown: () => {
},
getBuilderNameForTarget: () => Promise.resolve(BUILDER_NAME),
getTargetOptions: () => Promise.resolve(appOptions as any),
validateOptions: () => Promise.resolve(appOptions as any)
Expand All @@ -177,18 +173,18 @@ async function getNitroConfig(options: BuildApplicationOptions): Promise<NitroCo
const nitroDir = normalizePath(resolve(outputDir, 'ssr'));
const indexPath = getIndexInputFile(index!);

const prerenderedRoutes = prerender ? (await import(`${ outputDir }/prerendered-routes.json`, { assert: { type: 'json' }})).default : undefined;
const prerenderedRoutes = prerender ? (await import(`${outputDir}/prerendered-routes.json`, { assert: { type: 'json' } })).default : undefined;

return {
rootDir: workspaceRoot,
logLevel: 1, // TODO reset this to 3 or 2 https://github.com/unjs/consola/#log-level
srcDir: normalizePath(`${ workspaceRoot }/src/server`),
scanDirs: [normalizePath(`${ workspaceRoot }/src/server`)],
srcDir: normalizePath(`${workspaceRoot}/src/server`),
scanDirs: [normalizePath(`${workspaceRoot}/src/server`)],
buildDir: resolve(tempFolder, 'nitro'),

alias: ssr ? {
'#alias/entry.server': normalizePath(join(serverDir, 'server.mjs')),
'#alias/index': normalizePath(join(serverDir, `${ basename(indexPath, extname(indexPath)) }.server.html`))
'#alias/index': normalizePath(join(serverDir, `${basename(indexPath, extname(indexPath))}.server.html`))
} : {},
serverAssets: ssr ? [{
baseName: 'public',
Expand Down
52 changes: 28 additions & 24 deletions angular/app-types/angular-app-type/application.dev-server.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,8 @@
/* eslint-disable no-param-reassign */
import { executeDevServerBuilder, OutputHashing } from '@angular-devkit/build-angular';
import { VERSION } from '@angular/cli';
import {
dedupPaths,
getLoggerApi,
normalizePath
} from '@bitdev/angular.dev-services.common';
import {
type ApplicationBuilderOptions,
type DevServerBuilderOptions
} from '@bitdev/angular.dev-services.ng-compat';
import { dedupPaths, getLoggerApi, normalizePath } from '@bitdev/angular.dev-services.common';
import { type ApplicationBuilderOptions, type DevServerBuilderOptions, } from '@bitdev/angular.dev-services.ng-compat';
import { Logger } from '@teambit/logger';
import assert from 'assert';
import { createEvent } from 'h3';
Expand Down Expand Up @@ -45,10 +38,18 @@ export async function serveApplication(options: ServeApplicationOptions): Promis
const isSsr = !!server && Number(VERSION.major) >= 17;
const appOptions = getAppOptions(options, isSsr);
const builderContext = getBuilderContext(options, appOptions);
const devServerOptions = isSsr ? {
buildPlugins: [definePlugin({ ...envVars, ...define })],
middleware: [await createNitroApiMiddleware(options)]
} : undefined;
const devServerOptions: any = {
buildPlugins: [],
middleware: []
};
if (isSsr) {
devServerOptions.buildPlugins = [definePlugin({ ...envVars, ...define })];

// Versions of Angular <19 require a nitro middleware to support SSR API endpoints
if (Number(VERSION.major) < 19) {
devServerOptions.middleware = [await createNitroApiMiddleware(options)];
}
}

// @ts-ignore only v17+ has 4 arguments, previous versions only have 3
await executeDevServerBuilder(appOptions, builderContext as any, undefined, devServerOptions).toPromise();
Expand All @@ -57,16 +58,16 @@ export async function serveApplication(options: ServeApplicationOptions): Promis
function getAppOptions(options: ServeApplicationOptions, isSsr: boolean): ApplicationBuilderOptions & DevServerBuilderOptions {
const { angularOptions, port, sourceRoot, workspaceRoot } = options;
// declare constants for all reusable values here
const normalizedIndex = `./${ join(sourceRoot, 'index.html') }`;
const normalizedBrowser = `./${ join(sourceRoot, 'main.ts') }`;
const serverPath = `./${ join(sourceRoot, 'main.server.ts') }`;
const normalizedIndex = `./${join(sourceRoot, 'index.html')}`;
const normalizedBrowser = `./${join(sourceRoot, 'main.ts')}`;
const serverPath = `./${join(sourceRoot, 'main.server.ts')}`;

const dedupedAssets = dedupPaths([posix.join(sourceRoot, `assets/**/*`), ...(angularOptions.assets ?? [])]);
const dedupedStyles = dedupPaths([posix.join(sourceRoot, `styles.${ angularOptions.inlineStyleLanguage }`), ...(angularOptions.styles ?? [])]);
const dedupedStyles = dedupPaths([posix.join(sourceRoot, `styles.${angularOptions.inlineStyleLanguage}`), ...(angularOptions.styles ?? [])]);

return {
...angularOptions,
baseHref: angularOptions.baseHref,
baseHref: angularOptions.baseHref ?? '/',
preserveSymlinks: false,
outputPath: OUTPUT_PATH,
index: angularOptions.index ?? normalizedIndex,
Expand All @@ -82,7 +83,9 @@ function getAppOptions(options: ServeApplicationOptions, isSsr: boolean): Applic
sourceMap: angularOptions.sourceMap ?? true,
outputHashing: angularOptions.outputHashing ?? OutputHashing.All,
watch: true,
liveReload: true,
liveReload: angularOptions.liveReload ?? true,
hmr: angularOptions.hmr ?? false,
outputMode: angularOptions.outputMode ?? (isSsr ? 'server' : 'static'),
server: isSsr ? angularOptions.server ?? serverPath : undefined,
prerender: isSsr ? angularOptions.prerender ?? !!angularOptions.server : false,
ssr: isSsr ? (angularOptions.ssr ?? !!angularOptions.server) : false,
Expand Down Expand Up @@ -115,7 +118,8 @@ function getBuilderContext(options: ServeApplicationOptions, appOptions: Applica
target: 'development'
},
getProjectMetadata: getProjectMetadata(options),
addTeardown: () => {},
addTeardown: () => {
},
getBuilderNameForTarget: () => Promise.resolve(BUILDER_NAME),
getTargetOptions: () => Promise.resolve(appOptions as any),
validateOptions: () => Promise.resolve(appOptions as any)
Expand All @@ -124,7 +128,7 @@ function getBuilderContext(options: ServeApplicationOptions, appOptions: Applica

function getProjectMetadata(options: ServeApplicationOptions) {
const { sourceRoot, tempFolder } = options;
return function(projectName: string): Promise<any> {
return function (): Promise<any> {
return Promise.resolve({
root: '',
sourceRoot,
Expand All @@ -144,8 +148,8 @@ function getNitroConfig(options: ServeApplicationOptions): NitroConfig {
return {
rootDir,
logLevel: 2,
srcDir: normalizePath(`${ rootDir }/src/server`),
scanDirs: [normalizePath(`${ rootDir }/src/server`)],
srcDir: normalizePath(`${rootDir}/src/server`),
scanDirs: [normalizePath(`${rootDir}/src/server`)],
buildDir: resolve(tempFolder, 'nitro')
};
}
Expand All @@ -164,7 +168,7 @@ async function createNitroApiMiddleware(options: ServeApplicationOptions): Promi
const server = createDevServer(nitro);
await build(nitro);

return async(
return async (
req: any,
res: any,
next: any
Expand Down
2 changes: 1 addition & 1 deletion angular/app-types/angular-app-type/component.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"componentId": {
"scope": "bitdev.angular",
"name": "app-types/angular-app-type",
"version": "6.0.11"
"version": "7.0.0"
},
"propagate": false,
"extensions": {
Expand Down
2 changes: 1 addition & 1 deletion angular/devkit/common/component.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"componentId": {
"scope": "bitdev.angular",
"name": "dev-services/common",
"version": "6.0.8"
"version": "7.0.0"
},
"propagate": false,
"extensions": {
Expand Down
Loading

0 comments on commit dc8ebde

Please sign in to comment.