Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Support#577

Answeredbylili21
ScriptedAlchemy asked this question inQ&A
Jan 13, 2021· 72 comments· 180 replies
Discussion options

Welcome 🙏

Support questions, workaround, and implementation details questions can live here

You must be logged in to vote

any examples about versioning federation?

Replies: 72 comments 180 replies

Comment options

@ScriptedAlchemy any guidance around deployment of a large module federated app? I am looking to do exactly what you demonstrated on the shared-routing example with a shell and various feature MFs. When serving it seems that the plug-in manages setting up the n number of servers on ports, but when doing an actual production deployment, what are the best practices and examples here? How do you configure what the different remotes might be served from and are there ways that certain remotes can build and deploy only their changes safely without the shell?

Overall amazing work with this and really can’t wait to see more adoption of module federation in the community!

You must be logged in to vote
9 replies
@ScriptedAlchemy
Comment options

ScriptedAlchemyFeb 11, 2021
Maintainer Author

I'm working on federated unit tests so you'd be able to unit test the consumers / providers

Mocking or making an API module similar to a state data contract you have with a backend API, then you know all you need to test against is calling this API and it responding with the right thing. if the contract breaks - the API breaks and the test fails

@jacob-ebey
Comment options

@lili21 no article still but@jherr did an awesome video on the topic for the community:https://www.youtube.com/watch?v=ZFNxTy3fOO0

@jherr
Comment options

Yeah, I need to write the article on that one.

@ScriptedAlchemy
Comment options

ScriptedAlchemyJul 24, 2021
Maintainer Author

To mimic the multiple ports i have, use an ingress / CDN to route asset resources to specific folders or separate applications.

Federated unit tests work well (webpack build tests, then used code streaming & run jest against the bundle), also good ol cypress does the trick for some end to end smoke testing

@steven-pribilinskiy
Comment options

@ScriptedAlchemy how can we use code streaming?
should we use something likefetch/axios to load the module and add it to the node cache? e.g.

constreunited=(remotePath,name)=>`promise new Promise(resolve => {    const fetch = require("node-fetch");    fetch('${remotePath}').then(response => response.text()).then(moduleCode => {      require.cache[name] = moduleCode;      resolve(moduleCode);    });  })`
Comment options

@ScriptedAlchemy , first up, kudos to the team for the awesome work going on here.

I built a test app in TypeScript (React micro-frontends - container, header, landing page, auth page etc.) You can see code and demohere.

There are two issues I noticed and wanted to understand possible workarounds for these:

  1. The app does not scale very well on a mobile device. That is, the text, header size etc. is really small. Kinda like when you see a desktop version of the application on the mobile. Is this expected behavior in the current version? I tried running the local for thetypescript example from this repo and it seems to have a similar issue. Is there any plan on the roadmap towards a solution for this?

I'm attempting to workaround issue 1 by rendering a different set of microfrontends for the mobile app (albeit this is a sub-optimal approach). I will get back here on my experience with this workaround and how successful/effective the implementation turned out to be.

  1. When I change routes (say from landing to auth) -> the cleanup of useEffects inside landing is not fired. That is the landing micro-frontend is not unmounted. Any ideas for how I can work around this issue?
You must be logged in to vote
7 replies
@ashwanth1109
Comment options

@jacob-ebey , thank you for your reply. You are correct. I tried comparing header across a federation MFE, parcel MFE, monolith and plain index.html with 60px height set and they all looked the same. My apologies, I misunderstood the problem above

@jacob-ebey
Comment options

Does one have a<meta name="viewport" content="width=device-width, initial-scale=1" /> or similar while the other doesn't?

@ashwanth1109
Comment options

Yeah, you're right. That was the reason. How naïve of me! :)
Appreciate the answer 👍🏾

@mjRaza
Comment options

thanks for sharing the link. It helped me alot. can you please describe how did you deployed it? Like did you deployed all the modules on a single server or different?

@ashwanth1109
Comment options

@mjRaza , I'm glad it was helpful.
I'm using CDK (AWS) to deploy all my assets to a single S3 bucket (I have a CICD setup with github actions).
The container module is in the root of the bucket, and the header, landing, auth modules are in their respective folders -/header etc.
I'm giving atalk on this topic and share my experience to help others in my local community understand module federation and hopefully start using them. You can check it out if you'd like. :)

Comment options

@ScriptedAlchemy, thank you for putting all the hard work on this amazing feature.

Currently, I am trying to implement a module federation POC with the shell architecture. I noticed that module federation will disable tree-shaking on shared modules. Because of this , I am wondering is it true that we should only share non tree-shakable libraries only (e.g. react, react-dom but not lodash-es) ?

You must be logged in to vote
3 replies
@jacob-ebey
Comment options

It's not a hard rule but a good way to approach things. I'd only personally share modules if I know it'll exist in the consumer and you can't tree shake it. React Dom and React are perfect examples.

@ScriptedAlchemy
Comment options

ScriptedAlchemyJun 12, 2021
Maintainer Author

It really depends on what you need to share.

