@monolithed/module-federation-loader
v0.0.1
Published
A Webpack module for dynamically loading remote components
Downloads
1
Readme
@monolithed/module-federation-loader
A Webpack module for dynamically loading remote components
Installation
Install with npm or Yarn:
npm:
npm install @monolithed/module-federation-loader --save
Yarn:
yarn add @monolithed/module-federation-loader
Basic usage
// Todo.tsx
import React, {
FunctionComponent,
Suspense,
lazy,
useState,
useEffect
} from 'react';
import {
addScript,
remoteLoader
} from '@monolithed/module-federation-loader';
import ky from 'ky';
type Props = {
bundle: string;
module: string;
};
type BundleResponse = {
src: string;
};
const fetchBundle = (name: string): Promise<BundleResponse> => {
const request = ky.get('/bundle', {
searchParams: {name}
});
return request.json<BundleResponse>();
};
const useBundle = (name: string) => {
const [loading, setLoading] = useState<boolean>(true);
const [bundle, setBundle] = useState<HTMLScriptElement>();
useEffect(() => {
let abortController = new AbortController();
(async (): Promise<void> => {
let {src} = await fetchBundle(name);
const {script} = await addScript({src});
setBundle(script);
setLoading(false);
})();
return () => {
abortController.abort();
bundle?.remove();
};
}, [name]);
return {loading};
};
type ServiceComponent<Props> = FunctionComponent<Props> & {
Component: FunctionComponent<any>;
};
const LazyBundle: FunctionComponent<Props> = ({children, bundle, module}): JSX.Element => {
const {loading} = useBundle(bundle);
const remoteModule = remoteLoader({bundle, module});
const RemoteComponent = lazy(remoteModule);
return (
<Suspense fallback="loading...">
<RemoteComponent>{...children.props}</Component>
</Suspense>
);
};
const Component: FunctionComponent<any> = (props) => {
return <div {...props} />;
};
// Todo.tsx
import React, {FunctionComponent} from 'react';
import {LazyModule} from './LazyModule';
const Todo: FunctionComponent<any> = () => {
return (
<LazyBundle scope="todo" component="./List">
<LazyBundle.Component />
</LazyBundle>
);
};
export {Example};
// App.tsx
import React, {
FunctionComponent
} from 'react';
import {
BrowserRouter,
Switch,
Route
} from 'react-router-dom';
const App: FunctionComponent<Props> = () => (
<BrowserRouter>
<Switch>
<Route path="/">
<Todo />
</Route>
</Switch>
</BrowserRouter>
);
export {App};
// Bootstrap.tsx
import React from 'react';
import {render} from 'react-dom';
import {App} from './App';
const root = document.getElementById('root');
render(<App />, root);
// index.ts
(async () => await import('./Bootstrap'))();
Options
- bundle (required)
- module (required)
Publishing
npm publish --access public --verbose
License
MIT
Contributing
Feel free to submit a pull request if you find any bugs. Please make sure all commits are properly documented.