This repository provides a foundational configuration for integrating new extensions into any Micro Frontend (MFE). Currently, the configuration requires updates within the specific MFE where you intend to implement the feature. The content of this repository includes the initial setup for facilitating this configuration process. Here is the original implementation
Before proceeding with the following steps, clone this repository inside the Micro Frontend (MFE) where you intend to implement the extension.
git clone https://github.com/eduNEXT/extensible-mfe-example.gitAdding the basic configuration for eslint, jest, and webpack
eslint configuration: Add this configuration to the .eslintrc.js files inside the Micro Frontend (MFE).
const path = require('path'); const { createConfig } = require('@edx/frontend-build'); module.exports = createConfig('eslint', { settings: { 'import/resolver': { webpack: { config: path.resolve(__dirname, 'webpack.dev.config.js'), }, alias: { map: [ // optional to have an alias ['@communications-app', '.'], ], extensions: ['.ts', '.js', '.jsx', '.json'], }, }, }, rules: { ...otherRules, 'import/prefer-default-export': 'off', 'import/no-extraneous-dependencies': 'off', }, overrides: [ { files: ['plugins/**/*.jsx'], rules: { 'import/no-extraneous-dependencies': 'off', }, }, ], });
jest configuration: Add this configuration to the jest.config.js file inside the MFE.
const path = require('path'); const { createConfig } = require('@edx/frontend-build'); module.exports = createConfig('jest', { ...otherRules, moduleNameMapper: { // required '@node_modules/(.*)': '<rootDir>/node_modules/$1', // optional '@communications-app/(.*)': '<rootDir>/$1' }, });
webpack configuration:
development: Add this configuration to the webpack.dev.config.js file inside the MFE.
const path = require('path'); const { createConfig } = require('@edx/frontend-build'); const config = createConfig('webpack-dev'); // ...other rules const alias = { '@node_modules': path.resolve(__dirname, 'node_modules'), // optional '@communications-app': path.resolve(__dirname, '.'), }; config.resolve.alias = { ...config.resolve.alias, ...alias }; module.exports = config;
production: Add this configuration to the webpack.prod.config.js file inside the MFE.
const path = require('path'); const { createConfig } = require('@edx/frontend-build'); // ...other rules const alias = { '@node_modules': path.resolve(__dirname, 'node_modules'), // optional '@communications-app': path.resolve(__dirname, '.'), }; config.resolve.alias = { ...config.resolve.alias, ...alias };
Adding the PluggableComponent and contextFactory to the MFE
PluggableComponent: This component allows dynamic components, passing it two props:
- key: A string identifier for the component.
- as: A string that will be the name of the plugin. For example, if the package.json of the plugin is called "@openedx-plugins/example-app-example-plugin," then the "as" prop will be "example-app-example-plugin."
To add it to the MFE, move it to the "src" folder of the MFE.
cp -R extensible-mfe-example/PluggableComponent src
contextFactory (optional): This is a utility that you could use to create a context with a simple reducer to share between plugins if needed.
To add it to the MFE, move it to the "src" folder of the MFE.
cp -R extensible-mfe-example/contextFactory src
Move the plugin to the MFE root directory:
cp -R extensible-mfe-example/plugins .There is a plugin example; you can change the {{MFE_NAME}} for the MFE where you are adding this slot, which is in the peerDependencies in the package.json.
Install the dependencies:
Add these dependencies to your project's dependencies in the package.json file:
{ "dependencies": { ...otherDependencies, "@openedx-plugins/example-app-example-plugin": "file:plugins/PluginExample" } }Then, in your terminal, run:
npm install @loadable/component use-deep-compare-effect @openedx-plugins/example-app-example-plugin npm install --save-dev @testing-library/react-hooks eslint-import-resolver-alias eslint-import-resolver-webpack eslint-plugin-import
Add the `PluggableComponent` component to any part of the MFE:
import PluggableComponent from '{your_path}/PluggableComponent';
Then add it somewhere you want to:
<PluggableComponent id="example-plugin" as="example-app-example-plugin" />
Start the MFE:
npm start
You should be able to see the plugin in the part that you have added to the MFE.
Recommendations
The plugins should have an index.jsx file as the entry point to avoid problems when uploading the plugin to npm. Ensure that the plugin is Babel transpiled code when published to npm.