nx icon indicating copy to clipboard operation
nx copied to clipboard

No version specified and unable to automatically determine one With 14.5.10

Open vdiaz1130 opened this issue 2 years ago • 10 comments

Current Behavior

Application doesn't build correctly and produces warnings in terminal and errors in browser console when importing certain libraries and running app configured for Module Federation.

main.ts:1 Error: Unsatisfied version 0 from host of shared singleton module firebase/app (required ^9.9.0)

image

Expected Behavior

The application should compile and run as expected.

Steps to Reproduce

  1. Clone https://github.com/vdiaz1130/nx_mf_firebase_import_issue
  2. Run pnpm i
  3. Serve app pnpm start
  4. Note warnings and errors in terminal window.

Failure Logs

Configure dependencies in package.json:

    "dependencies": {
      "firebase": "^9.9.0",
      "firebase-admin": "^11.0.0",
      "firebase-functions": "^3.22.0",
      "passport-firebase-jwt": "^1.2.1",
      "@angular/fire": "^7.4.1",
      "@google-cloud/firestore": "^5.0.2",
      "@google-cloud/language": "^5.0.0",
      "@google-cloud/storage": "^6.2.3",
      "@google-cloud/vision": "^2.4.2",
      "rxfire": "^6.0.3",
      ...
    },
    "devDependencies": {
      "@firebase/app": "^0.7.31",
      "@firebase/rules-unit-testing": "^2.0.2",
      "@google-cloud/functions-framework": "^3.1.2",
      "@types/firebase": "^3.2.1",
      "firebase-functions-test": "^2.2.0",
      ...
    }

Add snippet below in any library project:

    import { DocumentSnapshot } from '@angular/fire/compat/firestore';
    import { OrderByDirection, WhereFilterOp } from 'firebase/firestore';

    export interface WhereCondition {
      field: string;
      operator: WhereFilterOp;
      value: string | number;
    }

    export interface OrderByCondition {
      field: string;
      order?: OrderByDirection;
    }

    export interface FirestoreQuery<T> {
      limit?: number;
      startAt?: number | string | DocumentSnapshot<T>;
      startAfter?: number | string | DocumentSnapshot<T>;
      endAt?: number | DocumentSnapshot<T>;
      endBefore?: number | DocumentSnapshot<T>;
      orderBy?: OrderByCondition[];
      where?: WhereCondition[];
    }

