Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

es-module-shims Uncaught Error #671

Open
joepeace01 opened this issue Oct 17, 2024 · 5 comments
Open

es-module-shims Uncaught Error #671

joepeace01 opened this issue Oct 17, 2024 · 5 comments

Comments

@joepeace01
Copy link

For which library do you need help?

native-federation

Question

Hi, I set up native federation to connect two angular 18 app which are on two different repositories.

My configurations are almost the same for my two apps, the host app is working fine, but the remote one does not pass the boostrapping of the app. I can still see my home page, but it's only cached information that I get from the server, cause I also installed angular ssr.

The app is working fine on server side but not on client side. I get an error from es-module-shims, I tried to skip all my packages but I still have the error so I think that it comes from the boostrapping of the app in the main.js file.

Capture d’écran 2024-10-17 à 14 05 28

I don't understant what causes this error, and I tried different version of es-module-shims.

Here is my angular.json file:

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects",
  "projects": {
    "mfe-evenement": {
      "projectType": "application",
      "schematics": {
        "@schematics/angular:component": {
          "style": "scss"
        }
      },
      "root": "mfe-evenement",
      "sourceRoot": "mfe-evenement/src",
      "prefix": "app",
      "architect": {
        "build": {
          "builder": "@angular-architects/native-federation:build",
          "configurations": {
						"production": {
							"target": "mfe-evenement:esbuild:production"
						},
            "qa": {
							"target": "mfe-evenement:esbuild:qa"
						},
						"development": {
							"target": "mfe-evenement:esbuild:development",
							"dev": true
						}
					}
        },
        "esbuild": {
          "builder": "@angular-devkit/build-angular:application",
          "options": {
            "outputPath": "dist/mfe-evenement/",
            "index": "mfe-evenement/src/index.html",
            "browser": "mfe-evenement/src/main.ts",
            "polyfills": [
							"zone.js",
							"es-module-shims",
              "@angular/localize/init"
						],            
            "tsConfig": "mfe-evenement/tsconfig.app.json",
            "inlineStyleLanguage": "scss",
            "assets": ["mfe-evenement/src/favicon.ico", "mfe-evenement/src/assets/"],
            "styles": [
              "node_modules/bootstrap/dist/css/bootstrap.min.css",
              "node_modules/@angular/material/prebuilt-themes/deeppurple-amber.css"
            ],
            "stylePreprocessorOptions": {
              "includePaths": ["./SASS-Modules"]
            },
            "allowedCommonJsDependencies": [
              "html2canvas",
              "canvg",
              "@angular-architects/native-federation",
              "compression",
              "moment",
              "jspdf"
            ],
            "server": "mfe-evenement/src/main.server.ts",
            "ssr": {
              "entry": "mfe-evenement/server.ts"
            },
            "scripts": [],
            "extractLicenses": false,
            "sourceMap": true,
            "optimization": true
          },
          "configurations": {
            "production": {
              "fileReplacements": [
                {
                  "replace": "mfe-evenement/src/environments/environment.ts",
                  "with": "mfe-evenement/src/environments/environment.prod.ts"
                }
              ],
              "budgets": [
                {
                  "type": "initial",
                  "maximumWarning": "700kb",
                  "maximumError": "15mb"
                },
                {
                  "type": "anyComponentStyle",
                  "maximumWarning": "80kb",
                  "maximumError": "1mb"
                }
              ],
              "outputHashing": "all"
            },
            "qa": {
              "fileReplacements": [
                {
                  "replace": "mfe-evenement/src/environments/environment.ts",
                  "with": "mfe-evenement/src/environments/environment.qa.ts"
                }
              ],
              "optimization": true,
              "outputHashing": "all",
              "sourceMap": false,
              "extractLicenses": true,
              "budgets": [
                {
                  "type": "initial",
                  "maximumWarning": "2mb",
                  "maximumError": "5mb"
                },
                {
                  "type": "anyComponentStyle",
                  "maximumWarning": "6kb"
                }
              ]
            },
            "development": {
              "optimization": false,
              "extractLicenses": false,
              "sourceMap": true
            }
          },
          "defaultConfiguration": "production"
        },
        "serve": {
          "builder": "@angular-architects/native-federation:build",
          "options": {
            "target": "mfe-evenement:serve-original:development",
            "rebuildDelay": 0,
            "dev": true,
            "port": 0
          }
        },
        "serve-original": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "configurations": {
            "production": {
              "buildTarget": "mfe-evenement:esbuild:production"
            },
            "qa": {
              "buildTarget": "mfe-evenement:esbuild:qa"
            },
            "development": {
              "buildTarget": "mfe-evenement:esbuild:development"
            }
          },
          "defaultConfiguration": "development",
          "options": {
            "port": 4201,
            "publicHost": "http://localhost:4201"
          }
        },
        "lint": {
          "builder": "@angular-eslint/builder:lint",
          "options": {
            "lintFilePatterns": ["mfe-evenement/src/**/*.ts", "mfe-evenement/src/**/*.html"]
          }
        },
        "extract-i18n": {
          "builder": "@angular-devkit/build-angular:extract-i18n",
          "options": {
            "buildTarget": "mfe-evenement:build"
          }
        },
        "test": {
          "builder": "@angular-devkit/build-angular:karma",
          "options": {
            "polyfills": [
							"zone.js",
							"es-module-shims",
              "@angular/localize/init"
						],            
            "tsConfig": "mfe-evenement/tsconfig.spec.json",
            "inlineStyleLanguage": "scss",
            "assets": ["mfe-evenement/src/favicon.ico", "mfe-evenement/src/assets"],
            "styles": [
              "mfe-evenement/src/styles.scss",
              "node_modules/bootstrap/dist/css/bootstrap.css",
              "node_modules/@angular/material/prebuilt-themes/deeppurple-amber.css"
            ],
            "scripts": []
          }
        }
      }
    }
  }
}

