English | 简体中文
Micro Frontends solution for large application. Website docs.
npm install @ice/stark --save
https://ice.work/docs/icestark/about
icestark
is a micro frontends solution for large application, contains:
- Modular management of multiple independent applications based on route
- Independent application independent warehouse, independent development and deployment
- Unified management page public content (Common Header, Common Sidebar, etc.)
- Support for low-cost migration
- SPA user experience
- Framework application and sub-application split according to UI structure
- Framework application: responsible for sub-applications registration, loading, common content display (Common Header, Common Sidebar, Common Footer, etc.)
- Sub-application: responsible for content display related to its own business
icestark
requires the framework application to use react version 15+, which has no restrictions on the technology stack of the sub-application, supports different technology stacks such as react, vue, angular, etc., and supports multi-version coexistence of the same technology stack.
// src/App.jsx
import React from 'react';
import ReactDOM from 'react-dom';
import { AppRouter, AppRoute } from '@ice/stark';
class App extends React.Component {
onRouteChange = (pathname, query) => {
console.log(pathname, query);
};
render() {
return (
<div>
<div>this is common header</div>
<AppRouter
onRouteChange={this.onRouteChange}
ErrorComponent={<div>js bundle loaded error</div>}
NotFoundComponent={<div>NotFound</div>}
>
<AppRoute
path={['/', '/message', '/about']}
basename="/"
exact
title="通用页面"
url={['//unpkg.com/icestark-child-common/build/js/index.js']}
/>
<AppRoute
path="/seller"
basename="/seller"
title="商家平台"
url={[
'//unpkg.com/icestark-child-seller/build/js/index.js',
'//unpkg.com/icestark-child-seller/build/css/index.css',
]}
/>
</AppRouter>
<div>this is common footer</div>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById('ice-container'));
AppRouter
locates the sub-application rendering nodeAppRoute
corresponds to the configuration of a sub-application,path
configures all route information,basename
configures a uniform route prefix,url
configures assets urlicestark
will follow the route parsing rules like to determine the currentpath
, load the static resources of the corresponding sub-application, and render
supported by @ice/stark@2.0.0
import { registerMicroApps } from '@ice/stark';
regsiterMicroApps([
{
name: 'app1',
activePath: ['/', '/message', '/about'],
exact: true,
title: '通用页面',
container: document.getElementById('icestarkNode'),
url: ['//unpkg.com/icestark-child-common/build/js/index.js'],
},
{
name: 'app2',
activePath: '/seller',
title: '商家平台',
container: document.getElementById('icestarkNode'),
url: [
'//unpkg.com/icestark-child-seller/build/js/index.js',
'//unpkg.com/icestark-child-seller/build/css/index.css',
],
},
]);
start();
after sub-application is registered, icestark will load app according to the activePath
.
sub-application can expose lifecycles in both register lifecycles and export lifecycles ways.
// src/index.js
import ReactDOM from 'react-dom';
import { isInIcestark, getMountNode, registerAppEnter, registerAppLeave } from '@ice/stark-app';
import router from './router';
if (isInIcestark()) {
const mountNode = getMountNode();
registerAppEnter(() => {
ReactDOM.render(router(), mountNode);
});
// make sure the unmount event is triggered
registerAppLeave(() => {
ReactDOM.unmountComponentAtNode(mountNode);
});
} else {
ReactDOM.render(router(), document.getElementById('ice-container'));
}
- Get the render
DOM Node
viagetMountNode
- Trigger app mount manually via
registerAppEnter
- Trigger app unmount manually via
registerAppLeave
// src/router.js
import React from 'react';
import { BrowserRouter as Router, Route, Switch, Redirect } from 'react-router-dom';
import { renderNotFound, getBasename } from '@ice/stark-app';
function List() {
return <div>List</div>;
}
function Detail() {
return <div>Detail</div>;
}
export default class App extends React.Component {
render() {
return (
<Router basename={getBasename()}>
<Switch>
<Route path="/list" component={List} />
<Route path="/detail" component={Detail} />
<Redirect exact from="/" to="list" />
<Route
component={() => {
return renderNotFound();
}}
/>
</Switch>
</Router>
);
}
}
- Get the
basename
configuration in the framework application viagetBasename
renderNotFound
triggers the framework application rendering global NotFound
exports lifecycles in sub-application:
import ReactDOM from 'react-dom';
import App from './app';
export function mount(props) {
ReactDOM.render(<App />, document.getElementById('icestarkNode'));
}
export function unmount() {
ReactDOM.unmountComponentAtNode(document.getElementById('icestarkNode'));
}
sub-application should be bundled as an UMD module, add the following configuration of webpack:
module.exports = {
output: {
library: 'sub-app-name',
libraryTarget: 'umd',
},
};
Project | Version | Docs | Description |
---|---|---|---|
icejs | docs | A universal framework based on react.js | |
icestore | docs | Simple and friendly state for React | |
formily | docs | Alibaba Group Unified Form Solution | |
iceworks | docs | Universal Application Development Pack for VS Code |
Feel free to report any questions as an issue, we'd love to have your helping hand on icestark
.
If you're interested in icestark
, see CONTRIBUTING.md for more information to learn how to get started.