Add AngularFire Module (see repo):

    import { isDevMode, NgModule } from '@angular/core';

    import {
      APP_NAME,
      APP_VERSION,
      DEBUG_MODE as ANALYTICS_DEBUG_MODE,
      ScreenTrackingService,
      UserTrackingService,
      COLLECTION_ENABLED,
    } from '@angular/fire/compat/analytics';
    import { SETTINGS as FIRESTORE_SETTINGS } from '@angular/fire/compat/firestore';
    import { USE_DEVICE_LANGUAGE } from '@angular/fire/compat/auth';
    import { SERVICE_WORKER, VAPID_KEY } from '@angular/fire/compat/messaging';
    import {
      SETTINGS as REMOTE_CONFIG_SETTINGS,
      DEFAULTS as REMOTE_CONFIG_DEFAULTS,
    } from '@angular/fire/compat/remote-config';
    import { PerformanceMonitoringService } from '@angular/fire/compat/performance';
    import { AngularFireAuthGuardModule } from '@angular/fire/compat/auth-guard';

    import { provideFirebaseApp, initializeApp } from '@angular/fire/app';
    import { connectFunctionsEmulator, FunctionsModule, getFunctions, provideFunctions } from '@angular/fire/functions';
    import {
      connectFirestoreEmulator,
      getFirestore,
      provideFirestore,
      enableMultiTabIndexedDbPersistence,
    } from '@angular/fire/firestore';
    import { connectDatabaseEmulator, getDatabase, provideDatabase } from '@angular/fire/database';
    import { connectStorageEmulator, getStorage, provideStorage } from '@angular/fire/storage';
    import { getRemoteConfig, provideRemoteConfig } from '@angular/fire/remote-config';
    import { getAnalytics, provideAnalytics } from '@angular/fire/analytics';
    import { getMessaging, provideMessaging } from '@angular/fire/messaging';
    import { getPerformance, providePerformance } from '@angular/fire/performance';
    import { getApp } from '@angular/fire/app';
    import {
      initializeAuth,
      browserPopupRedirectResolver,
      connectAuthEmulator,
      indexedDBLocalPersistence,
      provideAuth,
    } from '@angular/fire/auth';
    // import { initializeAppCheck, provideAppCheck, ReCaptchaV3Provider } from '@angular/fire/app-check';

    import { BrowserModule } from '@angular/platform-browser';

    const environment = {
      useEmulators: true,
      firebase: {
        apiKey: 'OeRXXXK7S_x_5rpQUu1XXXZMWyAXXXAIzatE',
        appId: '1:31401XXX732:web:ff29faXXX6595dXXX9c5',
        authDomain: 'XXX.firebaseapp.com',
        databaseURL: 'https://XXX.firebaseio.com',
        measurementId: 'G-7GXXXPWD0',
        messagingSenderId: '3571XXX61632',
        projectId: 'XXX',
        storageBucket: 'XXX.appspot.com',
      }
    }

    let resolvePersistenceEnabled: (enabled: boolean) => void;

    export const persistenceEnabled = new Promise<boolean>((resolve) => {
      resolvePersistenceEnabled = resolve;
    });

    @NgModule({
      imports: [
        BrowserModule,
        AngularFireAuthGuardModule,
        FunctionsModule,

        provideRemoteConfig(() => getRemoteConfig()),
        provideAnalytics(() => getAnalytics()),
        provideMessaging(() => getMessaging()),
        providePerformance(() => getPerformance()),
        provideAuth(() => {
          const auth = initializeAuth(getApp(), {
            persistence: indexedDBLocalPersistence,
            popupRedirectResolver: browserPopupRedirectResolver,
          });
          if (environment.useEmulators) {
            connectAuthEmulator(auth, 'http://localhost:9099', { disableWarnings: true });
          }
          return auth;
        }),
        // provideAppCheck(() =>  {
        //   const provider = new ReCaptchaV3Provider(environment.recaptcha3SiteKey);
        //   return initializeAppCheck(undefined, { provider, isTokenAutoRefreshEnabled: true });
        // }),

        provideFirebaseApp(() => initializeApp(environment.firebase)),
        provideFirestore(() => {
          const firestore = getFirestore();
          if (environment.useEmulators) {
            connectFirestoreEmulator(firestore, 'localhost', 8080);
          }
          enableMultiTabIndexedDbPersistence(firestore).then(
            () => resolvePersistenceEnabled(true),
            () => resolvePersistenceEnabled(false),
          );
          return firestore;
        }),
        provideDatabase(() => {
          const database = getDatabase();
          if (environment.useEmulators) {
            connectDatabaseEmulator(database, 'localhost', 9000);
          }
          return database;
        }),
        provideStorage(() => {
          const storage = getStorage();
          if (environment.useEmulators) {
            connectStorageEmulator(storage, 'localhost', 9199);
          }
          return storage;
        }),
        provideFunctions(() => {
          const functions = getFunctions();
          if (environment.useEmulators) {
            connectFunctionsEmulator(functions, 'localhost', 5001);
          }
          return functions;
        }),
      ],

      providers: [
        UserTrackingService,
        ScreenTrackingService,
        PerformanceMonitoringService,
        { provide: FIRESTORE_SETTINGS, useValue: { ignoreUndefinedProperties: true } },
        { provide: ANALYTICS_DEBUG_MODE, useValue: true },
        { provide: COLLECTION_ENABLED, useValue: true },
        { provide: REMOTE_CONFIG_SETTINGS, useFactory: () => (isDevMode() ? { minimumFetchIntervalMillis: 10_000 } : {}) },
        { provide: REMOTE_CONFIG_DEFAULTS, useValue: { background_color: 'red' } },
        { provide: USE_DEVICE_LANGUAGE, useValue: true },
        // { provide: VAPID_KEY, useValue: environment.vapidKey },
        {
          provide: SERVICE_WORKER,
          useFactory: () =>
            (typeof navigator !== 'undefined' &&
              navigator.serviceWorker?.register('firebase-messaging-sw.js', { scope: '__' })) ||
            undefined,
        },
        { provide: APP_VERSION, useValue: '0.0.0' },
        { provide: APP_NAME, useValue: 'deez.io' },
      ],
    })
    export class AngularFireModule { }

