Thanks for this man, was looking how to setup different URL paths for development and production because all I'm getting was a blank white page (like you showed early on the video ^^).
Thanks Jack, This is very helpful and practical video. I had some queries, after going through comments and your reply, all resolved now, But if you create new video that include these comments questions-answers then it would be so helpful to others .
Hey jack, constantly following you for micro-frontend concepts and really amazing content. I wanted to know when we are exposing the module the remoteEntry.js file is also accessible to the consumer app. How to add some authentication to that endpoint. i don't want everyone to use it. Thank you.
Remote modules are just Javascript files. They should be deployed via S3 or CDN and do not rely on the host application running in order to serve them. You could put some security around the modules, I suppose, but do you do that with the JavaScript you deploy now? Secure your API endpoints, thats the most important thing.
Blargh! I knew there was something I forgot to add to the video. I was intending to cover that and to use environment variables for it. So like: > LOCAL_REMOTES=header yarn dev And then I'd do: const localRemotes = (process.env.LOCAL_REMOTES || "").split(','); To break it out into an array in webpack.config.js. Then in the `remotes` key definition I'd switch on localRemotes.includes('header') or something like that.
In the consumer app we are referring to /remoteEntry.js but in actual production we would have some CDN which will append some kind of HTTP Cache hearders which will cache this file, so how to version remoteEntry.js so that caching this remoteEntry File is not a issue
very nice video, is possible specify a branch name for shared header ? i.e. in header repository creata a branch named "blue" , in the consumer app in the remote section i can specify the branch "blue"?
No, that's not right. We only run them on different ports in development. In production everything should be deployed to something like S3 and served off of port 80 or 443.
I want to keep code in one repo and divide into separate features like ProductPage, CartPage, CategoryListingPage and different team is working on each separate features. I want a freedom on build & Deployment of features separately without running on multiple ports, can you please suggest approach, tool to achieve this requirement
Use a monorepo like Nx or Turborepo and have each team have their own module with their own features. Or if you are using the App Router you can use route groups to give each team their own dedicated folder.
When it comes enterprise we will have different ENV like SIT, UAT and PROD each with different urls, how can we dynamically load individual environment urls with one config setup? Can you please answer this question?
Your channel is underrated. I enjoy these videos even tho I found you just now through an article that I was searching for new features in webpack 5. A question popped while watching this video is how would we prevent other applications trying to get specific remoteEntry files to see what that code does? (Keep in mind I haven't played around with webpack5 yet). I suppose we could use minification? But that requires a sourcefile for it, would be have to store that also on a dedicated place for both apps to access? Thanks for the content!
Thanks! In production the remoteEntry.js would be minified and uglified, but that's just security through obscurity. Honestly, I don't think Module Federation is any more or less than any other code you to the client. From a security perspective I think of it as largely similar to code splitting. The only difference being that you are exposing named entry points. Which you could obscure, but I doubt that would add much security.
New to the channel, thanks a lot your content is amazing! Is there any way to get code completion with TS when referencing the remote components ? Or must I have a type definition in the app that is doing the importing ?
I think you have to declare it in the app that's doing the importing. Module Federation is run-time and TS checking is compile time. What you could do is have a secondary NPM module with the type "contract" and then you depend on that contract in your consuming application. And you also import that into the module federation remote project to ensure that the federated module matches the contract as well.
Another option is to organize components into a monorepo (e.g. something that uses workspaces, and put shared typings that declare the contracts into a shared workspace that is imported into each of the federated components. To be perfectly honest, that's the dream, and the reality that I've experienced with npm workspaces and learna introduces more headaches, and in the past, I just end up using the npm's "file::" syntax to specify the location of the shared package that contains the contracts / typings for the exposed components.
PS, I'm in the process of learning Rushjs, which promises a better experience than npm workspaces or lerna, but it's to early the process for me to give it an informed thumbs up...
How to handle if a shell app imports two remotes and one of them crashes? In my situation i have one remote crashing that will cause the shell to stop working aswell.
How would you go about exporting the consumer project into production, without the module federation. Would it be possible to fetch and include the federated modules into a bundle?
@@jherr Pretty much, when i run build, i want to be able to deploy that without having to worry hosting the base project somewhere for it to fetch the shared components. Essentially I just want to federate modules during development only, and when i make my production build I need it to be autonomous.
@@geoili Ok... I haven't heard that particular use case, but my recommendation would be to use a monorepo, and have your federated modules shared both as hard dependencies and also federated dependencies. Then in the case of prod mode just remove the module federation configuration from the webpack config.
@@geoili yeah, but you do want to do two thing. you want to have a build time dependency in one case and a runtime dependency in another. you could do some fun automation in there with something like NX to automatically create the runtime dependency, but... something is going to have to do that work.
Hi Jack, thanks for the concise explainer! In the remotes key, is the `header@some-url.com/remoteEntry.js` used by HtmlWebpackPlugin to insert the script tag into the HTML template?
I don't think so, I think it's JS injected by one of the plugins used by the ModuleFederationPlugin. The ModuleFederationPlugin is just syntactic sugar around three plugins and I'm doing this from memory, but I think one of those handles the remotes and that's probably the one that does it.
Is there any method to do that without hosting the provider app into a server. I mean build provider app and consumer app adds generated static files from the provider app. Like adding a page inside another page from a react build into another
If you are looking for generated stuff my advice is to go with build time stuff. It doesn't make much sense to generate off of a snapshot of a federated module. You just lose the dynamic loading behavior.
All of this is just bundled JS files, so they should be deployed to an asset store (e.g. S3) and then referenced with script tags on the pages that you create from your Tomcat server. (Wow I haven't heard that name in a while.)
Next do it with dynamic URLs. The reason I suggest that is because there could be different environments people work on.
Awesome as usual. Thanks Jack.
You're a great human being
Thanks!
Thanks for this man, was looking how to setup different URL paths for development and production because all I'm getting was a blank white page (like you showed early on the video ^^).
Thanks Jack, This is very helpful and practical video. I had some queries, after going through comments and your reply, all resolved now,
But if you create new video that include these comments questions-answers then it would be so helpful to others .
Really nice ....... thank you! Great tip in the development vs production modes
Hey jack, constantly following you for micro-frontend concepts and really amazing content.
I wanted to know when we are exposing the module the remoteEntry.js file is also accessible to the consumer app. How to add some authentication to that endpoint. i don't want everyone to use it.
Thank you.
Remote modules are just Javascript files. They should be deployed via S3 or CDN and do not rely on the host application running in order to serve them. You could put some security around the modules, I suppose, but do you do that with the JavaScript you deploy now? Secure your API endpoints, thats the most important thing.
Hi Jack, Great video, I'm wondering how the versioning and deployment would work with AWS S3 or some other storage?
Great :) thanks. Is it possible to conditionally use the deployed header or the local one (production vs development)?
Blargh! I knew there was something I forgot to add to the video. I was intending to cover that and to use environment variables for it. So like:
> LOCAL_REMOTES=header yarn dev
And then I'd do:
const localRemotes = (process.env.LOCAL_REMOTES || "").split(',');
To break it out into an array in webpack.config.js.
Then in the `remotes` key definition I'd switch on localRemotes.includes('header') or something like that.
I am getting a CORS error on host site when following the same steps you mentioned, Any idea how to fix that?
Hi, Iam also getting a CORS error, were you able to fix it?
In the consumer app we are referring to /remoteEntry.js but in actual production we would have some CDN which will append some kind of HTTP Cache hearders which will cache this file, so how to version remoteEntry.js so that caching this remoteEntry File is not a issue
I'd set the caching on remoteEntry short and the caching on everything else to long.
very nice video, is possible specify a branch name for shared header ? i.e. in header repository creata a branch named "blue" , in the consumer app in the remote section i can specify the branch "blue"?
Hi Thanks,
What I understand every part of micro-frontend after deploying should be run on the different port.
Is it right?
No, that's not right. We only run them on different ports in development. In production everything should be deployed to something like S3 and served off of port 80 or 443.
@@jherr Thanks for answer. I got it
@@jherr In vercel can we do somthing like that?
I want to keep code in one repo and divide into separate features like ProductPage, CartPage, CategoryListingPage and different team is working on each separate features. I want a freedom on build & Deployment of features separately without running on multiple ports, can you please suggest approach, tool to achieve this requirement
Use a monorepo like Nx or Turborepo and have each team have their own module with their own features. Or if you are using the App Router you can use route groups to give each team their own dedicated folder.
Excellent thanks
When it comes enterprise we will have different ENV like SIT, UAT and PROD each with different urls, how can we dynamically load individual environment urls with one config setup? Can you please answer this question?
Amazing
Your channel is underrated. I enjoy these videos even tho I found you just now through an article that I was searching for new features in webpack 5.
A question popped while watching this video is how would we prevent other applications trying to get specific remoteEntry files to see what that code does? (Keep in mind I haven't played around with webpack5 yet). I suppose we could use minification? But that requires a sourcefile for it, would be have to store that also on a dedicated place for both apps to access?
Thanks for the content!
Thanks! In production the remoteEntry.js would be minified and uglified, but that's just security through obscurity. Honestly, I don't think Module Federation is any more or less than any other code you to the client. From a security perspective I think of it as largely similar to code splitting. The only difference being that you are exposing named entry points. Which you could obscure, but I doubt that would add much security.
New to the channel, thanks a lot your content is amazing!
Is there any way to get code completion with TS when referencing the remote components ? Or must I have a type definition in the app that is doing the importing ?
I think you have to declare it in the app that's doing the importing. Module Federation is run-time and TS checking is compile time. What you could do is have a secondary NPM module with the type "contract" and then you depend on that contract in your consuming application. And you also import that into the module federation remote project to ensure that the federated module matches the contract as well.
Another option is to organize components into a monorepo (e.g. something that uses workspaces, and put shared typings that declare the contracts into a shared workspace that is imported into each of the federated components. To be perfectly honest, that's the dream, and the reality that I've experienced with npm workspaces and learna introduces more headaches, and in the past, I just end up using the npm's "file::" syntax to specify the location of the shared package that contains the contracts / typings for the exposed components.
PS, I'm in the process of learning Rushjs, which promises a better experience than npm workspaces or lerna, but it's to early the process for me to give it an informed thumbs up...
How to handle if a shell app imports two remotes and one of them crashes? In my situation i have one remote crashing that will cause the shell to stop working aswell.
Use react error boundaries.
How would you go about exporting the consumer project into production, without the module federation. Would it be possible to fetch and include the federated modules into a bundle?
So you just want to version lock it by copying the current version of the module to defeat the runtime loading?
@@jherr Pretty much, when i run build, i want to be able to deploy that without having to worry hosting the base project somewhere for it to fetch the shared components.
Essentially I just want to federate modules during development only, and when i make my production build I need it to be autonomous.
@@geoili Ok... I haven't heard that particular use case, but my recommendation would be to use a monorepo, and have your federated modules shared both as hard dependencies and also federated dependencies. Then in the case of prod mode just remove the module federation configuration from the webpack config.
@@jherr hmm, that's essentially doing the same thing twice though isn't it? Thank you for the quick response!
@@geoili yeah, but you do want to do two thing. you want to have a build time dependency in one case and a runtime dependency in another. you could do some fun automation in there with something like NX to automatically create the runtime dependency, but... something is going to have to do that work.
Thanks, just to understand the base idea
Hi Jack, thanks for the concise explainer! In the remotes key, is the `header@some-url.com/remoteEntry.js` used by HtmlWebpackPlugin to insert the script tag into the HTML template?
I don't think so, I think it's JS injected by one of the plugins used by the ModuleFederationPlugin. The ModuleFederationPlugin is just syntactic sugar around three plugins and I'm doing this from memory, but I think one of those handles the remotes and that's probably the one that does it.
The fallback value in the ternary should be "/" so it'd work on any deployment target right (given module is mapped to root)?
Probably true.
can you use a deployed to prod repo link when running npm start with webpack development mode?
Is there any method to do that without hosting the provider app into a server. I mean build provider app and consumer app adds generated static files from the provider app. Like adding a page inside another page from a react build into another
If you are looking for generated stuff my advice is to go with build time stuff. It doesn't make much sense to generate off of a snapshot of a federated module. You just lose the dynamic loading behavior.
why "argv.mode" and not "arg.environment" is it something from webpack !?
Is webpack5 fully ready for production apps ?
Still in beta if you check out the tags.
In beta but production stable. I’ve got it in production without issue
Is Module Federation production ready?
It is in production on commercial sites.
How we can deploy app on tomact?
All of this is just bundled JS files, so they should be deployed to an asset store (e.g. S3) and then referenced with script tags on the pages that you create from your Tomcat server. (Wow I haven't heard that name in a while.)