Generally I share anything that depends on context or singletons. I'm not totally convinced that sharing things like a dsm is always effective as they can end up being quite large.

So I usually prefer to share less code. Especially if I'm routing between pages or using progressive enhancements or lazy hydration. In those cases I'm not too upset by downloading like an extra 50kb if need be compared to having a higher initial hit

Sharing is a dongle edge sword and I'd rely on bundle analyzer to help you decide what's worth sharing vs not

Like material-ui/icons will add 5000 icons to your build 😂 not worth sharing haha

@einarq
Comment options

Hmm, this seems like something that it would be good to know more about. I know that some of the motivation for creating module federation in the first place was to be able to share code between apps, and only download the missing pieces. Right? At least I heard that in an interview recently :)
So one would intuitively think its a good idea to share as much as possible.

Comment options

any examples about versioning federation?

You must be logged in to vote
1 reply
@jacob-ebey
Comment options

You can find a solution utilizing unpkg here:

Remote:
https://github.com/jacob-ebey/versioned-federated-module

Host:
https://github.com/jacob-ebey/consume-versioned-federated-module

Answer selected byScriptedAlchemy
Comment options

Hi@ScriptedAlchemy,@jacob-ebey!
First of all, thanks a lot you for the amazing work.
Currently, I am trying to implement an example with webpack 5 module federation and got one error that I just can't solve.

remote:
new ModuleFederationPlugin({
name: 'app',
filename: "remoteEntry.js",
remotes: {
service01:
'service01@http://localhost:3001/remoteEntry.js'
},
exposes: {
'./ThemeToggleButton': paths.src + '/contexts/ThemeContext/ThemeToggleButton',
},
....
}),

host:
new ModuleFederationPlugin({
name: "service",
filename: "remoteEntry.js",
exposes: {
"./ServiceApp": "./src/components/App",
},
remotes: {
mainApp: "app@http://localhost:8080/remoteEntry.js",
},
....
}),

and

const ThemeToggleButton = React.lazy(() => import("mainApp/ThemeToggleButton"));

const App = () => (
< container >
< React.Suspense fallback="ThemeToggleButton" >
< ThemeToggleButton />
</ React.Suspense >
</ container >
);

image

I would be very grateful if you can help and tell what I am doing wrong. Thanks

You must be logged in to vote
4 replies
@jacob-ebey
Comment options

@KFilipenkov going to need more of a repo case. Preferably a whole repo...

@KFilipenkov
Comment options

@jacob-ebey thanks, fixed! everything is ok.

just hanged
output: {
path: path.resolve(__dirname, './dist'),
filename: '[name].bundle.js',
publicPath: '/',
},

to
output: {
publicPath: "auto",
},

@ScriptedAlchemy
Comment options

ScriptedAlchemyJun 12, 2021
Maintainer Author

Yep public path auto should solve it.

There's also a plugin floating out there to allow global variables to be used in the remotes path so you can set the urls at runtime

@sonalipurwar
Comment options

OMG , thank you for this.

Comment options

how to handle various environments with the same file nameremoteEntry?
let's say I got two environments,test andprod。and we are using CDN to load the js file. the test build process will bundle the js file and upload it to cdn,but thetest andprod using the same CDN and file name.

You must be logged in to vote
7 replies
@lili21
Comment options

hash the remoteEntry file name?

@jacob-ebey
Comment options

Go for it. There are plenty examples and community plugins posted throughout the help and issues here on this repo you can explore. I still say do not deploy two builds of the same app to the same environment. Seems like you're asking for trouble. Spin up a test environment.

@lili21
Comment options

In practice, the ci system won't care about env that much. it just runs the build, and upload the assets to the CDN。the benefit of this strategy is the cd will be very fast for any enviroment, just need to deploy the Html file, no need for rebuilding.

@jacob-ebey
Comment options

I'm not going to condone or support this. You do you.

@ScriptedAlchemy
Comment options

ScriptedAlchemyJun 12, 2021
Maintainer Author

I'd suggest a sub domain like stage.cdn or some other path or use an ingress to route to specific assets

Comment options

Hi guys-@ScriptedAlchemy@jacob-ebey
Thanks for all the good work.. !!!

I am using webpack latest version, I am using bi directional MF approach. Only problem I am facing for each env I have to build the bundle seperately as in remote :{ } we are providing absolute path.

Lot of discussion is going on finding any hack to provide the remote bundle url at run time not at build time..

Is there any solution for this so that I can use same bundle for all my env and can set remote bundle url dynamically at runtime?

One folk suggested this plugin, will it work

#566

You must be logged in to vote
3 replies
@jacob-ebey
Comment options

IDK, maybe give it a go and try it out?

@rajnishsingh
Comment options

Will webpack provide any solution to set remote url path in future release ?

Or can you please help if you have already found any solution or hack ?

@jacob-ebey
Comment options

use public path "auto" or pull one of the existing solutions and give it a go.

Comment options

does the module federation plugin provide any hooks?

You must be logged in to vote
3 replies
@lili21
Comment options

