Skip to content

Latest commit

 

History

History
174 lines (138 loc) · 5.12 KB

File metadata and controls

174 lines (138 loc) · 5.12 KB

@redneckz/microfront-core-react

Microfrontend Core Library for React

NPM Version Build Status Coverage Status Bundle size

Installation

$ npm install --save @redneckz/microfront-core @redneckz/microfront-core-react

or:

$ yarn add @redneckz/microfront-core @redneckz/microfront-core-react

Usage

How to define micro frontend module

import React from 'react';
import { render, unmountComponentAtNode } from 'react-dom';
import { Router } from 'react-router-dom';

import { container, MicroFrontModuleBootstrap } from '@redneckz/microfront-core';
import { Container } from '@redneckz/microfront-core-react';

// Each and every micro frontend should implement async "bootstrap" function
export const bootstrap: MicroFrontModuleBootstrap = async ({ route: rootRoute }) => {
    // Global stuff can be lazily loaded here
    const { App } = await import('./App');
    const { createBrowserHistory } = await import('history');

    // Relative to MF root route
    const history = createBrowserHistory({ basename: rootRoute });

    return {
        mount: async mountingRoot => {
            render(
                <Container instance={container()}>
                    <Router history={history}>
                        <App />
                    </Router>
                </Container>,
                mountingRoot
            );
        },
        unmount: async mountingRoot => {
            unmountComponentAtNode(mountingRoot);
        }
    };
};

How to isolate global API relative to micro frontend instance

import React, { useCallback } from 'react';
import Toolbar from '@material-ui/core/Toolbar';
import Button from '@material-ui/core/Button';
import { useContainer } from '@redneckz/microfront-core-react';

export const Header: React.FC = () => {
    // Outside of micro frontend context returns identity function
    const container = useContainer();

    const onSignUp = useCallback(
        container(() => {
            // isolation is here
        }),
        []
    );

    return (
        <Toolbar>
            <Button onClick={onSignUp}>Sign up</Button>
        </Toolbar>
    );
};

How to retrieve micro frontend params

import React from 'react';
import { useMicroFrontParams } from '@redneckz/microfront-core-react';

export const Page: React.FC = () => {
    const params = useMicroFrontParams();
    return params ? (
        <article>This page is rendered as a micro frontend on the route `{params.route}`</article>
    ) : (
        <article>This page is rendered as a regular page</article>
    );
};

How to pass additional params to micro frontend on bootstrap

Parametrize bootstrap: MicroFrontModuleBootstrap<?> with additional props type. Export such types as a library to simplify integration with host container.

import type { HeaderProps } from './Header';

export const bootstrap: MicroFrontModuleBootstrap<HeaderProps> = async ({ title }) => {
    const { Header } = await import('./Header');
    return {
        mount: async mountingRoot => {
            ...
        },
        unmount: async mountingRoot => {
            ...
        }
    };
}

Integrate micro frontend with host container and pass in additional params:

import React from 'react';

import { register } from '@redneckz/microfront-core';
import { MicroFrontContainer } from '@redneckz/microfront-core-react';

import { Layout } from './Layout';

/**
 * It would be nice to have the latest typings of micro frontends
 * on host container to fix integration problems ASAP at compile time.
 * But keep in mind that host <-> microfront contract should be as simple as possible.
 */
import type { HeaderProps } from '@typings-scope/typings-library/Header';

const bootstrapHeader = register<HeaderProps>(
    'foo', // remote module name according to Module Federation config
    () => import('foo/Header') //  remote module
);

...

export const App: React.FC = () => (
    <Layout
        header={
            /* Typings are correctly seeped from "bootstrapHeader" to "MicroFrontContainer" */
            <MicroFrontContainer bootstrap={bootstrapHeader} title="Micro Frontends">
                {mountingRootRef => <div ref={mountingRootRef}>Loading...</div>}
            </MicroFrontContainer>
        }
    >
        ...
    </Layout>
);

License

MIT