Skip to content

Commit f0e8ea3

Browse files
committed
feat(nf): update for Angular 18
1 parent c932c5e commit f0e8ea3

File tree

11 files changed

+186
-24
lines changed

11 files changed

+186
-24
lines changed

libs/native-federation/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ We will at least provide a new version of this package per Angular major. If nec
2424
- Use version 16.2.x for Angular 16.2.x
2525
- Use version 17.x for Angular 17.x
2626
- Use version 17.1.x for Angular 17.1+
27+
- Use version 18.x for Angular 18+
2728

2829
## Angular Integration
2930

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Update to Native Federation for Angular 18
2+
3+
The package ``@angular-architects/native-federation`` version 18 was successfully tested with Angular 18.
4+
5+
## Option 1
6+
7+
Just use ``ng update``:
8+
9+
```
10+
ng update @angular-architects/native-federation
11+
```
12+
13+
## Option 2
14+
15+
Use npm install:
16+
17+
```
18+
npm i @angular-architects/native-federation@^18
19+
```
20+
21+
Make sure you have the following ``postinstall`` script in your ``package.json``:
22+
23+
```json
24+
"scripts": {
25+
[...]
26+
"postinstall": "node node_modules/@angular-architects/native-federation/src/patch-angular-build.js"
27+
},
28+
```
29+
30+
Run the ``postinstall`` script once manually for initialization:
31+
32+
```
33+
npm run postinstall
34+
```
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"$schema": "../../node_modules/@angular-devkit/schematics/collection-schema.json",
3+
"name": "native-federation",
4+
"version": "0.0.1",
5+
"schematics": {
6+
"update18": {
7+
"version": "18",
8+
"factory": "./src/schematics/update18/schematic",
9+
"schema": "./src/schematics/update18/schema.json",
10+
"description": "migrating to v18"
11+
}
12+
}
13+
}