my package.json file:

{
  "name": "mfe-evenement",
  "version": "0.0.0",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "build-prod": "ng build --configuration production",
    "build-qa": "ng build --configuration qa",
    "watch": "ng build --watch --configuration development",
    "run:all": "node node_modules/@angular-architects/module-federation/src/server/mf-dev-server.js",
    "format:fix": "pretty-quick --staged",
    "precommit": "run-s format:fix lint",
    "format:check": "prettier --config ./.prettierrc --list-different \"src/{app,environments,assets}/**/*{.ts,.js,.json,.css,.scss}\"",
    "lint": "ng lint"
  },
  "private": true,
  "dependencies": {
    "@angular/animations": "^18.2.8",
    "@angular/cdk": "^18.2.8",
    "@angular/common": "^18.2.8",
    "@angular/compiler": "^18.2.8",
    "@angular/core": "^18.2.8",
    "@angular/forms": "^18.2.8",
    "@angular/material": "^18.2.8",
    "@angular/platform-browser": "^18.2.8",
    "@angular/platform-browser-dynamic": "^18.2.8",
    "@angular/platform-server": "^18.2.8",
    "@angular/router": "^18.2.8",
    "@angular/service-worker": "^18.2.8",
    "@angular/ssr": "^18.2.8",
    "@ng-bootstrap/ng-bootstrap": "^17.0.1",
    "@types/compression": "^1.7.5",
    "bootstrap": "^5.3.3",
    "brotli": "^1.3.3",
    "calendar-link": "^2.7.0",
    "compress-brotli": "^1.3.12",
    "compression": "^1.7.4",
    "express": "^4.19.2",
    "gzipper": "^8.1.0",
    "isbot": "^5.1.17",
    "jspdf-html2canvas": "^1.5.2",
    "ngx-bootstrap": "^18.0.2",
    "ngx-cookie-service": "^18.0.0",
    "ngx-device-detector": "^8.0.0",
    "rxjs": "^7.8.1",
    "tslib": "^2.6.2",
    "zone.js": "^0.14.10"
  },
  "devDependencies": {
    "@angular-architects/native-federation": "^18.2.2",
    "@angular-devkit/build-angular": "^18.2.8",
    "@angular-eslint/builder": "^18.3.1",
    "@angular-eslint/eslint-plugin": "^18.3.0",
    "@angular-eslint/eslint-plugin-template": "^18.3.0",
    "@angular-eslint/schematics": "^18.3.0",
    "@angular-eslint/template-parser": "^18.3.0",
    "@angular-ru/prettier": "^14.0.13",
    "@angular/cli": "^18.2.8",
    "@angular/compiler-cli": "^18.2.8",
    "@angular/localize": "^18.2.8",
    "@schematics/angular": "^18.2.8",
    "@types/express": "^4.17.21",
    "@types/jest": "^29.5.0",
    "@types/node": "^20.11.15",
    "@typescript-eslint/eslint-plugin": "^7.2.0",
    "@typescript-eslint/parser": "^7.2.0",
    "es-module-shims": "^1.10.0",
    "eslint": "^8.57.0",
    "eslint-config-prettier": "^9.1.0",
    "eslint-plugin-angular": "^4.1.0",
    "eslint-plugin-prettier": "^5.1.3",
    "ng-packagr": "^18.2.1",
    "ngx-build-plus": "^18.0.0",
    "prettier": "^3.2.4",
    "prettier-eslint": "^16.3.0",
    "thread-loader": "^3.0.4",
    "typescript": "^5.5.4"
  }
}

