0.0.19 • Published 2 years ago
bluebell v0.0.19
bluebell
English | 简体中文
A high concurrency micro-frontend framework inspired by and compatible with single-spa.
features
- Compatible with single-spa
- Support multiple instances
- Support router & manual modes
- Support safe destroying
- Support safe nested
- Support async navigation cancelation
- Fast reaction in concurrency
- Multiple types of application entry
- Support built-in ESM loading
- Support unified resources management
- Support more chances for retry
- Support keep alive
- Support preload(intelligent optional)
- Support dead loop detect
- Support sandbox
- Support shadow DOM
- Support iframe
usage
router mode
const { RouterContainer } from 'bluebell';
const container = new RouterContainer({
name: 'top',
root: '#app',
fallbackUrl: '/foo',
fallbackOnlyWhen: loc => loc.pathname === '/',
cancelActivateApp: (app) => Promise.resolve(false),
});
const [fooApp, barApp, bazApp] = container.registerApps([
{
// use entry
name: 'foo',
entry: '/foo-config/assets.json',
activeWhen: '/foo',
},
{
// use assetsMap
name: 'bar',
entry: '/foo-config/assets.json',
assetsMap: { module: 'esm', initial: {}, async: {} },
activeWhen: (location: Location) => location.pathname.startsWith('/foo'),
},
{
// use lifecycle
name: 'baz',
lifecycle: {
mount: async () => {},
unmount: async () => {},
bootstrap: async () => {},
},
activeWhen: ['/baz', '/bas'],
}
]);
container.on('appactivating', ({ appname }) => {});
container.on('appactivated', ({ appname }) => {});
container.on('appactivateerror', ({ appname, error }) => {});
container.on('noappactivated', ({ error }) => {}); // No emitted if fallback.
container.run();
await container.destroy();
💡 Once a RouterContainer starts running, a popstate event will be dispatched after
pushState
orreplaceState
called, which changes the default behavior of browser.
manual mode
const { ManualContainer } from 'bluebell';
const container = new ManualContainer({
name: 'top',
root: '#app',
});
const [fooApp, barApp, bazApp] = container.registerApps([
{
// use entry
name: 'foo',
entry: '/foo-config/assets.json',
},
{
// use assetsMap
name: 'bar',
entry: '/foo-config/assets.json',
assetsMap: { module: 'esm', initial: {}, async: {} },
},
{
// use lifecycle
name: 'baz',
lifecycle: {
mount: async () => {},
unmount: async () => {},
bootstrap: async () => {},
},
}
]);
container.on('appactivating', ({ appname }) => {});
container.on('appactivated', ({ appname }) => {});
container.on('appactivateerror', ({ appname, error }) => {});
container.on('noappactivated', ({ error }) => {});
await container.activateApp('foo');
await container.destroy();
events
fooApp.on('beforestart', () => {});
fooApp.on('afterstart', () => {});
fooApp.on('starterror', ({ error: AppError; prevState: AppState }) => {});
fooApp.on('beforestop', () => {});
fooApp.on('afterstop', () => {});
fooApp.on('stoperror', ({ error: AppError; prevState: AppState }) => {});
fooApp.on('beforeupdate', () => {});
fooApp.on('afterupdate', () => {});
fooApp.on('updateerror', ({ error: AppError; prevState: AppState }) => {});
fooApp.on('beforeunload', () => {});
fooApp.on('afterunload', () => {});
fooApp.lifecycle.on('beforeload'), () => {});
fooApp.lifecycle.on('afterload'), () => {});
fooApp.lifecycle.on('loaderror'), ({ error: AppError }) => {});
fooApp.lifecycle.on('beforebootstrap'), () => {});
fooApp.lifecycle.on('afterbootstrap'), () => {});
fooApp.lifecycle.on('bootstraperror'), ({ error: AppError }) => {});
fooApp.lifecycle.on('beforemount'), () => {});
fooApp.lifecycle.on('aftermount'), () => {});
fooApp.lifecycle.on('mountinterrupted'), ({ error: AppError }) => {});
fooApp.lifecycle.on('mounterror'), ({ error: AppError }) => {});
fooApp.lifecycle.on('beforeunmount'), () => {});
fooApp.lifecycle.on('afterunmount'), () => {});
fooApp.lifecycle.on('unmounterror'), ({ error: AppError }) => {});
fooApp.lifecycle.on('beforeupdate'), () => {});
fooApp.lifecycle.on('afterupdate'), () => {});
fooApp.lifecycle.on('updateinterrupted'), ({ error: AppError }) => {});
fooApp.lifecycle.on('updateerror'), ({ error: AppError}) => {});
strict vs loose
container.registerApps([
{
name: 'foo',
strict: true,
// HTML entry
entry: 'http://localhost:9000',
},
]);
In loose mode, app tries to load CSS and JavaScript by creating HTML tags, otherwise by loading and evalating source code.
App is in loose mode by default.
contributors
0.0.14
2 years ago
0.0.15
2 years ago
0.0.16
2 years ago
0.0.17
2 years ago
0.0.18
2 years ago
0.0.19
2 years ago
0.0.12
2 years ago
0.0.13
2 years ago
0.0.10
2 years ago
0.0.11
2 years ago
0.0.9
2 years ago
0.0.8
2 years ago
0.0.5
2 years ago
0.0.4
2 years ago
0.0.7
2 years ago
0.0.6
2 years ago
0.0.3
2 years ago
0.0.2
2 years ago
0.0.1-alpha.3
2 years ago
0.0.1-alpha.2
2 years ago
0.0.1-alpha.1
2 years ago
0.0.1
2 years ago