Skip to content

Commit 655a658

Browse files
committed
feat(nf): add hash to generated bundles
1 parent da7180d commit 655a658

File tree

3 files changed

+136
-121
lines changed

3 files changed

+136
-121
lines changed

libs/native-federation-core/src/lib/core/bundle-shared.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { FederationOptions } from './federation-options';
88
import { copySrcMapIfExists } from '../utils/copy-src-map-if-exists';
99
import { logger } from '../utils/logger';
1010
import { normalize } from '../utils/normalize';
11+
import crypto from 'crypto';
1112

1213
export async function bundleShared(
1314
config: NormalizedFederationConfig,
@@ -32,11 +33,24 @@ export async function bundleShared(
3233

3334
const allEntryPoints = packageInfos.map((pi) => {
3435
const encName = pi.packageName.replace(/[^A-Za-z0-9]/g, '_');
35-
const encVersion = pi.version.replace(/[^A-Za-z0-9]/g, '_');
36-
36+
// const encVersion = pi.version.replace(/[^A-Za-z0-9]/g, '_');
37+
38+
// const outName = fedOptions.dev
39+
// ? `${encName}-${encVersion}-dev.js`
40+
// : `${encName}-${encVersion}.js`;
41+
42+
const hashBase = pi.version + '_' + pi.entryPoint;
43+
const hash = crypto.createHash('sha256')
44+
.update(hashBase)
45+
.digest('base64')
46+
.replace(/\//g, '_')
47+
.replace(/\+/g, '-')
48+
.replace(/=/g, '')
49+
.substring(0,10);
50+
3751
const outName = fedOptions.dev
38-
? `${encName}-${encVersion}-dev.js`
39-
: `${encName}-${encVersion}.js`;
52+
? `${encName}.${hash}-dev.js`
53+
: `${encName}.${hash}.js`;
4054

4155
return { fileName: pi.entryPoint, outName };
4256
});

libs/native-federation/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ We will at least provide a new version of this package per Angular major. If nec
2929

3030
## Migration from Module Federation
3131

32-
If you currently use Angular with Module Federation, you can follow our Migration Guide to migrate to Native Federation and Angular's new fast esbuild-based build system.
32+
If you currently use Angular with Module Federation, you can follow our [Migration Guide](https://github.com/angular-architects/module-federation-plugin/blob/main/libs/native-federation/docs/migrate.md) to migrate to Native Federation and Angular's new fast esbuild-based build system.
3333

3434
## Updates
3535

libs/native-federation/docs/migrate.md

Lines changed: 117 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -12,154 +12,155 @@ Native Federation for Angular is a thin wrapper around the esbuild builder that
1212
- Update your solution to the newest version of `@angular-architects/module-federation` (!)
1313
- Have a look to our [FAQs about sharing packages with Native Federation](share-faq.md)
1414

15+
In general, you need Native Federation for Angular 18.1 and Module Federation 18.x.
16+
1517
## Migration for Angular CLI projects
1618

1719
1. Remove Module Federation from your poject(s):
1820

19-
```
20-
ng g @angular-architects/module-federation:remove --project xyz
21-
```
21+
```
22+
ng g @angular-architects/module-federation:remove --project xyz
23+
```
2224

2325
2. Update your workspace to the new esbuild-based build system:
2426

25-
```
26-
ng update @angular/cli --name use-application-builder
27-
```
27+
```
28+
ng update @angular/cli --name use-application-builder
29+
```
2830

2931
3. Initialize Native Federation for your projects:
3032

31-
```
32-
ng add @angular-architects/native-federation --project xyz --type remote --port 4201
33-
```
33+
```
34+
ng add @angular-architects/native-federation --project xyz --type remote --port 4201
35+
```
3436

35-
**Remarks:** Use type `remote` or type `dynamic-host`.
37+
**Remarks:** Use type `remote` or type `dynamic-host`.
3638

3739
4. Adjust your `federation.config.js` generated for Native Federation. You can mostly copy over the settings from your `webpack.config.js` used for Module Federation before.
3840

3941
5. Update your EcmaScript imports in your source code. Make sure, you import from `@angular-architects/native-federation` instead of from `@angular-architects/module-federation`. Please also note that the signature of `loadRemoteModule` has been simplified:
4042

41-
```typescript
42-
// Before
43-
import { loadRemoteModule } from '@angular-architects/module-federation';
44-
45-
[...]
46-
47-
export const APP_ROUTES: Routes = [
48-
[...]
49-
{
50-
path: 'booking',
51-
loadChildren: () =>
52-
loadRemoteModule({
53-
type: 'module',
54-
remoteEntry: 'http://localhost:4201/remoteEntry.js',
55-
exposedModule: './routes'
56-
})
57-
.then(m => m.MFE1_ROUTES)
58-
},
59-
[...]
60-
];
61-
```
62-
63-
```typescript
64-
// After
65-
import { loadRemoteModule } from '@angular-architects/native-federation';
66-
67-
[...]
68-
69-
export const APP_ROUTES: Routes = [
70-
[...]
71-
{
72-
path: 'flights',
73-
loadComponent: () => loadRemoteModule('mfe1', './Component')
74-
.then((m) => m.AppComponent),
75-
},
76-
[...]
77-
];
78-
```
79-
80-
Please also note that loadRemoteModule now always points to a logical name that is resolved via the shell's federation manifest (`src/assets/federation.manifest.json` or `public/federation.manifest.json`):
81-
82-
```json
83-
{
84-
"mfe1": "http://localhost:4201/remoteEntry.json"
85-
}
86-
```
87-
88-
Please also note that the remoteEntry is now a `.json` file.
43+
```typescript
44+
// Before
45+
import { loadRemoteModule } from '@angular-architects/module-federation';
46+
47+
[...]
48+
49+
export const APP_ROUTES: Routes = [
50+
[...]
51+
{
52+
path: 'booking',
53+
loadChildren: () =>
54+
loadRemoteModule({
55+
type: 'module',
56+
remoteEntry: 'http://localhost:4201/remoteEntry.js',
57+
exposedModule: './routes'
58+
})
59+
.then(m => m.MFE1_ROUTES)
60+
},
61+
[...]
62+
];
63+
```
64+
65+
```typescript
66+
// After
67+
import { loadRemoteModule } from '@angular-architects/native-federation';
68+
69+
[...]
70+
71+
export const APP_ROUTES: Routes = [
72+
[...]
73+
{
74+
path: 'flights',
75+
loadComponent: () => loadRemoteModule('mfe1', './Component')
76+
.then((m) => m.AppComponent),
77+
},
78+
[...]
79+
];
80+
```
81+
82+
Please also note that loadRemoteModule now always points to a logical name that is resolved via the shell's federation manifest (`src/assets/federation.manifest.json` or `public/federation.manifest.json`):
83+
84+
```json
85+
{
86+
"mfe1": "http://localhost:4201/remoteEntry.json"
87+
}
88+
```
89+
90+
Please also note that the remoteEntry is now a `.json` file.
8991

9092
6. If everything works, delete your `webpack.config.js`
9193

92-
9394
## Migration for Nx projects
9495

9596
1. Remove Module Federation from your poject(s):
9697

97-
```
98-
nx g @angular-architects/module-federation:remove --project xyz
99-
```
98+
```
99+
nx g @angular-architects/module-federation:remove --project xyz
100+
```
100101

101102
2. Initialize Native Federation for your projects:
102103

103-
```
104-
npm i @angular-architects/native-federation
104+
```
105+
npm i @angular-architects/native-federation
105106
106-
nx g @angular-architects/native-federation:init --project xyz --type remote --port 4201
107-
```
107+
nx g @angular-architects/native-federation:init --project xyz --type remote --port 4201
108+
```
108109

109-
**Remarks:** Use type `remote` or type `dynamic-host`.
110+
**Remarks:** Use type `remote` or type `dynamic-host`.
110111

111-
3. Adjust your federation.config.js generated for Native Federation. You can mostly copy over the settings from your `webpack.config.js` used for Module Federation before.
112+
3. Adjust your `federation.config.js` generated for Native Federation. You can mostly copy over the settings from your `webpack.config.js` used for Module Federation before.
112113

113114
4. Update your EcmaScript imports in your source code. Make sure, you import from `@angular-architects/native-federation` instead of from `@angular-architects/module-federation`. Please also note that the signature of `loadRemoteModule` has been simplified:
114115

115-
```typescript
116-
// Before
117-
import { loadRemoteModule } from '@angular-architects/module-federation';
118-
119-
[...]
120-
121-
export const APP_ROUTES: Routes = [
122-
[...]
123-
{
124-
path: 'booking',
125-
loadChildren: () =>
126-
loadRemoteModule({
127-
type: 'module',
128-
remoteEntry: 'http://localhost:4201/remoteEntry.js',
129-
exposedModule: './routes'
130-
})
131-
.then(m => m.MFE1_ROUTES)
132-
},
133-
[...]
134-
];
135-
```
136-
137-
```typescript
138-
// After
139-
import { loadRemoteModule } from '@angular-architects/native-federation';
140-
141-
[...]
142-
143-
export const APP_ROUTES: Routes = [
144-
[...]
145-
{
146-
path: 'flights',
147-
loadComponent: () => loadRemoteModule('mfe1', './Component')
148-
.then((m) => m.AppComponent),
149-
},
150-
[...]
151-
];
152-
```
153-
154-
Please also note that loadRemoteModule now always points to a logical name that is resolved via the shell's federation manifest (`src/assets/federation.manifest.json` or `public/federation.manifest.json`):
155-
156-
```json
157-
{
158-
"mfe1": "http://localhost:4201/remoteEntry.json"
159-
}
160-
```
161-
162-
Please also note that the remoteEntry is now a `.json` file.
116+
```typescript
117+
// Before
118+
import { loadRemoteModule } from '@angular-architects/module-federation';
119+
120+
[...]
121+
122+
export const APP_ROUTES: Routes = [
123+
[...]
124+
{
125+
path: 'booking',
126+
loadChildren: () =>
127+
loadRemoteModule({
128+
type: 'module',
129+
remoteEntry: 'http://localhost:4201/remoteEntry.js',
130+
exposedModule: './routes'
131+
})
132+
.then(m => m.MFE1_ROUTES)
133+
},
134+
[...]
135+
];
136+
```
137+
138+
```typescript
139+
// After
140+
import { loadRemoteModule } from '@angular-architects/native-federation';
141+
142+
[...]
143+
144+
export const APP_ROUTES: Routes = [
145+
[...]
146+
{
147+
path: 'flights',
148+
loadComponent: () => loadRemoteModule('mfe1', './Component')
149+
.then((m) => m.AppComponent),
150+
},
151+
[...]
152+
];
153+
```
154+
155+
Please also note that loadRemoteModule now always points to a logical name that is resolved via the shell's federation manifest (`src/assets/federation.manifest.json` or `public/federation.manifest.json`):
156+
157+
```json
158+
{
159+
"mfe1": "http://localhost:4201/remoteEntry.json"
160+
}
161+
```
162+
163+
Please also note that the remoteEntry is now a `.json` file.
163164

164165
5. If everything works, delete your `webpack.config.js`
165166

0 commit comments

Comments
 (0)