to access the plugin's option.

@jacob-ebey
Comment options

There are no hooks. If you need the options somewhere you can do something like this in the apply of a new plugin:

const federationPlugins =  compiler.options.plugins &&  compiler.options.plugins.filter(    (plugin) => plugin.constructor.name === "ModuleFederationPlugin"  );
@ScriptedAlchemy
Comment options

ScriptedAlchemyJun 12, 2021
Maintainer Author

Yep filter the constructor name or wrap the MF plugin in another abstraction so you can get the options passed to it. Then you can call the underlying plugin + do whatever else you need to

Comment options

https://github.com/module-federation/module-federation-examples/blob/master/shared-routes2/app1/src/App.js#L6

I wonder how this one can be loaded the sync way?

import { HashRouter, Route, Switch } from "react-router-dom";import Navigation from "app1/Navigation";import React from "react";import localRoutes from "./routes";import remoteRoutes from "app1/routes";const routes = [...localRoutes, ...remoteRoutes];const App = () => (  <HashRouter>    <div>      <h1>App 2</h1>      <Navigation />      <React.Suspense fallback={<div>Loading...</div>}>        <Switch>          {routes.map((route) => (            <Route              key={route.path}              path={route.path}              component={route.component}              exact={route.exact}            />          ))}        </Switch>      </React.Suspense>    </div>  </HashRouter>);export default App;
You must be logged in to vote
3 replies
@lili21
Comment options

I thought the remote module can only be load in the async way.

@jacob-ebey
Comment options

That's what the async bootstrap is there for. The loading is "hoisted" to that import statement therefor it can be used synchronously.

@ScriptedAlchemy
Comment options

ScriptedAlchemyJul 24, 2021
Maintainer Author

Yep Jacob is right, the async bootstrap at the top is the solution, it allows anything async to be hoisted to the nearest promise, in this case its hoisting it to the import(bootstrap) since thats the nearest promise where webpack can pause the script execution and wait for something to happen

Comment options

You must be logged in to vote
1 reply
@ScriptedAlchemy
Comment options

ScriptedAlchemyJun 12, 2021
Maintainer Author

Upgrade to angular 12 - its god full support

Comment options

I'm new to this and still figuring things out. I have module federation working great in my project. My question is around error capturing if a sub app is down. In other words I have shell calling child. In my development environment if I start the child app everything works as expected. But if I stop child app then shell app spins and gives me some errors as expected. My question is how do I handle this. I'm not entirely sure how I can capture the event error ofhttp://localhost:8081/remoteEntry.js (child app) not being available. I just want to be able to display a nice spinner while remote entry is loading and then display an error if the sub app is not available. Any help or suggestions would be appreciated.

You must be logged in to vote
5 replies
@jherr
Comment options

The Javascript for federated modules in development is served from your local server, but in production would be stored on S3 and served from there. And for S3 to be down would be a catastrophe for the entire Internet and is extremely unlikely. That being said, the Module Federation system in Webpack provides for a fallback where you can provide backup routes if the primary route changes. And also, depending on your framework, you can trap the issue with an error boundary and then use a backup mechanism, like asynchronously loaded code from an NPM module.

@Devinwhite
Comment options

Understood, thank you for the reply. In my instance I'm using multiple server locations. So there is a possibility that my hosted provider server hosting (child app) could go down. While my shell app on aws is working just fine. I was reading more about error boundaries right before you replied. So at least I was on the right track.

@jherr
Comment options

You should always host your static assets on something like S3, or Google's data service, or... Never serve them from a running server. And that's just outside of MF, that's just good practice. And honestly, those sites rarely go down. So if something happens it's probably because a bucket gets errantly deleted or something like that.

IMHO, I wouldn't worry as much about that as I would putting up new code that is incompatible with the code consuming it (different methods, props, etc.) The plus side there is that you will probably take place right after a deploy and when that happens and ready to rollback immediately.

@Devinwhite
Comment options

Understood. I'm investigating a solution for including app components from existing applications (old monoliths) into a new framework that uses newer tech stack which will eventually break down and take over the monolith. So the included child app is a server side application that is hosted at a facility not on AWS. I agree 100% with what you're saying if I was starting fresh.

I did figure out the solution. It may not be elegant but it works.@jherr I think you'll appreciate this in particular because the proof of concept app I'm building is based on some MF videos you made. You may recognize the module names.

importReact,{lazy,Suspense}from'react';importReactDOMfrom'react-dom';import'./index.css';constDogWidget=lazy(()=>import('host/DogWidget').catch(()=>import('./ErrorMessage')));constApp=()=>(<div><Suspensefallback={<div>Loading...</div>}><DogWidget/></Suspense></div>);ReactDOM.render(<App/>,document.getElementById('app'));
@ScriptedAlchemy
Comment options

ScriptedAlchemyJun 12, 2021
Maintainer Author

Remotes can accept an array of urls in the event one origin is down.

Best bet is Jack's resilient component pattern if you want afford critical components to be down. Otherwise you're betting on the CDN to be online. If it's down you'd likely have bigger problems though haha.