Import AngularFire module in host application:

    @NgModule({
      declarations: [AppComponent],
      imports: [
        BrowserModule,
        AngularFireModule, // <--
        RouterModule.forRoot(
          [
            ...
          ],
          { initialNavigation: 'enabledBlocking' }
        ),
      ],
      providers: [],
      bootstrap: [AppComponent],
    })
    export class AppModule {}

Environment

 >  NX   Report complete - copy this into the issue template

   Node : 16.9.1
   OS   : darwin x64
   pnpm : 7.9.5

   nx : 14.5.10
   @nrwl/angular : 14.5.7
   @nrwl/cypress : 14.5.10
   @nrwl/detox : Not Found
   @nrwl/devkit : 13.1.3
   @nrwl/eslint-plugin-nx : 14.5.10
   @nrwl/express : Not Found
   @nrwl/jest : 14.5.10
   @nrwl/js : 14.5.7
   @nrwl/linter : 14.5.10
   @nrwl/nest : 14.5.7
   @nrwl/next : Not Found
   @nrwl/node : 14.5.7
   @nrwl/nx-cloud : 14.6.0
   @nrwl/nx-plugin : Not Found
   @nrwl/react : Not Found
   @nrwl/react-native : Not Found
   @nrwl/schematics : Not Found
   @nrwl/storybook : 14.5.7
   @nrwl/web : 14.5.7
   @nrwl/workspace : 14.5.10
   typescript : 4.7.4
   ---------------------------------------
   Local workspace plugins:
   ---------------------------------------
   Community plugins:
   	 @ngneat/transloco: 4.0.0
   	 @nguniversal/express-engine: 13.1.1
   	 angular-calendar: 0.29.0
   	 @nguniversal/builders: 13.1.1
   	 @ngxs/schematics: 0.0.1-alpha.5

vdiaz1130 avatar Aug 29 '22 21:08 vdiaz1130

I tried with nx 14.6.1 and problem persists. Is there a way to set the dependencies explicitly?

vdiaz1130 avatar Sep 01 '22 12:09 vdiaz1130

I can build fine... integrated with apollo client for graphql and now mfe has stopped in runtime refuses to launch my mfe remote from host

Error: Unsatisfied version 0 from nx-host of shared singleton module @apollo/client/core (required ^3.6.9)

is there any help, workaround?

