マイクロフロントエンドのカスタムフレームワーク
1. サブアプリケーションの統合
Vue2アプリケーション
const webpack = require('webpack');
const path = require('path');
module.exports = {
devServer: {
port: 9004,
headers: {
'Access-Control-Allow-Origin': '*'
}
},
configureWebpack: {
output: {
library: 'vue2App',
libraryTarget: 'umd'
}
}
};
import Vue from 'vue';
import App from './App.vue';
let vueInstance = null;
export const bootstrap = () => {
vueInstance = new Vue({
render: h => h(App)
}).$mount('#app-container');
};
export const mount = () => {
if (!vueInstance) bootstrap();
};
export const unmount = () => {
vueInstance.$destroy();
vueInstance = null;
};
Vue3アプリケーション
const { defineConfig } = require('@vue/cli-service');
module.exports = defineConfig({
devServer: {
port: 9005,
headers: { 'Access-Control-Allow-Origin': '*' }
},
configureWebpack: {
output: {
library: 'vue3App',
libraryTarget: 'umd'
}
}
});
import { createApp } from 'vue';
import App from './App.vue';
let appInstance = null;
export const mount = () => {
appInstance = createApp(App);
appInstance.mount('#app-container');
};
export const unmount = () => {
appInstance.unmount();
appInstance = null;
};
Reactアプリケーション
module.exports = {
output: {
library: 'reactApp',
libraryTarget: 'umd',
publicPath: 'http://localhost:9002/'
},
devServer: {
port: 9002,
headers: { 'Access-Control-Allow-Origin': '*' }
}
};
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
export const mount = () => {
ReactDOM.render(<App />, document.getElementById('app-container'));
};
export const unmount = () => {
const container = document.getElementById('app-container');
if (container) ReactDOM.unmountComponentAtNode(container);
};
2. メインアプリケーションでのサブアプリ登録
const microApps = [
{
name: 'vue2-app',
entry: '//localhost:9004',
container: '#app-container',
activeRule: '/vue2'
},
{
name: 'vue3-app',
entry: '//localhost:9005',
container: '#app-container',
activeRule: '/vue3'
}
];
3. ルートインターセプトの実装
const originalPushState = window.history.pushState;
window.history.pushState = function(...args) {
const result = originalPushState.apply(this, args);
window.dispatchEvent(new CustomEvent('microfrontend-route-change'));
return result;
};
4. ライフサイクル管理
const lifecycles = {
beforeMount: [],
afterMount: [],
beforeUnmount: []
};
export const registerLifecycle = (type, callback) => {
lifecycles[type].push(callback);
};
export const executeLifecycles = async (type) => {
for (const callback of lifecycles[type]) {
await callback();
}
};
5. HTMLの読み込みと解析
export const loadApplicationHTML = async (url) => {
const response = await fetch(url);
const html = await response.text();
const parser = new DOMParser();
return parser.parseFromString(html, 'text/html');
};
6. 実行環境の分離
class Sandbox {
constructor() {
this.proxyWindow = {};
}
execute(code) {
const executeCode = `(function(window) {
${code}
})(this.proxyWindow)`;
eval(executeCode);
}
}
7. CSSスタイルの分離
const scopedCSS = (css, scopeId) => {
return css.replace(/([^{]+){/g, (match, selector) => {
return `${selector}[data-scope="${scopeId}"] {`;
});
};
8. アプリケーション間通信
class EventBus {
constructor() {
this.events = {};
}
emit(event, data) {
if (this.events[event]) {
this.events[event].forEach(callback => callback(data));
}
}
on(event, callback) {
if (!this.events[event]) this.events[event] = [];
this.events[event].push(callback);
}
}
window.microFrontendEventBus = new EventBus();
9. グローバル状態管理
class GlobalStore {
constructor(initialState = {}) {
this.state = initialState;
this.subscribers = [];
}
setState(newState) {
this.state = { ...this.state, ...newState };
this.subscribers.forEach(subscriber => subscriber(this.state));
}
subscribe(callback) {
this.subscribers.push(callback);
}
}
window.globalStore = new GlobalStore();
10. パフォーマンス最適化
export const prefetchApplications = async (apps) => {
const prefetchPromises = apps.map(app => {
return fetch(app.entry).then(response => response.text());
});
await Promise.all(prefetchPromises);
};
既存マイクロフロントエンドフレームワーク
Qiankunフレームワーク
QiankunはSingle-SPAをベースにしたマイクロフロントエンドフレームワークで、サンドボックス、プリフェッチ、アプリケーション間通信などの機能を提供します。
Single-SPAフレームワーク
Single-SPAはマイクロフロントエンドのルーティングとライフサイクル管理を担当するコアライブラリで、様々なフレームワークの統合を可能にします。