libs/native-federation/package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@angular-architects/native-federation",
3-
"version": "17.1.8",
3+
"version": "18.0.1",
44
"main": "src/index.js",
55
"generators": "./collection.json",
66
"builders": "./builders.json",
@@ -15,6 +15,9 @@
1515
"type": "git",
1616
"url": "https://github.com/angular-architects/module-federation-plugin"
1717
},
18+
"ng-update": {
19+
"migrations": "./migration-collection.json"
20+
},
1821
"dependencies": {
1922
"@babel/core": "^7.19.0",
2023
"@softarc/native-federation": "2.0.9",

libs/native-federation/project.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@
3434
"glob": "builders.json",
3535
"output": "."
3636
},
37+
{
38+
"input": "./libs/native-federation",
39+
"glob": "migration-collection.json",
40+
"output": "."
41+
},
3742
{
3843
"input": "./libs/native-federation",
3944
"glob": "executors.json",

libs/native-federation/src/builders/build/builder.ts

Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ import {
1111
createBuilder,
1212
} from '@angular-devkit/architect';
1313

14-
import { buildApplication } from '@angular-devkit/build-angular';
14+
import { buildApplication, buildApplicationInternal } from '@angular/build/src/builders/application';
15+
import { serveWithVite } from '@angular/build/src/builders/dev-server/vite-server';
1516

1617
import {
17-
executeDevServerBuilder,
1818
DevServerBuilderOptions,
1919
} from '@angular-devkit/build-angular';
2020
import { normalizeOptions } from '@angular-devkit/build-angular/src/builders/dev-server/options';
@@ -53,6 +53,19 @@ import { Connect } from 'vite';
5353
import { PluginBuild } from 'esbuild';
5454
import { FederationInfo } from '@softarc/native-federation-runtime';
5555

56+
function _buildApplication(options, context, pluginsOrExtensions) {
57+
let extensions;
58+
if (pluginsOrExtensions && Array.isArray(pluginsOrExtensions)) {
59+
extensions = {
60+
codePlugins: pluginsOrExtensions,
61+
};
62+
}
63+
else {
64+
extensions = pluginsOrExtensions;
65+
}
66+
return buildApplicationInternal(options, context, { write: false }, extensions);
67+
}
68+
5669
export async function* runBuilder(
5770
nfOptions: NfBuilderSchema,
5871
context: BuilderContext
@@ -217,20 +230,23 @@ export async function* runBuilder(
217230

218231
// TODO: Clarify how DevServer needs to be executed. Not sure if its right.
219232
// TODO: Clarify if buildApplication is needed `executeDevServerBuilder` seems to choose the correct DevServer
233+
234+
const appBuilderName = '@angular-devkit/build-angular:application';
235+
220236
const builderRun = nfOptions.dev
221-
? executeDevServerBuilder(
222-
options,
223-
context,
224-
{
225-
indexHtml: nfOptions.skipHtmlTransform
226-
? {}
227-
: { indexHtml: transformIndexHtml(nfOptions) },
228-
},
229-
{
230-
buildPlugins: plugins,
231-
middleware,
232-
}
233-
)
237+
? serveWithVite(
238+
normOuterOptions,
239+
appBuilderName,
240+
_buildApplication,
241+
context,
242+
nfOptions.skipHtmlTransform
243+
? {}
244+
: { indexHtml: transformIndexHtml(nfOptions) },
245+
{
246+
buildPlugins: plugins,
247+
middleware,
248+
}
249+
)
234250
: buildApplication(options, context, plugins);
235251

236252
// builderRun.output.subscribe(async (output) => {
@@ -259,13 +275,13 @@ export async function* runBuilder(
259275
updateIndexHtml(fedOptions, nfOptions);
260276
}
261277

262-
if (first && runServer) {
263-
startServer(nfOptions, fedOptions.outputPath, memResults);
264-
}
278+
// if (first && runServer) {
279+
// startServer(nfOptions, fedOptions.outputPath, memResults);
280+
// }
265281

266-
if (!first && runServer) {
267-
reloadBrowser();
268-
}
282+
// if (!first && runServer) {
283+
// reloadBrowser();
284+
// }
269285

270286
if (!runServer) {
271287
yield output;
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import { patchAngularBuild } from './utils/patch-angular-build';
2+
3+
const workspaceRoot = process.cwd();
4+
patchAngularBuild(workspaceRoot);

libs/native-federation/src/schematics/init/schematic.ts

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ import { NodePackageInstallTask } from '@angular-devkit/schematics/tasks';
1414
import { strings } from '@angular-devkit/core';
1515
import { MfSchematicSchema } from './schema';
1616

17+
import { patchAngularBuildPackageJson } from '../../utils/patch-angular-build';
18+
1719
import {
1820
addPackageJsonDependency,
1921
NodeDependencyType,
@@ -32,6 +34,32 @@ type NormalizedOptions = {
3234
port: number;
3335
};
3436

37+
export function updatePackageJson(tree: Tree): void {
38+
const packageJson = tree.readJson('package.json');
39+
40+
const scriptCall = 'node node_modules/@angular-architects/native-federation/src/patch-angular-build.js';
41+
42+
if (!packageJson['scripts']) {
43+
packageJson['scripts'] = {};
44+
}
45+
46+
let postInstall = (packageJson['scripts']?.['postinstall'] || '') as string;
47+
if (postInstall?.includes(scriptCall)) {
48+
return;
49+
}
50+
51+
if (postInstall) {
52+
postInstall += ' && ';
53+
}
54+
55+
postInstall += scriptCall;
56+
57+
packageJson['scripts']['postinstall'] = postInstall;
58+
59+
tree.overwrite('package.json', JSON.stringify(packageJson, null, 2));
60+
61+
}
62+
3563
export default function config(options: MfSchematicSchema): Rule {
3664
return async function (tree, context) {
3765
const workspaceFileName = getWorkspaceFileName(tree);
@@ -71,6 +99,10 @@ export default function config(options: MfSchematicSchema): Rule {
7199

72100
updateWorkspaceConfig(tree, normalized, workspace, workspaceFileName);
73101

102+
updatePackageJson(tree);
103+
104+
patchAngularBuild(tree);
105+
74106
addPackageJsonDependency(tree, {
75107
name: 'es-module-shims',
76108
type: NodeDependencyType.Default,
@@ -84,6 +116,12 @@ export default function config(options: MfSchematicSchema): Rule {
84116
};
85117
}
86118

119+
export function patchAngularBuild(tree) {
120+
const packageJson = JSON.parse(tree.read('node_modules/@angular/build/package.json'));
121+
patchAngularBuildPackageJson(packageJson);
122+
tree.overwrite('node_modules/@angular/build/package.json', JSON.stringify(packageJson, null, 2));
123+
}
124+
87125
function updateWorkspaceConfig(
88126
tree: Tree,
89127
options: NormalizedOptions,
@@ -217,7 +255,7 @@ function normalizeOptions(
217255
);
218256

219257
const manifestPath = path
220-
.join(projectRoot, 'src/assets/federation.manifest.json')
258+
.join(projectRoot, 'public/federation.manifest.json')
221259
.replace(/\\/g, '/');
222260

223261
const main =
@@ -316,7 +354,7 @@ function makeMainAsync(
316354
if (options.type === 'dynamic-host') {
317355
newMainContent = `import { initFederation } from '@angular-architects/native-federation';
318356
319-
initFederation('/assets/federation.manifest.json')
357+
initFederation('federation.manifest.json')
320358
.catch(err => console.error(err))
321359
.then(_ => import('./bootstrap'))
322360
.catch(err => console.error(err));
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"$schema": "http://json-schema.org/schema",
3+
"$id": "mf",
4+
"title": "",
5+
"type": "object",
6+
"properties": {
7+
}
8+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { Rule, Tree } from '@angular-devkit/schematics';
2+
3+
import { patchAngularBuild, updatePackageJson } from '../init/schematic';
4+
5+
export default function update18(): Rule {
6+
return async function (tree: Tree) {
7+
updatePackageJson(tree);
8+
patchAngularBuild(tree);
9+
};
10+
}

0 commit comments

Comments
 (0)