index.js:556 [webpack-dev-server] WARNING in shared module @apollo/client/core -> /node_modules/@apollo/client/core/index.js
No version specified and unable to automatically determine one. No version in description file (usually package.json). Add version to description file node_modules/@apollo/client/core/package.json, or manually specify version in shared config.
logger @ index.js:556
(anonymous) @ index.js:730
warn @ index.js:189
warnings @ index.js:247
(anonymous) @ socket.js:60
client.onmessage @ WebSocketClient.js:50
wrapFn @ zone.js:766
invokeTask @ zone.js:406
runTask @ zone.js:178
invokeTask @ zone.js:487
invokeTask @ zone.js:1661
globalCallback @ zone.js:1692
globalZoneAwareCallback @ zone.js:1725
index.js:556 [webpack-dev-server] WARNING in shared module @apollo/client/link/batch -> /Users/w509297/PR/150305/Yeti-UI/node_modules/@apollo/client/link/batch/index.js
No version specified and unable to automatically determine one. No version in description file (usually package.json). Add version to description file /Users/w509297/PR/150305/Yeti-UI/node_modules/@apollo/client/link/batch/package.json, or manually specify version in shared config.
logger @ index.js:556
(anonymous) @ index.js:730
warn @ index.js:189
warnings @ index.js:247
(anonymous) @ socket.js:60
client.onmessage @ WebSocketClient.js:50
wrapFn @ zone.js:766
invokeTask @ zone.js:406
runTask @ zone.js:178
invokeTask @ zone.js:487
invokeTask @ zone.js:1661
globalCallback @ zone.js:1692
globalZoneAwareCallback @ zone.js:1725
index.js:556 [webpack-dev-server] WARNING
undefined depends on 'guid-typescript'. CommonJS or AMD dependencies can cause optimization bailouts.
For more info see: https://angular.io/guide/build#configuring-commonjs-dependencies
logger @ index.js:556
(anonymous) @ index.js:730
warn @ index.js:189
warnings @ index.js:247
(anonymous) @ socket.js:60
client.onmessage @ WebSocketClient.js:50
wrapFn @ zone.js:766
invokeTask @ zone.js:406
runTask @ zone.js:178
invokeTask @ zone.js:487
invokeTask @ zone.js:1661
globalCallback @ zone.js:1692
globalZoneAwareCallback @ zone.js:1725
main.ts:19 Error: Unsatisfied version 0 from host of shared singleton module @apollo/client/core (required ^3.6.9)
    at getStrictSingletonVersion (consumes:49:1)
    at consumes:130:1
    at consumes:82:1
    at 88904 (consumes:166:1)
    at consumes:289:1
    at Array.forEach (<anonymous>)
    at __webpack_require__.f.consumes (consumes:272:1)
    at ensure chunk:6:1
    at Array.reduce (<anonymous>)
    at __webpack_require__.e (ensure chunk:5:1)

kenatwex avatar Sep 02 '22 12:09 kenatwex

You'll need to use the additional dependencies option in the module-federation.config.js file for the apps using Firebase. (https://github.com/vdiaz1130/nx_mf_firebase_import_issue/blob/main/apps/host/module-federation.config.js)

Using the contents from the link above, it would look something like this:

module.exports = {
  name: 'host',
  remotes: ['cart', 'shop', 'about'],
  additionalShared: ['firebase']
};

Coly010 avatar Sep 06 '22 10:09 Coly010

You'll need to use the additional dependencies option in the module-federation.config.js file for the apps using Firebase. (https://github.com/vdiaz1130/nx_mf_firebase_import_issue/blob/main/apps/host/module-federation.config.js)

Using the contents from the link above, it would look something like this:

module.exports = {
  name: 'host',
  remotes: ['cart', 'shop', 'about'],
  additionalShared: ['firebase']
};

Thanks for the reply but something else is amiss here. I added your suggestion to the sample repo and the same error occurs.

vdiaz1130 avatar Sep 16 '22 16:09 vdiaz1130

Looks like you'll also need to add @apollo/client/core to additionalShared

Coly010 avatar Sep 19 '22 13:09 Coly010

Looks like you'll also need to add @apollo/client/core to additionalShared

Thank you for your response. But Apollo is not part of the repo. It’s all Firebase code. I added angular fire as well but no change.

these are the errors I’m seeing even after adding Firebase and angular/fire:

vdiaz1130 avatar Sep 19 '22 14:09 vdiaz1130

As frustrating as it may be, can you add all those package names to additionalShared and see if it functions for you?

e.g. firebase/storage,firebase/remote-config etc

Your additional shared will be pretty large, but if it works, then I'll investigate a better way to do it.

Coly010 avatar Sep 19 '22 14:09 Coly010