my federation.conf.js file:

const { withNativeFederation, shareAll } = require('@angular-architects/native-federation/config');

module.exports = withNativeFederation({
  name: 'mfeEvenement',

  exposes: {
    'component': 'mfe-evenement/src/app/app.component.ts',
  },

  shared: {
    ...shareAll({
      singleton: true,
      strictVersion: true,
      requiredVersion: 'auto',
    }),
  },
  skip: [
    'rxjs/ajax',
    'rxjs/fetch',
    'rxjs/testing',
    'rxjs/webSocket',
    'compression',
    'compress-brotli',
    'gzipper',
    'brotli',
    // Add further packages you don't need at runtime
  ],
});

my app.config.ts file:

import { LocationStrategy, PathLocationStrategy } from '@angular/common';
import { provideHttpClient, withFetch } from '@angular/common/http';
import { ApplicationConfig, APP_ID, importProvidersFrom, isDevMode, provideZoneChangeDetection } from '@angular/core';
import { provideClientHydration } from '@angular/platform-browser';
import { withHttpTransferCacheOptions } from '@angular/platform-browser';
import { provideServiceWorker } from '@angular/service-worker';
import { provideRouter } from '@angular/router';
import { routes } from './app.routes';
import { withInMemoryScrolling } from '@angular/router';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { SEOService } from './shared/services/seo.service';
import { PaginationService } from './shared/services/pagination.service';
import { EventsService } from './shared/services/events.service';
import { FilterService } from './shared/services/filter.service';
import { DataGouvService } from './shared/services/data-gouv.service';
import { ProfilService } from './shared/services/profil.service';
import { StorageService } from './shared/services/storage.service';
import { WindowEventService } from './shared/services/window.event.service';

export const appConfig: ApplicationConfig = {
  providers: [
    importProvidersFrom(BrowserAnimationsModule),
    SEOService,
    PaginationService,
    EventsService,
    FilterService,
    DataGouvService,
    ProfilService,
    StorageService,
    WindowEventService,
    { provide: LocationStrategy, useClass: PathLocationStrategy },
    provideServiceWorker('ngsw-worker.js', {
      enabled: !isDevMode(),
      registrationStrategy: 'registerWhenStable:30000',
    }),
    provideClientHydration(
      withHttpTransferCacheOptions({
        includePostRequests: true,
      })
    ),
    provideRouter(
      routes,
      withInMemoryScrolling({
        scrollPositionRestoration: 'enabled',
        anchorScrolling: 'enabled',
      })
    ),
    provideZoneChangeDetection({ eventCoalescing: true }),
    { provide: APP_ID, useValue: 'mfe-evenement' },
    provideHttpClient(withFetch()),
  ],
};

@manfredsteyer
Copy link
Contributor

Hi,

do you call initFederation?

@joepeace01
Copy link
Author

joepeace01 commented Oct 17, 2024

yes, here is my main .ts file


import { initFederation } from '@angular-architects/native-federation';
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app/app.component';
import { appConfig } from './app/app.config';

initFederation()
  .catch((err) => console.error(err))
  .then((_) => bootstrapApplication(AppComponent, appConfig))
  .catch((err) => console.error(err))

@joepeace01
Copy link
Author

Hi @manfredsteyer, do you have any lead that could help me debug it ?

@egozavr
Copy link

egozavr commented Oct 25, 2024

Hi @joepeace01! In our app we also have microfrontends in different repositories. I discovered that even minimal version mismatch of shared library in mfe and shell causes native-federation-runtime to select version of mfe for it instead of shell's one.

Selection of version seems to happen here: https://github.com/angular-architects/module-federation-plugin/blob/main/libs/native-federation-runtime/src/lib/init-federation.ts#L104. getExternalUrl(shared) is getting lib from cache map which is previously set by shell config processing. The key in that map is strictly package name + package version.

We have solved our problem by setting versions of shared packages strictly equal in both repositories, without any ^ or ~.

Hope it will help.

@joepeace01
Copy link
Author

hi @manfredsteyer, back on this topic, wanted to know if you had the chance to look into it ? I'm confused cause I don't have this issue on my shell. They both have similar configurations except what's specific to shell and remote. I'm having those errors locally when starting the remote app on port 4201. None of the api calls are working, I only get a static version of the home page

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants