A progressive micro frontends framework for building Web applications
MIT License
Fronts is a progressive micro frontends framework for building Web applications, and it's based on the module federation of Webpack.
Among the many micro frontends solutions, single-spa and Module Federation are the best of them.
single-spa is a micro frontends framework based on router configuration. The centralization of configuration brings some limitations, such as it is difficult to granulate nestable micro frontends, module granularity control, module sharing, and so on.
In 2019, Zack Jackson proposed and implemented Module Federation. Module Federation is a completely different concept from single-spa, and allows a JavaScript application to dynamically load code from another application. It completely solves the problem of code dependency sharing and runtime modularity. The idea is true - A game-changer in JavaScript architecture as mentioned in Zack Jackson's article. And it's currently supported by Webpack, Next.js, and Rollup.
Although the Module Federation concept is so amazing, it has not yet gone further to provide a more complete and fully targeted micro frontends framework implementation, and this is what Fronts is trying to do.
non-module-federation
mode.site.json
for dependency management in each Fronts app, support for nested micro frontends.micro-frontends
app and non-micro-frontends
app.You can follow this article(React without create-react-app Webpack 5) to quickly create
app1
andapp2
React projects.
Assuming you've completed these steps, let's get started with a quick taste of the wonderful micro frontends development of Fronts.
fronts-react
and fronts-bundler
in the projects.# with NPM
npm install fronts-react fronts-bundler
# or with Yarn
yarn add fronts-react fronts-bundler
site.json
and webpack.config.js
in the projectsWe define app1
as a parent micro frontend and it depends on app2
.
app1/site.json
:
{
"name": "app1",
"exports": [],
"dependencies": {
"app2": "http://localhost:3002/remoteEntry.js"
}
}
app2
doesn't have any dependencies, it acts as a micro frontend and we define it to export ./src/bootstrap
as a micro frontends entry, this entry of app2
end will be used by app1
.
app2/site.json
:
{
"name": "app2",
"exports": ["./src/bootstrap"],
"dependencies": {}
}
Wrap the Webpack config with createWebpackConfig()
in config/webpack.config.js
in the projects.
const { createWebpackConfig } = require('fronts-bundler');
module.exports = createWebpackConfig(originalWebpackConfig);
app2/src/bootstrap.jsx
and use boot()
to get it booted.import React from 'react';
import ReactDOM from 'react-dom';
import { boot } from 'fronts-react';
import App from './App';
export default function render(element) {
ReactDOM.render(<App />, element);
return () => {
ReactDOM.unmountComponentAtNode(element);
};
}
boot(render, document.getElementById('root'));
app1/src/App.jsx
with useApp()
to import app2
.import React from 'react';
import { useApp } from 'fronts-react';
export const App = () => {
const App2 = useApp({
name: 'app2',
loader: () => import('app2/src/bootstrap'),
});
return <App2 />;
};
API | Isolation |
---|---|
useApp() |
CSS(loose/optional) |
useWebComponents() |
CSS |
useIframe() |
CSS, JavaScript |
The most popular frontend frameworks are React, Vue and Angular. When the micro frontends uses one of these frameworks, it is recommended to use Fronts built-in package for this framework, such as fronts-react
, fronts-vue
and fronts-ng
, otherwise please use fronts
.
Packages | Support Framework | Status |
---|---|---|
fronts |
Any Framework | Completed ✅ |
fronts-react |
React | Completed ✅ |
fronts-vue |
Vue | In Progress 💡 |
fronts-ng |
Angular | - |
fronts-svelte |
svelte | - |
fronts-solid |
svelte | - |
Type | Requirement | Support |
---|---|---|
Non-Module-Federation | - | Dependency Management ❌ Monorepo ❌ Version Management ❌ |
Module Federation | Webpacksite.json | Dependency Management ✅ Monorepo ✅ Version Management ❌ |
Version Control | Webpacksite.jsonRegistry Server | Dependency Management ✅ Monorepo ✅ Version Management ✅ |
Use getMeta()
, it helps you to get the dependency mapping information.
import { getMeta } from 'fronts';
console.log(getMeta());
// {
// "name": "app3",
// "meta": {
// "__main__": "app1",
// "__entry__": "http://localhost:3001/#/app2",
// "app2": {
// "dependencies": {
// "app3": "http://localhost:3003"
// }
// },
// "app5": {
// "dependencies": {
// "app6": "http://localhost:3006"
// }
// },
// "app3": {
// "dependencies": {}
// },
// "app6": {
// "dependencies": {}
// },
// "app1": {
// "dependencies": {
// "app2": "http://localhost:3002",
// "app4": "http://localhost:3004",
// "app5": "http://localhost:3005"
// }
// }
// }
// }
fronts-test
provides an runner for function step, and any micro frontends IT and E2E can use it for reusable testing. It also provides other APIs, such as useContext()
, beforeHook and afterHook in createRunner()
.
import { $, useContext, Given, When, Then } from 'fronts-test';
const addTodo = $(() => {
const { page } = useContext();
await page.type('.text', 'Use Fronts');
await page.click('.add');
});
test('base', async () => {
await Given('user open the page').then(entry);
await When('user add todo text').then(addTodo);
await Then('user should see that todo list has a new item').then(checkTodo);
});
todo
Set up the registry server URL in the registry
field.
It supports dynamic
import()
, and it does not support static import.
{
"name": "app1",
"exports": [],
+ "registry": "http://localhost:3000/dev.json",
"dependencies": {
- "app2": "http://localhost:3002/remoteEntry.js"
+ "app2": "1.0.0"
}
}
Start the registry server and make sure that http://localhost:3000/dev.json?scope=app2%401.0.0
request gets a response data with the version specification.
{
"app2": "http://localhost:3002/remoteEntry.js"
}
todo
Q: Can Non-Module-Federation, Module Federation, and Version Control be compatible with each other?
A: Yes
Q: How to use SPA development mode in micro frontends codebase?
A: Use SPA=true yarn start
instead of yarn start
, make sure the current codebase is Monorepo and module federation or version control is enabled, and it just works with useApp()
and useWebComponent()
.
Fronts is MIT licensed.