From e19a80d2df0a1353fb61e91db909ce0bb7c6f45d Mon Sep 17 00:00:00 2001 From: Nicolas Frizzarin Date: Sat, 29 Mar 2025 13:30:10 +0100 Subject: [PATCH] feat(nf): compatibility with @angular/build package --- .../src/schematics/init-webpack/schematic.ts | 13 +++--- .../src/builders/build/builder.ts | 45 ++++++++++--------- .../src/schematics/appbuilder/schematic.ts | 5 ++- .../src/schematics/init/schematic.ts | 30 ++++++++----- .../src/utils/check-builder.ts | 22 +++++++++ 5 files changed, 74 insertions(+), 41 deletions(-) create mode 100644 libs/native-federation/src/utils/check-builder.ts diff --git a/libs/mf/src/schematics/init-webpack/schematic.ts b/libs/mf/src/schematics/init-webpack/schematic.ts index 1f19d2d3..8729bcf4 100644 --- a/libs/mf/src/schematics/init-webpack/schematic.ts +++ b/libs/mf/src/schematics/init-webpack/schematic.ts @@ -1,16 +1,16 @@ import { + apply, chain, + mergeWith, + move, Rule, + template, Tree, url, - apply, - mergeWith, - template, - move, } from '@angular-devkit/schematics'; -import { NodePackageInstallTask } from '@angular-devkit/schematics/tasks'; import { strings } from '@angular-devkit/core'; +import { NodePackageInstallTask } from '@angular-devkit/schematics/tasks'; import * as json5 from 'json5'; import * as semver from 'semver'; @@ -232,7 +232,8 @@ export default function config(options: MfSchematicSchema): Rule { const buildConfig = projectConfig?.architect?.build; const isApplicationBuilder = - buildConfig?.builder === '@angular-devkit/build-angular:application'; + buildConfig?.builder === '@angular-devkit/build-angular:application' || + buildConfig?.builder === '@angular/build:application'; if (isApplicationBuilder && !options.skipConfirmation) { console.warn( diff --git a/libs/native-federation/src/builders/build/builder.ts b/libs/native-federation/src/builders/build/builder.ts index 595e6784..004ba85e 100644 --- a/libs/native-federation/src/builders/build/builder.ts +++ b/libs/native-federation/src/builders/build/builder.ts @@ -1,11 +1,11 @@ -import * as path from 'path'; import * as fs from 'fs'; import * as mrmime from 'mrmime'; +import * as path from 'path'; -import { buildApplication, ApplicationBuilderOptions } from '@angular/build'; +import { ApplicationBuilderOptions, buildApplication } from '@angular/build'; import { - serveWithVite, buildApplicationInternal, + serveWithVite, } from '@angular/build/private'; import { @@ -16,39 +16,38 @@ import { import { normalizeOptions } from '@angular-devkit/build-angular/src/builders/dev-server/options'; -import { setLogLevel, logger } from '@softarc/native-federation/build'; +import { logger, setLogLevel } from '@softarc/native-federation/build'; -import { FederationOptions } from '@softarc/native-federation/build'; -import { setBuildAdapter } from '@softarc/native-federation/build'; +import { targetFromTargetString } from '@angular-devkit/architect'; +import { + buildForFederation, + FederationOptions, + getExternals, + loadFederationConfig, + setBuildAdapter, +} from '@softarc/native-federation/build'; import { createAngularBuildAdapter, setMemResultHandler, } from '../../utils/angular-esbuild-adapter'; -import { getExternals } from '@softarc/native-federation/build'; -import { loadFederationConfig } from '@softarc/native-federation/build'; -import { buildForFederation } from '@softarc/native-federation/build'; -import { targetFromTargetString } from '@angular-devkit/architect'; -import { NfBuilderSchema } from './schema'; -import { reloadBrowser, setError } from '../../utils/dev-server'; -import { RebuildHubs } from '../../utils/rebuild-events'; -import { updateScriptTags } from '../../utils/updateIndexHtml'; +import { JsonObject } from '@angular-devkit/core'; import { existsSync, mkdirSync, rmSync } from 'fs'; +import { reloadBrowser, setError } from '../../utils/dev-server'; import { EsBuildResult, MemResults, NgCliAssetResult, } from '../../utils/mem-resuts'; -import { JsonObject } from '@angular-devkit/core'; +import { RebuildHubs } from '../../utils/rebuild-events'; import { createSharedMappingsPlugin } from '../../utils/shared-mappings-plugin'; +import { updateScriptTags } from '../../utils/updateIndexHtml'; +import { NfBuilderSchema } from './schema'; // import { NextHandleFunction } from 'vite'; -import { PluginBuild } from 'esbuild'; import { FederationInfo } from '@softarc/native-federation-runtime'; -import { - getI18nConfig, - I18nConfig, - translateFederationArtefacts, -} from '../../utils/i18n'; +import { PluginBuild } from 'esbuild'; +import { checkAngularBuildApplicationBuilder } from '../../utils/check-builder'; +import { getI18nConfig, translateFederationArtefacts } from '../../utils/i18n'; function _buildApplication(options, context, pluginsOrExtensions) { let extensions; @@ -268,7 +267,9 @@ export async function* runBuilder( options.deleteOutputPath = false; - const appBuilderName = '@angular-devkit/build-angular:application'; + const appBuilderName = checkAngularBuildApplicationBuilder() + ? '@angular/build:application' + : '@angular-devkit/build-angular:application'; const builderRun = runServer ? serveWithVite( diff --git a/libs/native-federation/src/schematics/appbuilder/schematic.ts b/libs/native-federation/src/schematics/appbuilder/schematic.ts index 0379da0b..a0e8b363 100644 --- a/libs/native-federation/src/schematics/appbuilder/schematic.ts +++ b/libs/native-federation/src/schematics/appbuilder/schematic.ts @@ -3,6 +3,7 @@ import { Rule, Tree } from '@angular-devkit/schematics'; import { MfSchematicSchema } from './schema'; import * as path from 'path'; +import { checkAngularBuildApplicationBuilder } from '../../utils/check-builder'; type NormalizedOptions = { polyfills: string; @@ -41,7 +42,9 @@ function updateWorkspaceConfig( if (projectConfig.architect.esbuild) { projectConfig.architect.esbuild.builder = - '@angular-devkit/build-angular:application'; + checkAngularBuildApplicationBuilder() + ? '@angular/build:application' + : '@angular-devkit/build-angular:application'; projectConfig.architect.esbuild.options.browser = projectConfig.architect.esbuild.options.main; delete projectConfig.architect.esbuild.options.main; diff --git a/libs/native-federation/src/schematics/init/schematic.ts b/libs/native-federation/src/schematics/init/schematic.ts index deaf8e64..524b63ba 100644 --- a/libs/native-federation/src/schematics/init/schematic.ts +++ b/libs/native-federation/src/schematics/init/schematic.ts @@ -1,17 +1,17 @@ import { - chain, - Rule, - Tree, - url, apply, + chain, mergeWith, - template, move, noop, + Rule, + template, + Tree, + url, } from '@angular-devkit/schematics'; -import { NodePackageInstallTask } from '@angular-devkit/schematics/tasks'; import { strings } from '@angular-devkit/core'; +import { NodePackageInstallTask } from '@angular-devkit/schematics/tasks'; import { MfSchematicSchema } from './schema'; import { @@ -26,6 +26,7 @@ import { } from '@schematics/angular/utility/dependencies'; import * as path from 'path'; +import { checkAngularBuildApplicationBuilder } from '../../utils/check-builder'; const SSR_VERSION = '^2.0.10'; @@ -212,11 +213,16 @@ function updateWorkspaceConfig( const originalBuild = projectConfig.architect.build; - if (originalBuild.builder !== '@angular-devkit/build-angular:application') { + if ( + originalBuild.builder !== '@angular-devkit/build-angular:application' || + originalBuild.builder !== '@angular/build:application' + ) { console.log( 'Switching project to the application builder using esbuild ...' ); - originalBuild.builder = '@angular-devkit/build-angular:application'; + originalBuild.builder = checkAngularBuildApplicationBuilder() + ? '@angular/build:application' + : '@angular-devkit/build-angular:application'; delete originalBuild.configurations?.development?.buildOptimizer; delete originalBuild.configurations?.development?.vendorChunk; } @@ -502,7 +508,7 @@ function makeServerAsync( const cors = `import { createRequire } from "module"; const require = createRequire(import.meta.url); -const cors = require("cors"); +const cors = require("cors"); `; const mainContent = tree.read(server).toString('utf8'); const updatedContent = (cors + mainContent) @@ -531,7 +537,7 @@ console.log('Starting SSR for Shell'); remotesOrManifestUrl: '../browser/federation.manifest.json', relBundlePath: '../browser/', }); - + await import('./bootstrap-server'); })(); @@ -548,7 +554,7 @@ console.log('Starting SSR for Shell'); remotesOrManifestUrl: ${manifest}, relBundlePath: '../browser/', }); - + await import('./bootstrap-server'); })(); @@ -561,7 +567,7 @@ console.log('Starting SSR for Shell'); await initNodeFederation({ relBundlePath: '../browser/' }); - + await import('./bootstrap-server'); })(); diff --git a/libs/native-federation/src/utils/check-builder.ts b/libs/native-federation/src/utils/check-builder.ts new file mode 100644 index 00000000..436f3f6e --- /dev/null +++ b/libs/native-federation/src/utils/check-builder.ts @@ -0,0 +1,22 @@ +import { existsSync } from 'fs'; +import { resolve } from 'path'; + +/** + * Since Angular 16, the Angular CLI uses the new @angular/build package + * Currently the @angular/build package is not installed by default + * However in the next version of Angular (v20), it will replace the @angular-devkit/build-angular package + * + * This functions checks if the @angular/build package is installed to insure a compatibility with the next version of Angular + * and insure also that if people migrate on Angular 20 and don't change the builder, it will not break the compatibility with this package in v20 + * + * @returns true if the Angular build package is installed + */ +export const checkAngularBuildApplicationBuilder = () => { + const pathAngularBuildPackage = resolve( + process.cwd(), + 'node_modules', + '@angular/build' + ); + + return existsSync(pathAngularBuildPackage); +};