0

I have a host and two micro front ends (All are angular 14). This works fine in local development. Finally I containerized them and ran in docker. My host container trying to get the remoteEntry.js from the two micro front end containers, while doing so CORS error arises.

Please advice how to overcome this.

Access to script at 'http://localhost:3000/remoteEntry.js' from origin 'http://localhost:5000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

My webpack.config.js of one of the two mfe

const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");
const mf = require("@angular-architects/module-federation/webpack");
const path = require("path");
const share = mf.share;

const sharedMappings = new mf.SharedMappings();
sharedMappings.register(
  path.join(__dirname, '../../tsconfig.json'),
  [
    /* mapped paths to share */
    '@shared'
  ]);

module.exports = {
  devServer: {
    allowedHosts: 'all',
    headers: {
      "Access-Control-Allow-Origin": "*",
      "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS",
      "Access-Control-Allow-Headers": "X-Requested-With, content-type, Authorization"
    }
  },
  output: {
    uniqueName: "medicalcoding",
    publicPath: "auto"
  },
  optimization: {
    runtimeChunk: false
  },
  resolve: {
    alias: {
      ...sharedMappings.getAliases(),
    }
  },
  experiments: {
    outputModule: true
  },
  plugins: [
    new ModuleFederationPlugin({
      library: { type: "module" },

      // For remotes (please adjust)
      name: "medicalcoding",
      filename: "remoteEntry.js",
      exposes: {
        './Module': './projects/medicalcoding/src/app/app.module.ts',
      },

      // For hosts (please adjust)
      // remotes: {
      //     "mainapp": "http://localhost:5000/remoteEntry.js",
      //     "paymentposting": "http://localhost:4200/remoteEntry.js",

      // },

      shared: share({
        "@angular/core": { singleton: true, strictVersion: true, requiredVersion: 'auto' },
        "@angular/common": { singleton: true, strictVersion: true, requiredVersion: 'auto' },
        "@angular/common/http": { singleton: true, strictVersion: true, requiredVersion: 'auto' },
        "@angular/router": { singleton: true, strictVersion: true, requiredVersion: 'auto' },

        ...sharedMappings.getDescriptors()
      })

    })
    , sharedMappings.getPlugin()
  ],
};

My webpack.config.js of host

const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");
const mf = require("@angular-architects/module-federation/webpack");
const path = require("path");
const share = mf.share;

const sharedMappings = new mf.SharedMappings();
sharedMappings.register(
  path.join(__dirname, '../../tsconfig.json'),
  [
    /* mapped paths to share */
    '@shared'
  ]);

module.exports = {
  output: {
    uniqueName: "mainapp",
    publicPath: "auto",
    scriptType: 'text/javascript'
  },
  optimization: {
    runtimeChunk: false
  },
  resolve: {
    alias: {
      ...sharedMappings.getAliases(),
    }
  },
  experiments: {
    outputModule: true
  },
  plugins: [
    new ModuleFederationPlugin({
      library: { type: "module" },

      // For remotes (please adjust)
      // name: "mainapp",
      // filename: "remoteEntry.js",
      // exposes: {
      //     './Component': './projects/mainapp/src/app/app.component.ts',
      // },        

      // For hosts (please adjust)
      remotes: {
        "medicalcoding": "http://localhost:3000/remoteEntry.js",
        "paymentposting": "http://localhost:4000/remoteEntry.js"
      },

      shared: share({
        "@angular/core": { singleton: true, strictVersion: true, requiredVersion: 'auto' },
        "@angular/common": { singleton: true, strictVersion: true, requiredVersion: 'auto' },
        "@angular/common/http": { singleton: true, strictVersion: true, requiredVersion: 'auto' },
        "@angular/router": { singleton: true, strictVersion: true, requiredVersion: 'auto' },

        ...sharedMappings.getDescriptors()
      })
    }),
    sharedMappings.getPlugin()
  ],
};

Alphonse
  • 37
  • 8

1 Answers1

1

Technically, different ports are different domains. So, even if these microfrontends are coming from localhost, their ports are different and have to be whitelisted in your server. You didn't provide information about the server part so it's difficult to say where and what exactly you should change since every implementation is different.

Basically, you have to whitelist your calling domain in the server. For a explanation on how cors works, take a look at MDN

Since you wrote this is an angular application, I guess you are using Webpack to serve these apps. In your devServer, you can set CORS headers:

devServer: {
  ...,
  headers: {
    "Access-Control-Allow-Origin": "*",
    "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS",
    "Access-Control-Allow-Headers": "X-Requested-With, content-type, Authorization"
  }
},
brubs
  • 1,259
  • 8
  • 23
  • Hi, My host app is running on http://localhost:5000, on-load this host app is trying to get the `remoteEntry.js` from http://localhost:3000/ and http://localhost:4000/ (Two mfe). I understand I've to enable CORS in these two mfe but do not know, how to do it in webpack.config.js. Since these two mfes are angular apps, not API – Alphonse Mar 02 '23 at 13:54
  • Also I'm running the docker container in my local machine. I've not hosted it anywhere still. – Alphonse Mar 02 '23 at 13:56
  • I edited my answer adding an example for webpack. please note the webpack devServer is meant only for development environments. – brubs Mar 02 '23 at 13:57
  • If it is an API , I know how to add allow orgin headers. But these are angular apps – Alphonse Mar 02 '23 at 13:57
  • Unfortunately I am getting the same error again – Alphonse Mar 02 '23 at 14:14
  • Can you post your webpack config? – brubs Mar 02 '23 at 16:20
  • I've added them in my question now – Alphonse Mar 03 '23 at 03:12
  • That should be working. Which browser are you using? Note that chrome won't allow CORS on localhost. Have you tried with any other browser? https://bugs.chromium.org/p/chromium/issues/detail?id=67743 – brubs Mar 03 '23 at 09:49
  • But we have a restriction that our clients should only use Chrome. But chrome throws CORS error. So I have added the custom http header `add_header Access-Control-Allow-Origin "*";` in my nginx config file. Now it is working – Alphonse Mar 03 '23 at 10:13
  • 1
    You didn't mention you were using nginx, there were multiple issues then. If this answer fixes the issue in other browsers it should be accepted, since it solves a generic problem not related to business constraints. – brubs Mar 03 '23 at 12:46
  • can anyone please help here https://stackoverflow.com/questions/75958591/nx-mfe-angular-module-federation-not-able-to-access-remote-micro-front-end – Pranav MS Apr 10 '23 at 22:07