I have a webpack 'library' project with a webpack config that looks like this:
module.exports = ({ mode }) => {
const isProd = mode === 'production';
return {
mode,
entry: './src/index.tsx',
output: {
library: 'MyLibraryComponents',
path: path.resolve(__dirname, 'build'),
filename: getOutputFileName(isProd),
},
devServer: { ... },
optimization: { ... },
module: {
rules: [
{
test: /\.tsx?$/,
loader: 'ts-loader',
},
{
test: /\.less$/i,
use: [
{ loader: 'style-loader' },
{ loader: 'css-loader' },
{
loader: 'less-loader',
},
],
},
{
test: /\.css$/i,
use: ['style-loader', 'css-loader'],
},
],
},
resolve: {
extensions: ['.ts', '.tsx', '.js'],
},
plugins: [
new HtmlWebpackPlugin({
inject: true,
scriptLoading: 'blocking',
template: resolveAppPath('public/index.html'),
}),
],
};
};
This webpack build creates a global variable called "MyLibraryComponents", which has methods on it that render react components given an HTMLElement using ReactDOM.render(). My project is set up this way because I'm working in a legacy application, but want to re-write certain parts of the UI in react.
Here is what the entry file for the library looks like. The entry file is in .ts but I've simplified it a bit here:
// src/index.tsx
import ReactDOM from 'react-dom';
export Examples = {
FooComponent: {
async render(htmlElement, props) {
const { default: Foo } = await import("./components/Foo");
ReactDOM.render(<Foo {...props} />, htmlElement);
}
},
BarComponent: {
async render(htmlElement, props) {
const { default: Bar } = await import("./components/Bar");
ReactDOM.render(<Bar {...props} />, htmlElement);
}
}
};
When the webpack main bundle is downloaded using a <script src=''>, it creates an object on window called MyLibraryComponents. I can then render react components into the legacy app like this: MyLibraryComponents.Examples.FooComponent.render(...)
As more components are added to this library, I'm interested in potentially using Module Federation as a means to independently deploy components, and to isolate dependencies, etc.
However, in all the module federation project examples I've seen it is necessary to have a "bootstrap" file and have your webpack entry file do this. And then your "real" entry file to your app should be renamed to bootstrap.js:
import("./bootstrap")
Apparently, this ensures that the project's shared modules are loaded by the browser first, or something like that. The reason isn't 100% clear to me yet.
The issue I'm seeing is that my project's entry file actually has "exports" that my webpack library depends on, whereas if this was a traditional react app, it would just do something like this:
import ReactDOM from "react-dom";
import App from "./App;
ReactDOM.render(<App />, document.getElementById("root"));
If I update my entry point file to just import('./bootstrap'), then my library just ends up being an empty object when I inspect it in the console.
Is there a way I can write the 'bootstrap' entry file so that I can support module federation in this project?
Thank you for the help.