Yup. I've tried that but get the following error for each of those deps: The specified dependency "firebase/analytics" in the additionalShared configuration does not exist in the project graph. Please check your additionalShared configuration and make sure you are including valid workspace projects or npm packages.

However, they are in my node_modules:

image

If I remove analytics, I get that error for the next one on the list.

vdiaz1130 avatar Sep 19 '22 14:09 vdiaz1130

One thing I would note is that all those packages are nested inside the Firebase node_modules directory:

image

vdiaz1130 avatar Sep 19 '22 14:09 vdiaz1130

Ok, I'll take a closer look at what is going on there. Additional Shared is supposed to work for deps not in the project graph IIRC

Coly010 avatar Sep 19 '22 14:09 Coly010

Hi, thanks for re-directing me to this. We’re really impressed with Nx and keen to complete our upgrade to Nx 14 / angular 14 which has stalled as we've run up against this issue with apollo & firebase. Any guidance you can provide around a timeframe for resolving this or a workaround would be greatly appreciated. Thanks for your help.

keaston67 avatar Oct 04 '22 01:10 keaston67

I've taken a deeper look at this, and it looks like there may be an issue in the ModuleFederationPlugin itself.

I have a workaround in the meantime.

In each of your module-federation.config.js files, add the following to the config that is exported:

shared: (libraryName, config) => {
    if (libraryName.startsWith('firebase')) {
      return {
        ...config,
        strictVersion: false,
      };
    }
  },

You can use as many if statements as you need for the packages you need to apply the strictVersion: false to.

So your host's module-federation.config.js should look like this:

module.exports = {
  name: 'host',
  remotes: ['cart', 'shop', 'about'],
  shared: (libraryName, config) => {
    if (libraryName.startsWith('firebase')) {
      return {
        ...config,
        strictVersion: false,
      };
    }
  },
};

and your remotes should look like this:

module.exports = {
  name: 'cart',
  exposes: {
    './Module': 'apps/cart/src/app/remote-entry/entry.module.ts',
  },
  shared: (libraryName, config) => {
    if (libraryName.startsWith('firebase')) {
      return {
        ...config,
        strictVersion: false,
      };
    }
  },
};

As there is a workaround for this, I'm going to close this issue and I'll see if I can get this fixed in the MFP repo.

Coly010 avatar Oct 14 '22 10:10 Coly010

@Coly010 can you link any follow up on this / where I can continue to track? I'm using apollo-angular and have run into similar issues "app-routing.module.ts:31 Unsatisfied version 0 from web of shared singleton module @apollo/client/core (required =3.7.1)", getting that thrown on a basically empty MFE remote only the host needs apollo. Your solution does indeed bypass the error being thrown, but warnings still persist - WARNING in shared module @apollo/client/core

EDIT: If you don't need to share apollo client do the following instead (https://nx.dev/recipes/module-federation/faster-builds#excluding-or-overriding-shared-libraries) -

if (libraryName.startsWith('@apollo/client')) {
    return false;
}

JacobSiegle avatar Nov 14 '22 18:11 JacobSiegle

here is my module-federation.config for my remote

module.exports = {
  name: 'ui-auth',
  exposes: {
    './Module': 'apps/ui-auth/src/app/remote-entry/entry.module.ts',
  },
  shared: (libraryName, config) => {
    if (libraryName.startsWith('@apollo/client')) {
      return {
        ...config,
        strictVersion: false,
      };
    }
  },
};

heres my module-federation.config for my host

