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

TypeError: Failed to fetch dynamically imported module: remoteEntry.js #766

Closed
desmondblue opened this issue Feb 17, 2025 · 4 comments
Closed

Comments

@desmondblue
Copy link

For which library do you need help?

module-federation

Question

Hello

I am in middle of upgrading angular version from 12 to 15 for a dynamically module federated project.
As part of that I was also trying to upgrade the angular architects module federation plugin from v12 to v15 when I encounter this error. I have tried a bunch of permutations with the webpack config but I keep running into different errors. Any help or insight on this would be much appreciated.
Before the fetch module error the console also prints the following error in line 1 of the remoteEntry.js:

Failed to load module script: Expected a JavaScript module script but the server responded with a MIME type of "application/json". Strict MIME type checking is enforced for module scripts per HTML spec. remoteEntryjs.1

  • In my shell I am directly using loadRemoteModule function to load the remote modules dynamically.

  • For the shell and mfe I have set the module, target, lib as es2022 in tsconfig.

  • As given in the readme for the repo I have defined the webpack config for the shell and mfe accordingly(attached below).

  • I have a guard which gets activated via the shell and loads the remote mfes in turn via routing. The code for the same is attached here. In the code pluginsConfig is populated in the mfe via a javascript and the information is fetched via a service inside the guard in another function.

    const pluginRoute: Route = {
      path: "remoteMfe",
      loadChildren: () =>
        loadRemoteModule({
          type: "module",
          remoteEntry: pluginsConfig.loadRemoteModuleOptions.remoteEntry,
          exposedModule: pluginsConfig.loadRemoteModuleOptions.exposedModule,
        })
          .then((m) => m.MfeModule])
          .catch((error) => this.handleLoadingErrorForPlugin(error, true))

The error for failing to fetch remote module happens inside this loadRemoteModule function.

Shell webpack.config.js:

const { withModuleFederationPlugin, share } = require('@angular-architects/module-federation/webpack');
const sharedDeps = import('plugin-externals').SHARED_MAP;
const MergeJsonWebpackPlugin = require("merge-jsons-webpack-plugin");
const mergeJsonPluginConfig =    new MergeJsonWebpackPlugin({...
});

const moduleFederationConfig  = withModuleFederationPlugin({

  shared: share({
    ...sharedDeps
  }),

});
moduleFederationConfig.plugins.push(mergeJsonPluginConfig);

module.exports = {
  ...moduleFederationConfig,
};

MFE webpack.config.js:

const { withModuleFederationPlugin, share } = require('@angular-architects/module-federation/webpack');
const sharedDeps = import('plugin-externals').SHARED_MAP;

const MergeJsonWebpackPlugin = require("merge-jsons-webpack-plugin");

const mergeJsonPluginConfig= new MergeJsonWebpackPlugin({...
});

const moduleFederationConfig = withModuleFederationPlugin({
  name: "pluginName",
  filename: "remoteEntry.js",
  library: { type: "module" },
  exposes: {
    [`./mfe`]: `./plugin/src/mfe-angular-module/mfe.module.ts`,
  },
  shared: share({...sharedDeps }),
});

moduleFederationConfig.plugins.push(mergeJsonPluginConfig)
module.exports = { ...moduleFederationConfig };

Shared map of dependencies looks like below:

export const SHARED_MAP= {
  '@angular/core': { singleton: true, requiredVersion: 'auto' },
  '@angular/animations': { singleton: true, requiredVersion: 'auto' },
  '@angular/compiler': { singleton: true, requiredVersion: 'auto' },
  '@angular/common': { singleton: true, requiredVersion: 'auto' },
  '@angular/common/http': { singleton: true, requiredVersion: 'auto' },
  '@angular/forms': { singleton: true, requiredVersion: 'auto' },
  '@angular/router': { singleton: true, requiredVersion: 'auto' },
  '@angular/cdk': { singleton: true, requiredVersion: 'auto' },
  '@angular/cdk/coercion': { singleton: true, requiredVersion: 'auto' },
  '@angular/cdk/drag-drop': { singleton: true, requiredVersion: 'auto' },
  '@angular/material/sort': { singleton: true, requiredVersion: 'auto' },
  '@angular/material/table': { singleton: true, requiredVersion: 'auto' },
  '@angular/cdk/scrolling': { singleton: true, requiredVersion: 'auto' },
  'ngx-webstorage': { singleton: true, requiredVersion: 'auto' },
  '@ngx-translate/core': { singleton: false, requiredVersion: 'auto' },
  'rxjs': { singleton:true, requiredVersion: 'auto' },
  'tslib': { requiredVersion: 'auto' },
  '@fortawesome/angular-fontawesome': {singleton: true, requiredVersion: 'auto',},
  '@fortawesome/fontawesome-svg-core': { singleton: false,requiredVersion: 'auto'  },
  lodash: { requiredVersion: 'auto' },
  '@ngrx/effects': { singleton: true, requiredVersion: 'auto' },
  '@ngrx/store': { singleton: true, requiredVersion: 'auto' },
 'moment': { requiredVersion: 'auto' },
  'ngx-toastr': { singleton: true, requiredVersion: 'auto' },
  'ngx-monaco-editor-v2': { singleton: true, requiredVersion: 'auto' },
};

I also tried to work with shareAll for sharing dependencies but ran into the #253 error. Any help or insight on this would be much appreciated. Thanks in advance.

@manfredsteyer
Copy link
Contributor

Can you please provide a minimal reproduction via github?

@desmondblue
Copy link
Author

desmondblue commented Feb 18, 2025

@manfredsteyer Thanks for the response. Unfortunately replicating the structure of the project would be a bit of work. I will try and come up with something or refine my question further.
The idea is essentially the mfe gets packaged with the backend and the pluginconfig details are fetched via rest APi which then allows me to plugin the mfe via the remoteentry.js without hosting the mfe as a separate web application. It is here where I get stuck with this mime type and failed to load module error.
Earlier with angular 12 configuration of the webpack for the remote mfe - I was utilizing library type "var" because that was the default in webpack config.
If I use the libary type as var in the remote plugin config now, I get the error:

Cannot use 'import.meta' outside a module (at remoteEntry.js:1)

and in the dynamic.federation.ts Cannot read properties of undefined (reading 'init') during container.init

@desmondblue
Copy link
Author

desmondblue commented Feb 18, 2025

@manfredsteyer After a little bit of tinkering around I was able to come up with a mrp that sort of mimics my problem. Upon trying to directly load the remoteModule in your example I get the import.meta error as well. Please see the link to the repo here
Pardon me this was a rather quick attempt at creating a mrp and it does not reproduce the issue that I face with the failed to load module.
I will try to come up with a mrp over the weekend it is quite tricky.
The idea of the project is to use the shell app as a common host for plugging in different gui's which have more or less the same dependency versions etc. It is while attempting to do this that I am stuck. I will do a good amount of research and work on this over the weekend and clarify my thoughts on this issue then.

@desmondblue
Copy link
Author

In the end the issue got resolved after removing shareall and only sharing a few deps

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

No branches or pull requests

2 participants