├── mfe1
├── src
│ ├── assets
│ │ ├── .gitkeep
│ │ ├── vite.svg
│ │ └── analog.svg
│ ├── vite-env.d.ts
│ ├── environments
│ │ ├── environment.prod.ts
│ │ └── environment.ts
│ ├── favicon.ico
│ ├── main.ts
│ ├── bootstrap.ts
│ ├── test.ts
│ ├── index.html
│ ├── app
│ │ ├── app.component.ts
│ │ └── app.component.spec.ts
│ ├── styles.css
│ └── polyfills.ts
├── .vscode
│ ├── extensions.json
│ ├── launch.json
│ └── tasks.json
├── .editorconfig
├── tsconfig.app.json
├── update.bat
├── tsconfig.spec.json
├── federation.config.cjs
├── angular.json
├── .browserslistrc
├── README.md
├── tsconfig.json
├── package.json
└── vite.config.ts
├── shell
├── src
│ ├── assets
│ │ ├── .gitkeep
│ │ ├── vite.svg
│ │ └── analog.svg
│ ├── vite-env.d.ts
│ ├── environments
│ │ ├── environment.prod.ts
│ │ └── environment.ts
│ ├── favicon.ico
│ ├── app
│ │ ├── home.component.ts
│ │ ├── app.routes.ts
│ │ ├── app.component.ts
│ │ └── app.component.spec.ts
│ ├── main.ts
│ ├── test.ts
│ ├── bootstrap.ts
│ ├── index.html
│ ├── styles.css
│ └── polyfills.ts
├── .vscode
│ ├── extensions.json
│ ├── launch.json
│ └── tasks.json
├── federation.config.cjs
├── tsconfig.app.json
├── update.bat
├── .editorconfig
├── tsconfig.spec.json
├── angular.json
├── .browserslistrc
├── README.md
├── tsconfig.json
├── package.json
└── vite.config.ts
├── .gitignore
├── shared
└── index.ts
├── example.png
└── readme.md
/mfe1/src/assets/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/shell/src/assets/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | dist
3 |
--------------------------------------------------------------------------------
/mfe1/src/vite-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/shared/index.ts:
--------------------------------------------------------------------------------
1 | export const shared = {
2 | userName: ''
3 | };
--------------------------------------------------------------------------------
/shell/src/vite-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/manfredsteyer/native-federation-vite-angular-demo/HEAD/example.png
--------------------------------------------------------------------------------
/mfe1/src/environments/environment.prod.ts:
--------------------------------------------------------------------------------
1 | export const environment = {
2 | production: true
3 | };
4 |
--------------------------------------------------------------------------------
/shell/src/environments/environment.prod.ts:
--------------------------------------------------------------------------------
1 | export const environment = {
2 | production: true
3 | };
4 |
--------------------------------------------------------------------------------
/mfe1/src/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/manfredsteyer/native-federation-vite-angular-demo/HEAD/mfe1/src/favicon.ico
--------------------------------------------------------------------------------
/shell/src/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/manfredsteyer/native-federation-vite-angular-demo/HEAD/shell/src/favicon.ico
--------------------------------------------------------------------------------
/mfe1/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=827846
3 | "recommendations": ["angular.ng-template"]
4 | }
5 |
--------------------------------------------------------------------------------
/shell/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=827846
3 | "recommendations": ["angular.ng-template"]
4 | }
5 |
--------------------------------------------------------------------------------
/mfe1/src/main.ts:
--------------------------------------------------------------------------------
1 | import { initFederation } from "@softarc/native-federation";
2 |
3 | (async () => {
4 |
5 | await initFederation();
6 | await import('./bootstrap');
7 |
8 | })();
--------------------------------------------------------------------------------
/shell/src/app/home.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 |
3 | @Component({
4 | standalone: true,
5 | selector: 'app-home',
6 | template: `
Welcome!
`,
7 | })
8 | export class HomeComponent {}
9 |
--------------------------------------------------------------------------------
/shell/src/main.ts:
--------------------------------------------------------------------------------
1 | import { initFederation } from "@softarc/native-federation";
2 |
3 | (async () => {
4 |
5 | await initFederation({
6 | 'mfe1': 'http://localhost:3001/remoteEntry.json'
7 | });
8 |
9 | await import('./bootstrap');
10 |
11 | })();
--------------------------------------------------------------------------------
/shell/federation.config.cjs:
--------------------------------------------------------------------------------
1 | const {
2 | withNativeFederation,
3 | shareAll,
4 | } = require("@softarc/native-federation/build");
5 |
6 | module.exports = withNativeFederation({
7 | name: "host",
8 |
9 | shared: {
10 | ...shareAll({ singleton: true, strictVersion: true, requiredVersion: "auto", }),
11 | },
12 |
13 | });
14 |
--------------------------------------------------------------------------------
/mfe1/src/bootstrap.ts:
--------------------------------------------------------------------------------
1 | import './polyfills';
2 | import { enableProdMode } from '@angular/core';
3 | import { bootstrapApplication } from '@angular/platform-browser';
4 |
5 | import { AppComponent } from './app/app.component';
6 |
7 | if (import.meta.env.PROD) {
8 | enableProdMode();
9 | }
10 |
11 | bootstrapApplication(AppComponent);
12 |
--------------------------------------------------------------------------------
/mfe1/.editorconfig:
--------------------------------------------------------------------------------
1 | # Editor configuration, see https://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | charset = utf-8
6 | indent_style = space
7 | indent_size = 2
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
11 | [*.ts]
12 | quote_type = single
13 |
14 | [*.md]
15 | max_line_length = off
16 | trim_trailing_whitespace = false
17 |
--------------------------------------------------------------------------------
/mfe1/tsconfig.app.json:
--------------------------------------------------------------------------------
1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */
2 | {
3 | "extends": "./tsconfig.json",
4 | "compilerOptions": {
5 | "composite": false,
6 | "outDir": "./out-tsc/app",
7 | "types": []
8 | },
9 | "files": ["src/main.ts", "src/polyfills.ts"],
10 | "include": ["src/**/*.d.ts"]
11 | }
12 |
--------------------------------------------------------------------------------
/shell/tsconfig.app.json:
--------------------------------------------------------------------------------
1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */
2 | {
3 | "extends": "./tsconfig.json",
4 | "compilerOptions": {
5 | "composite": false,
6 | "outDir": "./out-tsc/app",
7 | "types": []
8 | },
9 | "files": ["src/main.ts", "src/polyfills.ts"],
10 | "include": ["src/**/*.d.ts"]
11 | }
12 |
--------------------------------------------------------------------------------
/shell/update.bat:
--------------------------------------------------------------------------------
1 | call npm i @softarc/native-federation@latest --registry http://localhost:4873
2 | call npm i @softarc/native-federation-runtime@latest --registry http://localhost:4873
3 | call npm i @softarc/native-federation-esbuild@latest --registry http://localhost:4873
4 | call npm i @angular-architects/native-federation@latest --registry http://localhost:4873
5 |
--------------------------------------------------------------------------------
/shell/.editorconfig:
--------------------------------------------------------------------------------
1 | # Editor configuration, see https://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | charset = utf-8
6 | indent_style = space
7 | indent_size = 2
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
11 | [*.ts]
12 | quote_type = single
13 |
14 | [*.md]
15 | max_line_length = off
16 | trim_trailing_whitespace = false
17 |
--------------------------------------------------------------------------------
/mfe1/update.bat:
--------------------------------------------------------------------------------
1 | call npm i @softarc/native-federation@latest --registry http://localhost:4873 -f
2 | call npm i @softarc/native-federation-runtime@latest --registry http://localhost:4873 -f
3 | call npm i @softarc/native-federation-esbuild@latest --registry http://localhost:4873 -f
4 | call npm i @angular-architects/native-federation@latest --registry http://localhost:4873 -f
5 |
6 |
--------------------------------------------------------------------------------
/mfe1/src/test.ts:
--------------------------------------------------------------------------------
1 | import '@analogjs/vite-plugin-angular/setup-vitest';
2 |
3 | import {
4 | BrowserDynamicTestingModule,
5 | platformBrowserDynamicTesting,
6 | } from '@angular/platform-browser-dynamic/testing';
7 | import { getTestBed } from '@angular/core/testing';
8 |
9 | getTestBed().initTestEnvironment(
10 | BrowserDynamicTestingModule,
11 | platformBrowserDynamicTesting()
12 | );
13 |
--------------------------------------------------------------------------------
/mfe1/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */
2 | {
3 | "extends": "./tsconfig.json",
4 | "compilerOptions": {
5 | "composite": false,
6 | "outDir": "./out-tsc/spec",
7 | "types": ["node", "vitest/globals"]
8 | },
9 | "files": ["src/test.ts", "src/polyfills.ts"],
10 | "include": ["src/**/*.spec.ts", "src/**/*.ts"]
11 | }
12 |
--------------------------------------------------------------------------------
/shell/src/test.ts:
--------------------------------------------------------------------------------
1 | import '@analogjs/vite-plugin-angular/setup-vitest';
2 |
3 | import {
4 | BrowserDynamicTestingModule,
5 | platformBrowserDynamicTesting,
6 | } from '@angular/platform-browser-dynamic/testing';
7 | import { getTestBed } from '@angular/core/testing';
8 |
9 | getTestBed().initTestEnvironment(
10 | BrowserDynamicTestingModule,
11 | platformBrowserDynamicTesting()
12 | );
13 |
--------------------------------------------------------------------------------
/shell/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */
2 | {
3 | "extends": "./tsconfig.json",
4 | "compilerOptions": {
5 | "composite": false,
6 | "outDir": "./out-tsc/spec",
7 | "types": ["node", "vitest/globals"]
8 | },
9 | "files": ["src/test.ts", "src/polyfills.ts"],
10 | "include": ["src/**/*.spec.ts", "src/**/*.ts"]
11 | }
12 |
--------------------------------------------------------------------------------
/mfe1/federation.config.cjs:
--------------------------------------------------------------------------------
1 | const {
2 | withNativeFederation,
3 | shareAll,
4 | } = require("@softarc/native-federation/build");
5 |
6 | module.exports = withNativeFederation({
7 | name: "host",
8 |
9 | exposes: {
10 | "./comp": "src/app/app.component.ts"
11 | },
12 |
13 | shared: {
14 | ...shareAll({ singleton: true, strictVersion: true, requiredVersion: "auto", }),
15 | },
16 |
17 | });
18 |
--------------------------------------------------------------------------------
/mfe1/angular.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
3 | "version": 1,
4 | "newProjectRoot": "projects",
5 | "projects": {
6 | "my-app": {
7 | "projectType": "application",
8 | "schematics": {},
9 | "root": "",
10 | "sourceRoot": "src",
11 | "prefix": "app",
12 | "architect": {
13 | "targets": {}
14 | }
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/shell/angular.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
3 | "version": 1,
4 | "newProjectRoot": "projects",
5 | "projects": {
6 | "my-app": {
7 | "projectType": "application",
8 | "schematics": {},
9 | "root": "",
10 | "sourceRoot": "src",
11 | "prefix": "app",
12 | "architect": {
13 | "targets": {}
14 | }
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/shell/src/bootstrap.ts:
--------------------------------------------------------------------------------
1 | import './polyfills';
2 | import { enableProdMode } from '@angular/core';
3 | import { bootstrapApplication } from '@angular/platform-browser';
4 |
5 | import { AppComponent } from './app/app.component';
6 | import { provideRouter } from '@angular/router';
7 | import { APP_ROUTES } from './app/app.routes';
8 |
9 | if (import.meta.env.PROD) {
10 | enableProdMode();
11 | }
12 |
13 | bootstrapApplication(AppComponent, {
14 | providers: [
15 | provideRouter(APP_ROUTES,)
16 | ]
17 | });
18 |
--------------------------------------------------------------------------------
/mfe1/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
3 | "version": "0.2.0",
4 | "configurations": [
5 | {
6 | "name": "ng serve",
7 | "type": "pwa-chrome",
8 | "request": "launch",
9 | "preLaunchTask": "npm: start",
10 | "url": "http://localhost:4200/"
11 | },
12 | {
13 | "name": "ng test",
14 | "type": "chrome",
15 | "request": "launch",
16 | "preLaunchTask": "npm: test",
17 | "url": "http://localhost:9876/debug.html"
18 | }
19 | ]
20 | }
21 |
--------------------------------------------------------------------------------
/shell/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
3 | "version": "0.2.0",
4 | "configurations": [
5 | {
6 | "name": "ng serve",
7 | "type": "pwa-chrome",
8 | "request": "launch",
9 | "preLaunchTask": "npm: start",
10 | "url": "http://localhost:4200/"
11 | },
12 | {
13 | "name": "ng test",
14 | "type": "chrome",
15 | "request": "launch",
16 | "preLaunchTask": "npm: test",
17 | "url": "http://localhost:9876/debug.html"
18 | }
19 | ]
20 | }
21 |
--------------------------------------------------------------------------------
/shell/src/app/app.routes.ts:
--------------------------------------------------------------------------------
1 | import { Routes } from '@angular/router';
2 | import { loadRemoteModule } from '@softarc/native-federation-runtime';
3 | import { HomeComponent } from './home.component';
4 |
5 | export const APP_ROUTES: Routes = [
6 | {
7 | path: '',
8 | pathMatch: 'full',
9 | redirectTo: 'home',
10 | },
11 | {
12 | path: 'home',
13 | component: HomeComponent,
14 | },
15 | {
16 | path: 'mfe1',
17 | loadComponent: () =>
18 | loadRemoteModule({
19 | remoteName: 'mfe1',
20 | exposedModule: './comp',
21 | }).then((esm) => esm.AppComponent),
22 | },
23 | ];
24 |
--------------------------------------------------------------------------------
/mfe1/.browserslistrc:
--------------------------------------------------------------------------------
1 | # This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
2 | # For additional information regarding the format and rule options, please see:
3 | # https://github.com/browserslist/browserslist#queries
4 |
5 | # For the full list of supported browsers by the Angular framework, please see:
6 | # https://angular.io/guide/browser-support
7 |
8 | # You can see what browsers were selected by your queries by running:
9 | # npx browserslist
10 |
11 | last 1 Chrome version
12 | last 1 Firefox version
13 | last 2 Edge major versions
14 | last 2 Safari major versions
15 | last 2 iOS major versions
16 | Firefox ESR
17 |
--------------------------------------------------------------------------------
/shell/.browserslistrc:
--------------------------------------------------------------------------------
1 | # This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
2 | # For additional information regarding the format and rule options, please see:
3 | # https://github.com/browserslist/browserslist#queries
4 |
5 | # For the full list of supported browsers by the Angular framework, please see:
6 | # https://angular.io/guide/browser-support
7 |
8 | # You can see what browsers were selected by your queries by running:
9 | # npx browserslist
10 |
11 | last 1 Chrome version
12 | last 1 Firefox version
13 | last 2 Edge major versions
14 | last 2 Safari major versions
15 | last 2 iOS major versions
16 | Firefox ESR
17 |
--------------------------------------------------------------------------------
/mfe1/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | MFE1
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/shell/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Shell
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/mfe1/src/environments/environment.ts:
--------------------------------------------------------------------------------
1 | // This file can be replaced during build by using the `fileReplacements` array.
2 | // `ng build` replaces `environment.ts` with `environment.prod.ts`.
3 | // The list of file replacements can be found in `angular.json`.
4 |
5 | export const environment = {
6 | production: false
7 | };
8 |
9 | /*
10 | * For easier debugging in development mode, you can import the following file
11 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`.
12 | *
13 | * This import should be commented out in production mode because it will have a negative impact
14 | * on performance if an error is thrown.
15 | */
16 | // import 'zone.js/plugins/zone-error'; // Included with Angular CLI.
17 |
--------------------------------------------------------------------------------
/shell/src/environments/environment.ts:
--------------------------------------------------------------------------------
1 | // This file can be replaced during build by using the `fileReplacements` array.
2 | // `ng build` replaces `environment.ts` with `environment.prod.ts`.
3 | // The list of file replacements can be found in `angular.json`.
4 |
5 | export const environment = {
6 | production: false
7 | };
8 |
9 | /*
10 | * For easier debugging in development mode, you can import the following file
11 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`.
12 | *
13 | * This import should be commented out in production mode because it will have a negative impact
14 | * on performance if an error is thrown.
15 | */
16 | // import 'zone.js/plugins/zone-error'; // Included with Angular CLI.
17 |
--------------------------------------------------------------------------------
/mfe1/README.md:
--------------------------------------------------------------------------------
1 | # Analog App
2 |
3 | This project was generated with [Analog](https://npmjs.com/package/create-analog).
4 |
5 | ## Setup
6 |
7 | Run `yarn` to install the application dependencies.
8 |
9 | ## Development
10 |
11 | Run `yarn dev` for a dev server. Navigate to `http://localhost:5173/`. The application will automatically reload if you change any of the source files.
12 |
13 | ## Build
14 |
15 | Run `yarn build` to build the project. The build artifacts will be stored in the `dist/` directory.
16 |
17 | ## Test
18 |
19 | Run `yarn test` to run unit tests with [Vitest](https://vitest.dev).
20 |
21 | ## Community
22 |
23 | - Join the [Discord](https://discord.gg/mKC2Ec48U5)
24 | - Visit and Star the [GitHub Repo](https://github.com/analogjs/analog)
25 | - Visit the [Website](https://analogjs.org/)
26 | - Follow us on [Twitter](https://twitter.com/analogjs)
27 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # Example: Micro Frontends with Native Federation + vite + Angular powered by AnalogJS
2 |
3 | The section between the dashed lines is a separately compiled and deployed Micro Frontend:
4 |
5 | 
6 |
7 | ## Install and Run
8 |
9 | Repeat this for both, the ``shell`` and the ``mfe1`` folder:
10 |
11 | ```
12 | npm i
13 | npm run dev
14 | ```
15 |
16 | ## Inspect the Examples
17 |
18 | - ``vite.config.ts``: Here, the federation-vite-plugin is used and the dev server is configured to allow access to the ``shared`` folder
19 | - ``federation.config``: Native Federation config
20 | - ``index.html``: Here, the polyfill for Import Maps is registered
21 | - ``main.ts``: Initializes Native Federation and then (!) imports ``bootstrap.ts`` for starting the application
22 |
--------------------------------------------------------------------------------
/shell/README.md:
--------------------------------------------------------------------------------
1 | # Analog App
2 |
3 | This project was generated with [Analog](https://npmjs.com/package/create-analog).
4 |
5 | ## Setup
6 |
7 | Run `yarn` to install the application dependencies.
8 |
9 | ## Development
10 |
11 | Run `yarn dev` for a dev server. Navigate to `http://localhost:5173/`. The application will automatically reload if you change any of the source files.
12 |
13 | ## Build
14 |
15 | Run `yarn build` to build the project. The build artifacts will be stored in the `dist/` directory.
16 |
17 | ## Test
18 |
19 | Run `yarn test` to run unit tests with [Vitest](https://vitest.dev).
20 |
21 | ## Community
22 |
23 | - Join the [Discord](https://discord.gg/mKC2Ec48U5)
24 | - Visit and Star the [GitHub Repo](https://github.com/analogjs/analog)
25 | - Visit the [Website](https://analogjs.org/)
26 | - Follow us on [Twitter](https://twitter.com/analogjs)
27 |
--------------------------------------------------------------------------------
/mfe1/src/app/app.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 | import { shared } from 'shared';
3 |
4 | @Component({
5 | selector: 'app-root',
6 | standalone: true,
7 | template: `
8 |
9 |
Flights
10 |
11 |
12 |
13 | `,
14 | styles: [
15 | `
16 | .mfe {
17 | border: 2px darkred dashed;
18 | padding: 20px;
19 | }
20 |
21 | input[type='text'] {
22 | width: 300px;
23 | }
24 |
25 | button, input[type='text'] {
26 | border-radius: 5px;
27 | border: black 1px solid;
28 | padding: 8px 5px;
29 | margin: 8px 0;
30 | margin-right:10px;
31 | box-sizing: border-box;
32 | }
33 | `,
34 | ],
35 | })
36 | export class AppComponent {
37 | constructor() {
38 | console.log('mfe1:user name', shared.userName)
39 | }
40 | search() {
41 | alert('Not implemented for this demo.');
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/shell/src/app/app.component.ts:
--------------------------------------------------------------------------------
1 | import { CommonModule } from '@angular/common';
2 | import { Component } from '@angular/core';
3 | import { RouterLinkWithHref, RouterOutlet } from '@angular/router';
4 | import { HomeComponent } from './home.component';
5 | import { shared } from 'shared';
6 |
7 | @Component({
8 | selector: 'app-root',
9 | standalone: true,
10 | imports: [
11 | HomeComponent,
12 | CommonModule,
13 | RouterLinkWithHref,
14 | RouterOutlet
15 | ],
16 | template: `
17 |
21 |
22 |
23 |
24 | `,
25 | styles: [`
26 |
27 | .menu {
28 | background-color: black;
29 | padding:20px;
30 | }
31 |
32 | .menu a {
33 | color: white;
34 | font-size: 18px;
35 | margin-right: 20px;
36 | }
37 |
38 | main {
39 | padding: 20px;
40 | }
41 | `]
42 | })
43 | export class AppComponent {
44 | constructor() {
45 | shared.userName = 'Jane Doe';
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/mfe1/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | // For more information, visit: https://go.microsoft.com/fwlink/?LinkId=733558
3 | "version": "2.0.0",
4 | "tasks": [
5 | {
6 | "type": "npm",
7 | "script": "start",
8 | "isBackground": true,
9 | "problemMatcher": {
10 | "owner": "typescript",
11 | "pattern": "$tsc",
12 | "background": {
13 | "activeOnStart": true,
14 | "beginsPattern": {
15 | "regexp": "(.*?)"
16 | },
17 | "endsPattern": {
18 | "regexp": "bundle generation complete"
19 | }
20 | }
21 | }
22 | },
23 | {
24 | "type": "npm",
25 | "script": "test",
26 | "isBackground": true,
27 | "problemMatcher": {
28 | "owner": "typescript",
29 | "pattern": "$tsc",
30 | "background": {
31 | "activeOnStart": true,
32 | "beginsPattern": {
33 | "regexp": "(.*?)"
34 | },
35 | "endsPattern": {
36 | "regexp": "bundle generation complete"
37 | }
38 | }
39 | }
40 | }
41 | ]
42 | }
43 |
--------------------------------------------------------------------------------
/shell/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | // For more information, visit: https://go.microsoft.com/fwlink/?LinkId=733558
3 | "version": "2.0.0",
4 | "tasks": [
5 | {
6 | "type": "npm",
7 | "script": "start",
8 | "isBackground": true,
9 | "problemMatcher": {
10 | "owner": "typescript",
11 | "pattern": "$tsc",
12 | "background": {
13 | "activeOnStart": true,
14 | "beginsPattern": {
15 | "regexp": "(.*?)"
16 | },
17 | "endsPattern": {
18 | "regexp": "bundle generation complete"
19 | }
20 | }
21 | }
22 | },
23 | {
24 | "type": "npm",
25 | "script": "test",
26 | "isBackground": true,
27 | "problemMatcher": {
28 | "owner": "typescript",
29 | "pattern": "$tsc",
30 | "background": {
31 | "activeOnStart": true,
32 | "beginsPattern": {
33 | "regexp": "(.*?)"
34 | },
35 | "endsPattern": {
36 | "regexp": "bundle generation complete"
37 | }
38 | }
39 | }
40 | }
41 | ]
42 | }
43 |
--------------------------------------------------------------------------------
/mfe1/tsconfig.json:
--------------------------------------------------------------------------------
1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */
2 | {
3 | "compileOnSave": false,
4 | "compilerOptions": {
5 | "baseUrl": "./",
6 | "outDir": "./dist/out-tsc",
7 | "forceConsistentCasingInFileNames": true,
8 | "strict": true,
9 | "noImplicitOverride": true,
10 | "noPropertyAccessFromIndexSignature": true,
11 | "noImplicitReturns": true,
12 | "noFallthroughCasesInSwitch": true,
13 | "sourceMap": true,
14 | "declaration": false,
15 | "downlevelIteration": true,
16 | "experimentalDecorators": true,
17 | "moduleResolution": "node",
18 | "importHelpers": true,
19 | "target": "es2020",
20 | "module": "es2020",
21 | "lib": ["es2020", "dom"],
22 | "paths": {
23 | "shared": ["../shared/index.ts"]
24 | }
25 | },
26 | "angularCompilerOptions": {
27 | "enableI18nLegacyMessageIdFormat": false,
28 | "strictInjectionParameters": true,
29 | "strictInputAccessModifiers": true,
30 | "strictTemplates": true
31 | },
32 | "references": [
33 | { "path": "tsconfig.app.json" },
34 | { "path": "tsconfig.spec.json" }
35 | ]
36 | }
37 |
--------------------------------------------------------------------------------
/shell/tsconfig.json:
--------------------------------------------------------------------------------
1 | /* To learn more about this file see: https://angular.io/config/tsconfig. */
2 | {
3 | "compileOnSave": false,
4 | "compilerOptions": {
5 | "baseUrl": "./",
6 | "outDir": "./dist/out-tsc",
7 | "forceConsistentCasingInFileNames": true,
8 | "strict": true,
9 | "noImplicitOverride": true,
10 | "noPropertyAccessFromIndexSignature": true,
11 | "noImplicitReturns": true,
12 | "noFallthroughCasesInSwitch": true,
13 | "sourceMap": true,
14 | "declaration": false,
15 | "downlevelIteration": true,
16 | "experimentalDecorators": true,
17 | "moduleResolution": "node",
18 | "importHelpers": true,
19 | "target": "es2020",
20 | "module": "es2020",
21 | "lib": ["es2020", "dom"],
22 | "paths": {
23 | "shared": ["../shared/index.ts"]
24 | }
25 | },
26 | "angularCompilerOptions": {
27 | "enableI18nLegacyMessageIdFormat": false,
28 | "strictInjectionParameters": true,
29 | "strictInputAccessModifiers": true,
30 | "strictTemplates": true
31 | },
32 | "references": [
33 | { "path": "tsconfig.app.json" },
34 | { "path": "tsconfig.spec.json" }
35 | ]
36 | }
37 |
--------------------------------------------------------------------------------
/mfe1/src/app/app.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { TestBed } from '@angular/core/testing';
2 | import { RouterTestingModule } from '@angular/router/testing';
3 | import { AppComponent } from './app.component';
4 |
5 | describe('AppComponent', () => {
6 | beforeEach(async () => {
7 | await TestBed.configureTestingModule({
8 | imports: [
9 | RouterTestingModule,
10 | AppComponent
11 | ]
12 | }).compileComponents();
13 | });
14 |
15 | it('should create the app', () => {
16 | const fixture = TestBed.createComponent(AppComponent);
17 | const app = fixture.componentInstance;
18 | expect(app).toBeTruthy();
19 | });
20 |
21 | it(`should have an initial count of 0`, () => {
22 | const fixture = TestBed.createComponent(AppComponent);
23 | const app = fixture.componentInstance;
24 | expect(app.count).toEqual(0);
25 | });
26 |
27 | it('should render title', () => {
28 | const fixture = TestBed.createComponent(AppComponent);
29 | fixture.detectChanges();
30 | const compiled = fixture.nativeElement as HTMLElement;
31 | expect(compiled.querySelector('h1')?.textContent).toContain('Vite + Angular');
32 | });
33 | });
34 |
--------------------------------------------------------------------------------
/shell/src/app/app.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { TestBed } from '@angular/core/testing';
2 | import { RouterTestingModule } from '@angular/router/testing';
3 | import { AppComponent } from './app.component';
4 |
5 | describe('AppComponent', () => {
6 | beforeEach(async () => {
7 | await TestBed.configureTestingModule({
8 | imports: [
9 | RouterTestingModule,
10 | AppComponent
11 | ]
12 | }).compileComponents();
13 | });
14 |
15 | it('should create the app', () => {
16 | const fixture = TestBed.createComponent(AppComponent);
17 | const app = fixture.componentInstance;
18 | expect(app).toBeTruthy();
19 | });
20 |
21 | it(`should have an initial count of 0`, () => {
22 | const fixture = TestBed.createComponent(AppComponent);
23 | const app = fixture.componentInstance;
24 | expect(app.count).toEqual(0);
25 | });
26 |
27 | it('should render title', () => {
28 | const fixture = TestBed.createComponent(AppComponent);
29 | fixture.detectChanges();
30 | const compiled = fixture.nativeElement as HTMLElement;
31 | expect(compiled.querySelector('h1')?.textContent).toContain('Vite + Angular');
32 | });
33 | });
34 |
--------------------------------------------------------------------------------
/shell/src/styles.css:
--------------------------------------------------------------------------------
1 | /* You can add global styles to this file, and also import other style files */
2 | /* You can add global styles to this file, and also import other style files */
3 | :root {
4 | font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
5 | font-size: 16px;
6 | line-height: 24px;
7 | font-weight: 400;
8 |
9 | color-scheme: light dark;
10 | color: rgba(255, 255, 255, 0.87);
11 | background-color: #242424;
12 |
13 | font-synthesis: none;
14 | text-rendering: optimizeLegibility;
15 | -webkit-font-smoothing: antialiased;
16 | -moz-osx-font-smoothing: grayscale;
17 | -webkit-text-size-adjust: 100%;
18 | }
19 |
20 | a {
21 | font-weight: 500;
22 | color: #646cff;
23 | text-decoration: inherit;
24 | }
25 | a:hover {
26 | color: #535bf2;
27 | }
28 |
29 | body {
30 | margin: 0;
31 | padding:0px;
32 | }
33 |
34 | h1 {
35 | font-size: 3.2em;
36 | line-height: 1.1;
37 | }
38 |
39 | .card {
40 | padding: 2em;
41 | }
42 |
43 | @media (prefers-color-scheme: light) {
44 | :root {
45 | color: #213547;
46 | background-color: #ffffff;
47 | }
48 | a:hover {
49 | color: #747bff;
50 | }
51 | button {
52 | background-color: #f9f9f9;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/mfe1/src/styles.css:
--------------------------------------------------------------------------------
1 | /* You can add global styles to this file, and also import other style files */
2 | /* You can add global styles to this file, and also import other style files */
3 | :root {
4 | font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
5 | font-size: 16px;
6 | line-height: 24px;
7 | font-weight: 400;
8 |
9 | color-scheme: light dark;
10 | color: rgba(255, 255, 255, 0.87);
11 | background-color: #242424;
12 |
13 | font-synthesis: none;
14 | text-rendering: optimizeLegibility;
15 | -webkit-font-smoothing: antialiased;
16 | -moz-osx-font-smoothing: grayscale;
17 | -webkit-text-size-adjust: 100%;
18 | }
19 |
20 | a {
21 | font-weight: 500;
22 | color: #646cff;
23 | text-decoration: inherit;
24 | }
25 | a:hover {
26 | color: #535bf2;
27 | }
28 |
29 | body {
30 | margin: 0;
31 | /* display: flex;
32 | place-items: center; */
33 | padding:20px;
34 | /* min-width: 320px;
35 | min-height: 100vh; */
36 | }
37 |
38 | h1 {
39 | font-size: 3.2em;
40 | line-height: 1.1;
41 | }
42 |
43 |
44 |
45 | .card {
46 | padding: 2em;
47 | }
48 |
49 | @media (prefers-color-scheme: light) {
50 | :root {
51 | color: #213547;
52 | background-color: #ffffff;
53 | }
54 | a:hover {
55 | color: #747bff;
56 | }
57 | button {
58 | background-color: #f9f9f9;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/mfe1/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "mfe1",
3 | "version": "0.0.0",
4 | "private": true,
5 | "engines": {
6 | "node": ">=16.0.0"
7 | },
8 | "scripts": {
9 | "dev": "vite",
10 | "ng": "ng",
11 | "start": "npm run dev",
12 | "build": "vite build",
13 | "watch": "vite build --watch",
14 | "test": "vitest",
15 | "postinstall": "vite optimize"
16 | },
17 | "dependencies": {
18 | "@angular/animations": "^14.0.0",
19 | "@angular/common": "^14.0.0",
20 | "@angular/compiler": "^14.0.0",
21 | "@angular/core": "^14.0.0",
22 | "@angular/forms": "^14.0.0",
23 | "@angular/platform-browser": "^14.0.0",
24 | "@angular/platform-browser-dynamic": "^14.0.0",
25 | "@angular/router": "^14.0.0",
26 | "@softarc/native-federation": "^1.0.0",
27 | "@softarc/native-federation-runtime": "^1.0.0",
28 | "rxjs": "~7.5.6",
29 | "tslib": "^2.4.0",
30 | "zone.js": "~0.11.8"
31 | },
32 | "devDependencies": {
33 | "@analogjs/vite-plugin-angular": "latest",
34 | "@angular-architects/native-federation": "^1.0.0-beta.1",
35 | "@angular-devkit/build-angular": "^14.0.3",
36 | "@angular/cli": "~14.0.3",
37 | "@angular/compiler-cli": "^14.0.0",
38 | "@gioboa/vite-module-federation": "^0.2.3",
39 | "@softarc/native-federation-esbuild": "^1.0.0",
40 | "jsdom": "^20.0.0",
41 | "typescript": "~4.7.4",
42 | "vite": "^3.0.9",
43 | "vitest": "^0.22.1"
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/shell/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "shell",
3 | "version": "0.0.0",
4 | "private": true,
5 | "engines": {
6 | "node": ">=16.0.0"
7 | },
8 | "scripts": {
9 | "dev": "vite",
10 | "ng": "ng",
11 | "start": "npm run dev",
12 | "build": "vite build",
13 | "watch": "vite build --watch",
14 | "test": "vitest",
15 | "postinstall": "vite optimize"
16 | },
17 | "dependencies": {
18 | "@angular-architects/native-federation": "^1.0.0-beta.1",
19 | "@angular/animations": "^14.0.0",
20 | "@angular/common": "^14.0.0",
21 | "@angular/compiler": "^14.0.0",
22 | "@angular/core": "^14.0.0",
23 | "@angular/forms": "^14.0.0",
24 | "@angular/platform-browser": "^14.0.0",
25 | "@angular/platform-browser-dynamic": "^14.0.0",
26 | "@angular/router": "^14.0.0",
27 | "@softarc/native-federation": "^1.0.0",
28 | "@softarc/native-federation-esbuild": "^1.0.0",
29 | "@softarc/native-federation-runtime": "^1.0.0",
30 | "rxjs": "~7.5.6",
31 | "tslib": "^2.4.0",
32 | "zone.js": "~0.11.8"
33 | },
34 | "devDependencies": {
35 | "@analogjs/vite-plugin-angular": "latest",
36 | "@angular-devkit/build-angular": "^14.0.3",
37 | "@angular/cli": "~14.0.3",
38 | "@angular/compiler-cli": "^14.0.0",
39 | "@gioboa/vite-module-federation": "^0.2.3",
40 | "jsdom": "^20.0.0",
41 | "typescript": "~4.7.4",
42 | "vite": "^3.0.9",
43 | "vitest": "^0.22.1"
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/mfe1/src/assets/vite.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/shell/src/assets/vite.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/mfe1/vite.config.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
3 | import { defineConfig } from 'vite';
4 | import angular from '@analogjs/vite-plugin-angular';
5 | import { federation } from '@gioboa/vite-module-federation';
6 | import { AngularEsBuildAdapter } from '@angular-architects/native-federation/src/utils/angular-esbuild-adapter';
7 |
8 | // https://vitejs.dev/config/
9 | export default defineConfig(({ mode, command }) => ({
10 | root: 'src',
11 | publicDir: 'assets',
12 | server: {
13 | port: 3001,
14 | open: true,
15 | fs: {
16 | // Allowing access to both, project
17 | // and shared folder in dev mode
18 | allow: [
19 | '.',
20 | '../../shared'
21 | ]
22 | }
23 | },
24 | preview: {
25 | port: 3001,
26 | open: true,
27 | },
28 | build: {
29 | outDir: `../dist/my-app`,
30 | emptyOutDir: true,
31 | target: 'es2020',
32 | },
33 | resolve: {
34 | mainFields: ['module'],
35 | },
36 | plugins: [
37 | federation({
38 | options: {
39 | workspaceRoot: __dirname,
40 | outputPath: 'dist/my-app',
41 | tsConfig: 'tsconfig.app.json',
42 | federationConfig: 'federation.config.cjs',
43 | verbose: false,
44 | dev: command === 'serve',
45 | },
46 | adapter: AngularEsBuildAdapter,
47 | }),
48 | angular()
49 | ],
50 | test: {
51 | globals: true,
52 | environment: 'jsdom',
53 | setupFiles: ['test.ts'],
54 | include: ['**/*.spec.ts'],
55 | cache: {
56 | dir: `../node_modules/.vitest`,
57 | },
58 | },
59 | define: {
60 | 'import.meta.vitest': mode !== 'production',
61 | },
62 | }));
63 |
--------------------------------------------------------------------------------
/shell/vite.config.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
3 | import { defineConfig } from 'vite';
4 | import angular from '@analogjs/vite-plugin-angular';
5 | import { federation } from '@gioboa/vite-module-federation';
6 | import { AngularEsBuildAdapter } from '@angular-architects/native-federation/src/utils/angular-esbuild-adapter';
7 |
8 |
9 | // https://vitejs.dev/config/
10 | export default defineConfig(({ mode, command }) => ({
11 | root: 'src',
12 | publicDir: 'assets',
13 | server: {
14 | port: 3000,
15 | open: true,
16 | fs: {
17 | // Allowing access to both, project
18 | // and shared folder in dev mode
19 | allow: [
20 | '.',
21 | '../../shared'
22 | ]
23 | }
24 | },
25 | preview: {
26 | port: 3000,
27 | open: true,
28 | },
29 | build: {
30 | outDir: `../dist/my-app`,
31 | emptyOutDir: true,
32 | target: 'es2020',
33 | },
34 | resolve: {
35 | mainFields: ['module'],
36 | },
37 | plugins: [
38 | federation({
39 | options: {
40 | workspaceRoot: __dirname,
41 | outputPath: 'dist/my-app',
42 | tsConfig: 'tsconfig.app.json',
43 | federationConfig: 'federation.config.cjs',
44 | verbose: false,
45 | dev: command === 'serve',
46 | },
47 | adapter: AngularEsBuildAdapter,
48 | }),
49 | angular(),
50 | ],
51 | test: {
52 | globals: true,
53 | environment: 'jsdom',
54 | setupFiles: ['test.ts'],
55 | include: ['**/*.spec.ts'],
56 | cache: {
57 | dir: `../node_modules/.vitest`,
58 | },
59 | },
60 | define: {
61 | 'import.meta.vitest': mode !== 'production',
62 | },
63 | }));
64 |
--------------------------------------------------------------------------------
/mfe1/src/polyfills.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * This file includes polyfills needed by Angular and is loaded before the app.
3 | * You can add your own extra polyfills to this file.
4 | *
5 | * This file is divided into 2 sections:
6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main
8 | * file.
9 | *
10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that
11 | * automatically update themselves. This includes recent versions of Safari, Chrome (including
12 | * Opera), Edge on the desktop, and iOS and Chrome on mobile.
13 | *
14 | * Learn more in https://angular.io/guide/browser-support
15 | */
16 |
17 | /***************************************************************************************************
18 | * BROWSER POLYFILLS
19 | */
20 |
21 | /**
22 | * By default, zone.js will patch all possible macroTask and DomEvents
23 | * user can disable parts of macroTask/DomEvents patch by setting following flags
24 | * because those flags need to be set before `zone.js` being loaded, and webpack
25 | * will put import in the top of bundle, so user need to create a separate file
26 | * in this directory (for example: zone-flags.ts), and put the following flags
27 | * into that file, and then add the following code before importing zone.js.
28 | * import './zone-flags';
29 | *
30 | * The flags allowed in zone-flags.ts are listed here.
31 | *
32 | * The following flags will work for all browsers.
33 | *
34 | * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
35 | * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
36 | * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
37 | *
38 | * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
39 | * with the following flag, it will bypass `zone.js` patch for IE/Edge
40 | *
41 | * (window as any).__Zone_enable_cross_context_check = true;
42 | *
43 | */
44 |
45 | /***************************************************************************************************
46 | * Zone JS is required by default for Angular itself.
47 | */
48 | import 'zone.js'; // Included with Angular CLI.
49 |
50 |
51 | /***************************************************************************************************
52 | * APPLICATION IMPORTS
53 | */
54 |
--------------------------------------------------------------------------------
/shell/src/polyfills.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * This file includes polyfills needed by Angular and is loaded before the app.
3 | * You can add your own extra polyfills to this file.
4 | *
5 | * This file is divided into 2 sections:
6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main
8 | * file.
9 | *
10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that
11 | * automatically update themselves. This includes recent versions of Safari, Chrome (including
12 | * Opera), Edge on the desktop, and iOS and Chrome on mobile.
13 | *
14 | * Learn more in https://angular.io/guide/browser-support
15 | */
16 |
17 | /***************************************************************************************************
18 | * BROWSER POLYFILLS
19 | */
20 |
21 | /**
22 | * By default, zone.js will patch all possible macroTask and DomEvents
23 | * user can disable parts of macroTask/DomEvents patch by setting following flags
24 | * because those flags need to be set before `zone.js` being loaded, and webpack
25 | * will put import in the top of bundle, so user need to create a separate file
26 | * in this directory (for example: zone-flags.ts), and put the following flags
27 | * into that file, and then add the following code before importing zone.js.
28 | * import './zone-flags';
29 | *
30 | * The flags allowed in zone-flags.ts are listed here.
31 | *
32 | * The following flags will work for all browsers.
33 | *
34 | * (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
35 | * (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
36 | * (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
37 | *
38 | * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
39 | * with the following flag, it will bypass `zone.js` patch for IE/Edge
40 | *
41 | * (window as any).__Zone_enable_cross_context_check = true;
42 | *
43 | */
44 |
45 | /***************************************************************************************************
46 | * Zone JS is required by default for Angular itself.
47 | */
48 | import 'zone.js'; // Included with Angular CLI.
49 |
50 |
51 | /***************************************************************************************************
52 | * APPLICATION IMPORTS
53 | */
54 |
--------------------------------------------------------------------------------
/mfe1/src/assets/analog.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/shell/src/assets/analog.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------