Good logging practices are always encouraged so you're aware of any possible outage or failure.

I also leave previous deploys on the CDN so that when deploying assets don't go missing mid deploy for users who already landed on the site

Comment options

I am currently developing a project respecting a microfrontend architecture using Webpack5 Module Federation and Angular. I am dealing with a somewhat anondin problem. Indeed, all my microfrontends (remote) work perfectly alone but when integrating them into the shell (host). I have an error that appears and shows some bugs on the application.

ERROR TypeError: You provided an invalid object where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.

This error comes from Angular Core and especially when there is an integrated Angular Material component.

The craziest thing about this problem is that it’s no longer there when I activate the chrome extension "Redux Dev Tools".
Do you have any ideas ?

There’s probably a problem with sharing libraries, but I don’t know where?

My various configs of the host and remotes:
Shell :

    new ModuleFederationPlugin({      remotes: {          // all remotes that will be used in the shell          'designer': "designer@http://localhost:4201/remoteEntry.js",          'library':"library@http://localhost:4202/remoteEntry.js"        },      shared:  {        // all libraries that will be shared with microfrontends        "@angular/core": { singleton: true, strictVersion: false },        "@angular/common": { singleton: true, strictVersion: false },        "@angular/router": { singleton: true, strictVersion: false },        "@angular/forms":{ singleton: true, strictVersion: false },        "@angular/cdk":{ singleton: true, strictVersion: false },        "@angular/material":{ singleton: true, strictVersion: false },        //"@ngx-translate/core":{ singleton: true, strictVersion: false },        "@bl/auth-token": { singleton: true, strictVersion: false },        //"@bl/elements": { singleton: true, strictVersion: false },        "@bl/theme": { singleton: true, strictVersion: false },        "@bl/shared": { singleton: true, strictVersion: false },        "@bl/bl-app-layout": { singleton: true, strictVersion: false },      }  })

Remote 1 :

new ModuleFederationPlugin({                // For remotes (please adjust)      name: "library",      filename: "remoteEntry.js",      exposes: {        './web-components': './src/bootstrap.ts',      },              shared:  {        "@angular/core": { singleton: true, strictVersion: false },        "@angular/common": { singleton: true, strictVersion: false },        "@angular/router": { singleton: true, strictVersion: false },        "@angular/forms":{ singleton: true, strictVersion: false },        "@angular/cdk":{ singleton: true, strictVersion: false },        "@angular/material":{ singleton: true, strictVersion: false },        //"@ngx-translate/core":{ singleton: true, strictVersion: false },        "@bl/auth-token": { singleton: true, strictVersion: false },        //"@bl/elements": { singleton: true, strictVersion: false },        "@bl/theme": { singleton: true, strictVersion: false },        "@bl/shared": { singleton: true, strictVersion: false },        "@bl/bl-app-layout": { singleton: true, strictVersion: false },      }    }),

Remote 2:

new ModuleFederationPlugin({                // For remotes (please adjust)      name: "designer",      filename: "remoteEntry.js",      exposes: {        './web-components': './src/bootstrap.ts',      },              shared:  {        "@angular/core": { singleton: true, strictVersion: false },        "@angular/common": { singleton: true, strictVersion: false },        "@angular/router": { singleton: true, strictVersion: false },        "@angular/forms":{ singleton: true, strictVersion: false },        "@angular/cdk":{ singleton: true, strictVersion: false },        "@angular/material":{ singleton: true, strictVersion: false },        //"@ngx-translate/core":{ singleton: true, strictVersion: false },        "@bl/auth-token": { singleton: true, strictVersion: false },        //"@bl/elements": { singleton: true, strictVersion: false },        "@bl/theme": { singleton: true, strictVersion: false },        "@bl/shared": { singleton: true, strictVersion: false },        "@bl/bl-app-layout": { singleton: true, strictVersion: false },      }    }),
You must be logged in to vote
1 reply
@ScriptedAlchemy
Comment options

ScriptedAlchemyJun 12, 2021
Maintainer Author

Sorry I don't on this one. Not an angular person but it looks like something might not be shared or it's not pulling the export off the object? Kind of like when you pass something wrong to react lazy and it can't find the default export?

Comment options

I am trying to runmulti-threaded-ssr, its complaining @module-federation/federated-runtime-plugin@* is not found in the npm registry, is the package json up to date?

You must be logged in to vote
4 replies
@ScriptedAlchemy
Comment options

ScriptedAlchemyJun 3, 2021
Maintainer Author

I'll have to try running that example again. It's been a while

@dileep8014
Comment options

ok sounds good, I think the @module-federation/federated-runtime plugin is not available in the npm registry or might have been changed?

@jacob-ebey
Comment options

It says right in the README:

Unless you are an author of StreamedFederation, you WILL NOT be able to run this.

@ScriptedAlchemy
Comment options

ScriptedAlchemyJun 12, 2021
Maintainer Author

A Microsoft engineer released a open plugin that was based off our last public release which only worked pre-stable webpack.

I have never used it so I can't say how reliable it is.

Our streaming plugin is not open source for webpack stable

Comment options

Hi guys! I hope everyone is okay!
I'm currently working on a project that has been migrated from CRA to webpack5 so module federation can be used. And then I developed a micro-frontend that exposes some components and contexts to handle authentication workflow. Here is the point, when my first app consumes it synchronously, aparently all works just fine, but I got this error console:

Uncaught (in promise) Error: Container initialization failed as it has already been initialized with a different share scopewhile loading "./AuthProvider" from webpack/container/reference/authwhile loading "./AccessDenied" from webpack/container/reference/authwhile loading "./Login" from webpack/container/reference/authwhile loading "./PublicRoute" from webpack/container/reference/authwhile loading "./PrivateRoute" from webpack/container/reference/auth    at Object.init (remoteEntry.js:56)    at initFn (bundle.js:394)    at async Promise.all (:3000/index 0)

Auth App

new ModuleFederationPlugin({      name: 'auth',      filename: 'remoteEntry.js',      exposes: {        './AccessDenied': './src/core/components/AccessDenied',        './UnauthorizedModal': './src/core/components/UnauthorizedModal',        './PrivateRoute': './src/core/components/PrivateRoute',        './PublicRoute': './src/core/components/PublicRoute',        './Login': './src/core/pages/Login',        './AuthProvider': './src/core/contexts/auth',      },      remotes: {},      shared: {        ...dependencies,        'react-router-dom': {          requiredVersion: dependencies['react-router-dom'],          singleton: true,        },        'react-dom': {          requiredVersion: dependencies['react-dom'],          singleton: true,        },        react: {          requiredVersion: dependencies.react,          singleton: true,        },        axios: {          requiredVersion: dependencies.axios,          singleton: true,        },       // custom design system lib        'ui': {          singleton: true,        },      },    }),

Consume App

new ModuleFederationPlugin({      name: 'consumer',      filename: 'remoteEntry.js',      remotes: {        auth: 'auth@http://localhost:8080/remoteEntry.js',      },      exposes: {},      shared: {        ...dependencies,        'react-router-dom': {          requiredVersion: dependencies['react-router-dom'],          singleton: true,        },        'react-dom': {          requiredVersion: dependencies['react-dom'],          singleton: true,        },        react: {          requiredVersion: dependencies.react,          singleton: true,        },        axios: {          requiredVersion: dependencies.axios,          singleton: true,        },       // custom design system lib        'ui': {          singleton: true,        },      },    }),

I don't know if I understand what the error mean, but how can the container has already been initialized with a different share scope?

You must be logged in to vote
4 replies
@ScriptedAlchemy
Comment options

ScriptedAlchemyJun 12, 2021
Maintainer Author

Are you using the low level api to initialize any dynamic remotes? I have only seen this when someone uses the vanilla api to initialize containers.

@mayckcoelho
Comment options

I figure it out! I was having a problem with webpack not finding thebundle.js file when the window reloads so I put a reference on theindex.html.

<div>    <!-- this is where the root react component will get rendered --></div><script src="/bundle.js"></script>

And that was creating the lost share scope. I removed the script and the error console disappeared. Everything seems to work now except I went back to the first problem haha

Tks man!

@vijay-qburst
Comment options

Are you using the low level api to initialize any dynamic remotes? I have only seen this when someone uses the vanilla api to initialize containers.

Yes I am, I followed this example:https://github.com/module-federation/module-federation-examples/blob/master/nextjs-client-only/nextjs/components/LoadNextMF.jsx#L5

In my case 1. root NextJS app mounts a 2. react app (on a particular path), both of which use another 3. shared react app that shares several components. So when navigating from a NextJS route to React route this error occurs. Interestingly if we reload the app on the same URL, the error doesn't occur. Order of loading issue may be? Is it possible to avoid this error and just use the already initialized container?

@ScriptedAlchemy
Comment options

ScriptedAlchemyJul 28, 2021
Maintainer Author

You'd want to use the nextjs example. Nextjs depends on nextjs-mf which is a paid plugin in other to make it work properly.

You can only initialize a remote once. So if you're lazy load if additional remotes they cannot re-inject updated share scope into existing remotes that were already initialized.

It causes object reference issues since you'd need to basically hot reload it to make the references cascade

A workaround is to remove the remote and reinject them again which could cause them to have the updated share scopes

Comment options

Hi@ScriptedAlchemy@jherr

I'm working on a SPA, In which i have a application shell and number of micro-frontends that are loaded based on the route configuration. I have achieved this with the help of webpack's module federation plugin.

Now i wanted to communicate UI state / data between micro-frontends, i have preferred Pub/Sub model of communication between the MFE's. But I don't want the Pub/Sub to be a global API whereas i wanted it to be local between the parent and child.

The issue i'm facing is :

While Sharing the Pub/Sub code between Micro Frontends, Every time a new instance of the Pub/Sub is being created, But I wanted a single instance of Pub/Sub between parent and child.

The reason for the issue being the file is being completely loaded using webpack.require rather than sharing the instance alone.
How can i overcome this isuse/ Or should i use any other way of communication?

You must be logged in to vote
5 replies
@ScriptedAlchemy
Comment options

ScriptedAlchemyJun 22, 2021
Maintainer Author

You can probably use sharing to share a single instance between the applications. Similar to how the shell shares service in shared-routing

@nayeembadhusha
Comment options

Thanks man! that worked :)

@NikJ87
Comment options

Hi@nayeembadhusha,@ScriptedAlchemy

I'm also struggling with similar issue. Could you help me to point with some examples to implement it right way ?

Thanks
Nik

@ScriptedAlchemy
Comment options

ScriptedAlchemySep 29, 2022
Maintainer Author

use recoil shared as a singleton

@ScriptedAlchemy
Comment options

ScriptedAlchemySep 29, 2022
Maintainer Author

use recoil shared as a singleton

Comment options

Sorry@ScriptedAlchemy, got another questions.

Can you suggest a best practice on usingeager: true? Is it correct if we use this to reduce the number of chunks downloaded?

For instance, I have ashell andchild application, and they are sharing 10 dependencies whose size are < 10KB. If I put these 10 dependencies intoshared withouteager: true, then the plugin will break up these 10 dependencies into 10 small chunks, and there will be 10 different network request. I feel this is a bit overwhelming and performs bad in HTTP 1.1 ?

However if seteager: true, these dependencies will be included in theshell bundle so those small chunks won't be downloaded. Of course the shell chunk and it'sremoteEntry will be bigger, but this reduces the number of network request.

Is this actually an intended usage ofeager: true?

You must be logged in to vote
0 replies
Comment options

Hey Folks,

I wanted to use dynamic federated module loading in a web worker, so I adapted some of the advanced API examples to work in a web workers.Example here in case it helps anyone else.

Cheers,

You must be logged in to vote
0 replies
Comment options

Has anyone made any progress with exposing components from the new nextJs 13app directory architecture (which replaces pages)?

Currently, when I do this, I getcreateContext only works in Client Components

I'm particularly interested in this because in modularises the server side code, rather than at the _app.tsx entry point (which is incompatible with module federation)

You must be logged in to vote
1 reply
@jare25
Comment options

Hi all!

I have react app (localhost:3000), used as host. I have two remotes build with svelte. Both build with webpack 5, and module federation. On localhost everything works as expected, but when I deploy one remote (child) app on i.e. azure static websites, i.e. svelte2.remote.com and use it as remote on local host app - it gets svelte2.remote.com/remoteEntry.js, and after that it tries to get localhost:3000/585.js, instead of svelte2.remote.com/585.js.

Any ideas on what am I doing wrong?

Thanks!

Comment options

Hi Team-@ScriptedAlchemy / all Developers,

I have worked with custom elements previously in angular. Now am trying to use Modular Federation approach to load mfe. I am using different versions in angular for different mfe's. I am using custom element approach in modular federation(https://www.angulararchitects.io/en/aktuelles/multi-framework-and-version-micro-frontends-with-module-federation-your-4-steps-guide/). As a Custom element it will work when we downloaded the build js files in browser and add the "tag or attribute" to dom.
My doubt is custom element can work independly we all aware of it, but how does the sharing libraries comes into picture, if its a modular federation web components. How it really now downloading the packages if we keep it shared library in shell. Even if we have same version and go with custom element approach in modular federation as it has its own bundled files. While building the application separately, it never knows the shell shares. I really don't know how it avoids the duplicate package to load again. On runtime how it negotiates. I may be wrong in conveying or getting things right.

"Your help to understand me is highly appreciable"

Thanks all for the support.

You must be logged in to vote
0 replies
Comment options

Hi@ScriptedAlchemy, team,
I would like to say a big thank you for making SSR version free to use. Here is our case, I believe to get some ideas about it.

We have a pretty big application that uses Marionette and Preact 8 with SSR. It has a big codebase, which is bundled by Webpack 4. Let's call itBase Repository.
What is the most convenient way to feed to this application Microfrontends from another mono-repository(let's call it Monorepo) which is going to be written in React 18?

I see it as the following approach:

  1. Upgrade Webpack 4 to Webpack 5, add ModuleFederationPlugin inBase Repostory
  2. Do not share any dependencies (for the sake of simplicity) betweenBase Repository aka host app andMonorepository apps
  3. Leverage NX, ModuleFederation functionality, and all great features insideMonorepository

Will it work with SSR? Is there a simpler solution? The less we touchBase Repository application logic the better.
Thank you!

image

You must be logged in to vote
1 reply
@Carduelis
Comment options

Am I correct we can utilizereact-loadable example?
Am I correct, we can load any React version, by providingHTML node ? And the library@loadable/component will manage everything?

Comment options

@ScriptedAlchemy , is there a way to check what a package version is resolved to?
Scenario:
We have a host app that uses package x version 1.0.0 .
We have a client app that uses package x version 2.0.0
We have several other apps that use package x version we don't know.

There is a bug that does not happen locally when application is running in dev mode, but happens only when all mfes are deployed. We suspect that this is a specific bug with one of the packages, but we cannot figure out the version of the package x that is used by the mfe in prod mode.

You must be logged in to vote
1 reply
@ScriptedAlchemy
Comment options

ScriptedAlchemyApr 25, 2023
Maintainer Author

Console logwebpack_share_scopes in your build then check it on browser. If you expand into default.react.version.from == “oneWhoVendes”

Comment options

Hello@ScriptedAlchemy

I'm new in Next.js Module Federation, I just came up with issue about exposedPages, innext2 module I've page calledprofile.tsx where I use image, I try to put that page innext1 but image is not showing because I usenext/image component which renders on server and saves in.next folder andnext1 doesnt have access onnext2.next folder so is there any solution fix to that? or I should avoid usingnext/images

Thanks

You must be logged in to vote
1 reply
@ScriptedAlchemy
Comment options

ScriptedAlchemyApr 25, 2023
Maintainer Author

Try extraOptions from my plugin readme. There’s a option to try and patch image resources.

Comment options

Hello again@ScriptedAlchemy

Currently working with nextjs module federations which uses tailwind as styling, in current module tailwind works pretty well but when I export for example page or component viaexpose orexposedPages styles are no longer applying in on module, for example ifnext2 module has stylings and imoporting it innext1, after runningnext1 locally,next2 is showing up but not its stylings is there any solution to fix that?

this is my next1next.config.js

const{ NextFederationPlugin}=require("@module-federation/nextjs-mf");/**@type {import('next').NextConfig} */constnextConfig={reactStrictMode:true,images:{domains:["avatars.githubusercontent.com"],},css:{modules:true,global:["./src/styles/global.css"],// Add the path to the styles.css file},webpack:(config,options)=>{const{ isServer}=options;config.plugins.push(newNextFederationPlugin({name:"next1",remotes:{next2:`next2@http://localhost:3001/_next/static/${isServer ?"ssr" :"chunks"}/remoteEntry.js`,},filename:"static/chunks/remoteEntry.js",exposes:{"./footer":"./src/components/Footer/index.tsx","./header":"./src/components/Header/index.tsx",},shared:{tailwindcss:{eager:true,singleton:true,},},}));returnconfig;},};module.exports=nextConfig;

if any farther configurations are necessary, mention it and I'll send here

Thanks

You must be logged in to vote
3 replies
@mblancodev
Comment options

Styles aren't shareable through the MF

@ScriptedAlchemy
Comment options

ScriptedAlchemySep 29, 2024
Maintainer Author

Styles can be shared

@ScriptedAlchemy
Comment options

ScriptedAlchemySep 29, 2024
Maintainer Author

If you dont import the css in the component though, then how would webpack know it supposed to load that. IF you import global at top of app, federation doesnt see any dep in the leaf node, so it doesnt load it.

Comment options

I'm wondering if it's generally wise or a bad idea to spread thepackage.json dependencies into theshared object, and whether this would be a good or bad idea in one or both of the Host or Component apps?

You must be logged in to vote
1 reply
@ScriptedAlchemy
Comment options

ScriptedAlchemySep 29, 2024
Maintainer Author

not a great idea, cant tree shake shared modules, generally i only share what i need to, not share everything always.

Comment options

I am creating a POC for a new webstite with react and module federation with webpack. I have the following micro frontends, a shell, a menu and a filter bar, everything works as expected when the shell app put together the rest of apps. I want some guidance on how I can get the bundles generete of each micro frontend and render separetly in the old website app through a html script tag. This is because while I am developing the new site I want to be able to test some components in the old website with real clients.

Thanks 🙏

You must be logged in to vote
0 replies
Comment options

Hi@ScriptedAlchemy,

Thanks for the great work!. We're thriving with micro frontend because of your contribution.

I'm usingModuleFederationPlugin and trying to intercept the chunk request to append query params by using the below function

__webpack_get_script_filename__ = chunkId => { const filename = original(chunkId); returnjs=${filename}?foo=bar; };

This function used to be injected via entry option in the webpack config with the same name as we would give in the ModuleFederationPlugin.

I have referred your suggestion from this postModule Federation and Custom startup code

"The entry point naming trick takes advantage of module and chunk merging.
If two entry points have the same group or chunk name, they are merged. That's how cacheGroups works. "

It used to work fine but now this seems broken where the chunk merges incorrectly as it exports the startup code as the exported module. As it is mentioned by you as a dirty workaround, what is the recommended way of doing it ?

Do you have any suggestion?

You must be logged in to vote
2 replies
@ScriptedAlchemy
Comment options

ScriptedAlchemyAug 26, 2023
Maintainer Author

Google webpack module variables. You can patch or replace chunk load function at runtime on the fly

@cjkumaresh
Comment options

Thanks@ScriptedAlchemy for the suggestion.As this would require the replace chunk function to be part of the host and we would have to identify every request and replace if it is for the remote and skip otherwise so I thought it would be better if we scope thewebpack_get_script_filename function to be part of the remote Entry itself. Please let us know if there is such option available.

Comment options

@ScriptedAlchemy ,

There is a webpack concept ofComponents library as container. Do you recommend or have any examples related to this ?

You must be logged in to vote
0 replies
Comment options

Hi@ScriptedAlchemy,

I've been struggling trying to implement HMR or a least hot reload usingthis React 18 SRR example usingrenderToPipeableStream

I tried many things from using@module-federation/fmr or even thisfast-refresh-express example repository that uses SWC which is similar to themulti-threaded-ssr example. I tried to merge their implementations but couldn’t make it work.

Could you tell us how we could get at least hot reload or hot module replacement working with ReactrenderToPipeableStream?

Thank you so much 🙏

You must be logged in to vote
0 replies
Comment options

Hello everyone,

I'm trying to build a micro fe project with next 14 project and I'm kinda stuck whether it is possibile or not to create remotes with the standalone build.

After build the next files are inside standalone folder (duh?) and yes the remotes are being generated but outside of it, and of course if I try to run my next apps withnode server.js yes apps as single entities will work but remotes wont since they are outside the standalone folder.

So my question is,does module federation supports next standalone build? In order to make remotes works, do I also need to consider the.next/static/chunks/* and.next/static/ssr/* folders by cutting them inside standalone folder on build process or is there another pratice to make this work?

Here is the projecthttps://github.com/Staslios/federated-next-monorepo

Sorry for the poor knowledge but I am still learning both Next and MF, any help is appreciated even external resources or yt videos, thank you all.

You must be logged in to vote
3 replies
@ScriptedAlchemy
Comment options

ScriptedAlchemySep 29, 2024
Maintainer Author

youd need to host those folders publically as well so they can be accesses over the internet etc.

@Staslios
Comment options

@ScriptedAlchemy Thank you for your kind answer. In simpler words I should consider a separate process build for app and remotes ? Something like a standalone build for the app and then a secondary build for the remotes only, I cannot make all in one build standalone + client remote + ssr remotes, correct me if I'm mistaken.

I saw the other demos you made but withvanilla react, you set like a webpack.shared, webpack.client and webpack.remote, I should proceed with something similar for next ?

@ScriptedAlchemy
Comment options

ScriptedAlchemyOct 23, 2024
Maintainer Author

Just cp the files into standalone directory if they are in wrong place

Comment options

Hi, I have been trying to integrate microfrontends in our monolithic application, and I have been indecisive about using static imports across remotes, because of error handling reasons similar toabove.

If I take the above example,

With dynamic federation

import React, { lazy, Suspense } from 'react';import ReactDOM from 'react-dom';import './index.css';const DogWidget = lazy(() => import('host/DogWidget').catch(() => import('./ErrorMessage')));const App = () => (    <div>        <Suspense fallback={<div>Loading...</div>}>            <DogWidget />        </Suspense>    </div>);ReactDOM.render(<App />, document.getElementById('app'));

Now, with static federation, what would be the equivalent way to show an error state?

import React, { lazy, Suspense } from 'react';import ReactDOM from 'react-dom';import './index.css';import DogWidget from 'host/DogWidget'; // Nowhere to catch error?const App = () => (    <div>         <DogWidget />    </div>);ReactDOM.render(<App />, document.getElementById('app'));

I have the following questions:-
Question 1: Across MFs there is a higher chance one of them could go down independently from other MFs. In such a case, it is important for MF1 to handle error states when it can't load something from a Remote. This is easy with the dynamic case as shown above, but in the static case, I don't have a promise, so how would I handle the error state in the second case?

Question 2: I have a lot of legacy code, so static imports might be the only way to migrate while still being independently deployable. Along these lines, I am planning to statically import hooks and utils from remotes as well. My doubt is that if I import 10 hooks in a chunk, I expect that webpack will create a new chunk for each of these 10 hooks. This might mean that I will have 10 more network calls for loading a chunk, compared to what I had in the monolith. I would like to know firstly if this is a valid concern.

If yes, is there a way to "group" multiple exposes to the same chunk to avoid too many network calls. I would also like to confirm if this is supported out of the box by webpack Module federation, or would I have to do some custom plugin magic to support my use-case?

You must be logged in to vote
1 reply
@ScriptedAlchemy
Comment options

ScriptedAlchemyAug 4, 2025
Maintainer Author

Error load remote hook via runtime plugin. Check our doc site or runtime plugin dir in this repo

Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Category
Q&A
Labels
None yet
76 participants
@jherr@einarq@itapingu@vaindil@stevebrowndotco@clemente-raposo@dcesiel@ToLive@mdsmith00@daem0ndev@steven-pribilinskiy@Carduelis@vijay-qburst@cjkumaresh@lili21@mstelz@Devinwhite@CaffeinatedCodeMonkey@skingston91@jare25@dileep8014and others

[8]ページ先頭

©2009-2025 Movatter.jp