- By reusing your own components you can save development time, keep your UI consistent across applications and let your whole team build together.
- No need to create a UI library for reusable components across apps.
- Create Shared UI App to create UI components. Deploy Shared UI App and Dynamically load a React Component from that URL using remote-component.
- You can also add shared styles and common files in Shared App which you want to reuse.
- The RemoteComponent React Component takes a URL as a prop. The URL is loaded and processed. This file must be a valid CommonJS Module that exports the component as default.
- While the URL is loading, the fallback will be rendered. This is a similar pattern to React.Suspense. If no fallback is provided, then nothing will be rendered while loading.
- Once loaded, there will either be an error a Component. The rendering will first be handled by the render callback function. If there is no render callback and err exists, a generic message will be shown.
- The Component will be rendered either to the render callback if one exists, otherwise, it will be rendered as a standard component.
- To use UI Components in all the apps you have to follow this for all the apps.
- Install remote-component
$ npm install @paciolan/remote-component --save
- Remote Components will require some dependencies to be injected into them. At the minimum, we'll be injecting the React dependency.
- The web application can include dependencies and inject them into the RemoteComponent. At a minimum, you will probably need the react dependency.
- Create a file remote-component.config.js in the root of the web application.
- If you are using any library or package that the Ui component is using then you have to add that dependency in this file.
- ex: If you are using Material-UI to create a UI component then you have to add material-ui as a dependency in this file like this:
["@material-ui/core"]: require("@material-ui/core")
/**
* remote-component.config.js
* Dependencies for Remote Components
*/
module.exports = {
resolve: {
react: require("react")
}
};
- Create a file named RemoteComponent.js in the src folder.
- Export RemoteComponent with the requires from remote-component.config.js. This will inject the dependencies into the RemoteComponent.
/*
* src/components/RemoteComponent.js
*/
import {
createRemoteComponent,
createRequires
} from "@paciolan/remote-component";
import { resolve } from "../remote-component.config.js";
const requires = createRequires(resolve);
export const RemoteComponent = createRemoteComponent({ requires });
- Usage:
- Create a file that exports al UI components.
import { RemoteComponent } from "./RemoteComponent";
const element = document.getElementById("app");
const url = "https://raw.githubusercontent.com/Paciolan/remote-component/master/examples/remote-components/HelloWorld.js";
const HelloWorld = props =>
<RemoteComponent
url={url}
render={({ err, Component }) =>
err ? <div>{err.toString()}</div> : <Component {...props} />
}
/>
);
export default HelloWorld;
- Now you can import HelloWorld component in your app like this:
import { HelloWorld } from "./index";
- To use UI components in all the apps you have to add this configuration in all the apps.
- To Create a Shared UI app follow this configuration.
- Create a Folder named Shared.
- Create a folder named src/UI(Or name you want).
- Create Components in the UI folder.
- Ex: To create a Label component in src folder create a file Label.js
import React from 'react';
import Typography from '@material-ui/core/Typography';
export default function Title(props) {
return (
<Typography component="h2" variant="h6" color="primary" gutterBottom>
{props.children}
</Typography>
);
}
- UI Component Label is created.
- Create package.json at the root of the app.
- Add all dependencies in the package.json which is required to create UI component.
- Ex: Title Component is required material-ui, So Install material-ui first.
- If you want common CSS across all the apps or any common file that is used by all the apps then you can add it in the src folder.
- This file must be a valid CommonJS Module that exports the component as default, So we have to convert es6 files to commonjs.
- Create .babelrc in the root folder.
{
"presets": [
"minify",
"@babel/preset-react",
"@babel/env"
],
"plugins": [
"@babel/plugin-proposal-class-properties",
"@babel/plugin-proposal-object-rest-spread"
]
}
- Install "@babel/preset-react", "@babel/env", "@babel/plugin-proposal-class-properties", "@babel/plugin-proposal-object-rest-spread".
- Add scripts in package.json to convert es6 files to commonJs module using babel.
"scripts": {
"build": "babel ./src --out-dir build --extensions '.ts,.tsx,.js,.jsx' && cp ./src/index.css build/",
"start": "serve --port 5000 --cors build"
},
- When you run npm run build, It will convert all files from src directory and add it in build directory and copy index.css file in the build folder.
- Now to use shared components and styles you have to serve build folder.
- You can get components js file from http://localhost:5001/UI/Label.js
- There are 2 apps created in this repo app1 and app2 which are using the shared app for reusable components.
- Created Remore-Component.jsx and remote-component-config.js files and are the same for both apps.
/**
* remote-component.config.js
*
* Dependencies for Remote Components
*/
module.exports = {
resolve: {
react: require("react"),
["@material-ui/core"]: require("@material-ui/core"),
["@material-ui/icons"]: require("@material-ui/icons"),
["@material-ui/core/Link"]: require("@material-ui/core/Link"),
["@material-ui/core/styles"]: require("@material-ui/core/styles"),
["@material-ui/core/Typography"]: require("@material-ui/core/Typography"),
["recharts"]: require("recharts")
}
};
import { createRemoteComponent } from "@paciolan/remote-component/dist/lib/createRemoteComponent";
import { createRequires } from "@paciolan/remote-component/dist/lib/createRequires";
import { resolve } from "./remote-component.config.js";
const requires = createRequires(resolve);
export const RemoteComponent = createRemoteComponent({ requires });
- Created indexShared.js file for add all UI components.
import React from "react";
import { RemoteComponent } from "./RemoteComponent";
const Title = (props) => {
const url1 = "http://localhost:5000/ui/Title.js";
return (
<RemoteComponent
url={url1}
render={({ err, Component }) =>
err ? <div>{err.toString()}</div> : <Component {...props} />
}
/>
);
};
export { Title };
const Deposits = (props) => {
const url = "http://localhost:5000/ui/Deposits.js";
return (
<RemoteComponent
url={url}
render={({ err, Component }) =>
err ? <div>{err.toString()}</div> : <Component {...props} />
}
/>
);
};
export { Deposits };
const Chart = (props) => {
const url = "http://localhost:5000/ui/Chart.js";
return (
<RemoteComponent
url={url}
render={({ err, Component }) =>
err ? <div>{err.toString()}</div> : <Component {...props} />
}
/>
);
};
export { Chart };
const Orders = (props) => {
const url = "http://localhost:5000/ui/Orders.js";
return (
<RemoteComponent
url={url}
render={({ err, Component }) =>
err ? <div>{err.toString()}</div> : <Component {...props} />
}
/>
);
};
export { Orders };
const listItems = (props) => {
const url = "http://localhost:5000/ui/listItems.js";
return (
<RemoteComponent
url={url}
render={({ err, Component }) =>
err ? <div>{err.toString()}</div> : <Component {...props} />
}
/>
);
};
export { listItems };
- imported all UI components in Dashboard.js file
import { Title, Deposits, Chart, Orders } from "./indexShared";
- Created a Shared folder for reusable components.
- Created the Common/ui folder and added all reusable components in ui folder.
- Created index.css file in the Common folder to reuse the same style in all the apps.
- Clone the repo
- Open each app and run npm install.
- Open Shared app and run npm run build
- Run all the apps by npm start
app1: http://localhost:3001
app2: http://localhost:3002
shared: http://localhost:5000
- UI components Chart, Deposits, Orders, and Title are shared with both the apps.