module.exports = {
  name: 'ui-main',
  remotes: [],
  shared: (libraryName, config) => {
    if (libraryName.startsWith('@apollo/client')) {
      return {
        ...config,
        strictVersion: false,
      };
    }
  },
  additionalShared: [
    '@angular/animations',
    '@angular/cdk',
    '@angular/common',
    '@angular/compiler',
    '@angular/core',
    '@angular/forms',
    '@angular/router',
    '@apollo/client',
    '@apollo/client',
    '@ngrx/effects',
    '@ngrx/store',
    'apollo-angular',
    'graphql',
    '@ngrx/effects',
    '@ngrx/store',
    '@wexinc/environment',
    '@wexinc/logger',
    '@wexinc/animations',
    '@wexinc/constants',
    '@wexinc/isomorphic',
    '@wexinc/models',
    '@wexinc/notifications',
    '@wexinc/service',
  ]
};




kenatwex avatar Nov 14 '22 18:11 kenatwex

the docs have changed too

https://nx.dev/recipes/module-federation/dynamic-module-federation-with-angular

using dev-remotes in launch

this is how I launch which makes a diff too

instead of nx serve

I use nx launch

    "launch": {
      "executor": "nx:run-commands",
      "options": {
        "parallel": true,
        "commands": [
          {
            "command": "json-graphql-server .bff/data.js --p 3333 --h localhost"
          },
          {
            "command": "nx run ui-main:serve:development --devRemotes=ui-auth,ui-navigation,ui-dashboard,ui-cards"
          }
        ]
      }
    },

kenatwex avatar Nov 14 '22 18:11 kenatwex

Im getting this error when I think i shouldn't

Error: Uncaught (in promise): Error: Call setRemoteDefinitions or setRemoteUrlResolver to allow Dynamic Federation to find the remote apps correctly. Error: Call setRemoteDefinitions or setRemoteUrlResolver to allow Dynamic Federation to find the remote apps correctly.

my main.ts does both calls pointing to urls for not just the host but all remotes

and im still receiving this error

any help Colum is appreciated

my remotes lazy load a feature lib which has routes to load MFE's... is this a malformed approach?

thats when I attempt to route directkly to an MFE from within a lib of routes my feature.nmodule

but if I attempt resort to navigate directly to the MFE entry module using the router my router gets lost

my router is getting lost on subsequent navigations all I am getting to now is the initialization index route anything deeper fails pathmatch full/prefix mfe or lib cant seem to shake this out

kenatwex avatar Nov 14 '22 19:11 kenatwex

@kenatwex you can perform this part of the tutorial to get past that error message - https://nx.dev/recipes/module-federation/dynamic-module-federation-with-angular#fetch-and-set-the-remote-definitions

It feels weird to have to manually have module-federation.manifest.json and fetch it. Not sure I fully understand this approach / if somehow the MFE nx settings override it somewhere along the line but does get me a bit further in my basic attempt to POC a MFE with NX and Angular.

Maybe a decent example repo to look at - https://github.com/Royserg/nx-mfe-angular/tree/a46ab305218b68d03e7c7a9e16cef6235162e29f, found some by Coly010 but they were out of date for Angular 14 / don't match the most recent MFE code NX shows in the tutorial.

JacobSiegle avatar Nov 14 '22 19:11 JacobSiegle

Thanks friend I hope mine pans out will check it out

I think their code is still evolving.

Be nice to see some proactive PUSH in this area...

We are trying to use MFE's everywhere and hitting brick walls in the process... dynamic environments, prod, qa, staging, dev... URLS and such

Colum likes to focus on this area I hope he continues its not 100% and we need it now

kenatwex avatar Nov 14 '22 21:11 kenatwex

The only diff I see in that repo is [email protected] is part of package.json

my repo doesnt even have webpack and I try to avoid it trusting what they bundle against

do we even need webpack?

O hope not

any elaboration on tis is appreciated.

Its not part of any MFE monoreppo that gets generated

and I see no docs requiring it

unless we have to drill deeper which im hopingnot Nx is suppose to automate all of webpack ghorry details

kenatwex avatar Nov 14 '22 22:11 kenatwex

