Is there a way to use module federation using create-react-app without ejecting? I want to convert my existing react applications(created using CRA) to micro-frontends.
Is there a way to use module federation using create-react-app without ejecting? I want to convert my existing react applications(created using CRA) to micro-frontends.
Answering because this question is top for Google searches
CRA with Module Federation
Update 17 Nov 2021 - based on this answer I've created a GitHub template to make it easier for anyone else trying to do module federation with CRA.
Take a look at the craco-module-federation repo for an example of CRA working with Module Federation.
To support Module Federation you need the craco-module-federation CRACO plugin (or to write your own CRACO config) to overwrite CRA webpack config.
react-scripts, and update any dependencies.craco-module-federation is a plugin for CRACO that does the heavy lifting required.
The steps for getting CRA and Module Federation working are:
npx create-react-app@next --scripts-version=@next --template=cra-template@next my-js-app
More info here https://github.com/facebook/create-react-app/discussions/11278
For an existing app delete node_modules, and install the alpha version of react-scripts. Then resolve any dependencies issues.
npm install @craco/craco --save
Change your package.json scripts to run craco:
"scripts": {
"start": "craco start",
"build": "craco build"
}
Either install the craco-module-federation plugin, or write your own CRACO config to overwrite webpack's config to add the ModuleFederationPlugin.
Either to modulefederation.config.js if your using the craco-module-federation plugin, or to craco.config.js if you configuring without the craco-module-federation plugin.
Create React App 5 with webpack 5 support is in Alpha, you may run into issues.
craco-module-federation IS NOT PRODUCTION READY
react-scripts still uses webpack 4.x.x. You can track the migration here.
What you can do in the meantime is use CRACO, an amazing tool to set custom configurations on top of CRA's without ejecting.
Follow the instructions on how to set CRACO in your project, is fair simple.
Then install webpack 5, after attempting yarn start or build you'll get a warning from react-script saying webpack 5 shouldn't be installed. A workaround, as they state, add SKIP_PREFLIGHT_CHECK=true to a .env file.
This is a temporary fix while CRA's team upgrades, I strongly suggest you remove it later on. Keep using CRACO is totally fine though.
Here's a sample of a basic .craco.js file:
const { ModuleFederationPlugin } = require("webpack").container;
const allDeps = require("../package.json").dependencies;
module.exports = ({ env }) => ({
plugins: [
{
plugin: ModuleFederationPlugin,
options: {
shared: {
...allDeps,
'styled-components': {
singleton: true
}
}
}
}
],
});
And remember to change your package.json scripts to run craco:
"scripts": {
"start": "craco start",
"build": "craco build"
}
You can even create a custom plugin, put it on top of CRA, and reuse it.
No. In order to bump the version of the current webpack for CRA you need to eject. Moreover, CRA at the moment would be on webpack v4, which is no good for module federation. So you need to wait until authors of CRA will move on with webpack v5 or create your own template and implement federation into it )) If you want to be on track, follow https://github.com/facebook/create-react-app/issues/9994
you can use a plugin called craco-plugin-micro-frontend
npm install --save-dev craco-plugin-micro-frontend
and use it your craco.config.js
const microFrontedPlugin = require('craco-plugin-micro-frontend');
module.exports = {
plugins: [
{
plugin: microFrontedPlugin,
options: {
orgName: 'my-org',
fileName: 'my-app.js', // should same as package main
entry: 'src/index.injectable.js', //defaults to src/index.injectable.js,
orgPackagesAsExternal: false, // defaults to false. marks packages that has @my-org prefix as external so they are not included in the bundle
reactPackagesAsExternal: true, // defaults to true. marks react and react-dom as external so they are not included in the bundle
externals: ['react-router', 'react-router-dom'], // defaults to []. marks the specified modules as external so they are not included in the bundle
minimize: false, // defaults to false, sets optimization.minimize value
libraryTarget: 'commonjs2', // defaults to umd
outputPath: 'dist',
customJestConfig: {}, // custom jest configurations
},
},
],
};
your package.json
"scripts": {
"start": "craco start",
"build": "craco build",
"build:lib": "REACT_APP_INJECTABLE=true craco build",
...
}
for more info can read here: https://github.com/m-nathani/craco-plugin-micro-frontend#readme