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()
],
};
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"
}
},