@kenatwex I've run into same issue as you, i.e. trying to load MFE inside another MFE. The problem is that the package @nrwl/angular/mf is explicitly not shared across your MFEs in the withModuleFederation nx plugin - see for yourself. That mean's that if you are using loadRemoteModule or other functions from the package directly, each MFE will get their own instance. One way to avoid this is to create a root provided service, which acts as a proxy to these functions. All your MFEs now can use this service to get the same remoteDefinitions that were set by your shell (or if you desire - wherever you provided this service... standard DI rules apply).

faileon avatar Nov 15 '22 08:11 faileon

@kenatwex I've run into same issue as you, i.e. trying to load MFE inside another MFE. The problem is that the package @nrwl/angular/mf is explicitly not shared across your MFEs in the withModuleFederation nx plugin - see for yourself. That mean's that if you are using loadRemoteModule or other functions from the package directly, each MFE will get their own instance. One way to avoid this is to create a root provided service, which acts as a proxy to these functions. All your MFEs now can use this service to get the same remoteDefinitions that were set by your shell (or if you desire - wherever you provided this service... standard DI rules apply).

Thanks friend... but isn't this what the HOST is suppose to do by intent? Do you have a service snippet you can share so I can review? And is this service token injected and governed by what host/remote if any?

kenatwex avatar Nov 15 '22 12:11 kenatwex

and so if we peek at our friends repo here https://github.com/Royserg/nx-mfe-angular/tree/a46ab305218b68d03e7c7a9e16cef6235162e29f

we see the router config model is in fact modeled and governed by the host

I would love to have my feature.module route config handle it all Components/MFE but it will only load components from the feature/module route config. MFE routing fails due to it in part being executed by my navigation remote.

I am migrating this lib/feature.module router config to my host and starting from there.

Colum stated that Nx will handle everything and just use router as normal but the route config I feel needs some pertinent focused in the host which Im addressing this morning. Results pending.

But I would like to hear more about your citation

Colum if you can weigh in here that would be terrific.

kenatwex avatar Nov 15 '22 12:11 kenatwex

Thanks friend... but isn't this what the HOST is suppose to do by intent? Do you have a service snippet you can share so I can review? And is this service token injected and governed by what host/remote if any?

In your use case it is probably the responsibility of the host. However the default behavior is that each MFE can specify their own subset of remotes - because they each get their own @nrwl/angular/mf package. If you want to share the remote definitions, which are defined by the host, you can solve it with the proxy service approach or load the same remotes for the MFE again.

The service is really simple:

import { Injectable } from '@angular/core';
import { loadRemoteModule, setRemoteDefinitions } from '@nrwl/angular/mf';

@Injectable({
    providedIn: 'root'
})
export class RemotesService {

    public setRemotesManifest(manifest: Record<string, string>) {
        setRemoteDefinitions(manifest);
    }

    public async loadModule(remoteName: string, exposedModule: string) {
        return loadRemoteModule(remoteName, exposedModule);
    }
}

In your host app, you can use the @nrwl/angular/mf without problems, but if you have a MFE that wants to use the remotes defined by the host, you must go thru the service. Keep this service in separate nx library and use it wherever you desire.

If however your remotes don't need to use another remote, you do not need this at all. You can perhaps also check out my sample repo https://github.com/faileon/angular-module-federation excuse the readme, its in czech language, but code should be fine.

faileon avatar Nov 15 '22 12:11 faileon

sorry I didnt find usage of your remote service in your repo

would you happen to have a usage example repo?

Thanks friend

kenatwex avatar Nov 15 '22 13:11 kenatwex

sorry I didnt find usage of your remote service in your repo

would you happen to have a usage example repo?

Thanks friend

That's correct, the repo is a simple sample. It was a POC to confirm a few ideas on how to approach plugin based architecture in angular.

Perhaps you can share your repo and I'll see if I can help you.

faileon avatar Nov 15 '22 13:11 faileon

This issue has been closed for more than 30 days. If this issue is still occuring, please open a new issue with more recent context.

github-actions[bot] avatar Mar 21 '23 12:03 github-actions[bot]