micro-app
micro-app copied to clipboard
How to render same micro app twice on the same page?
How i can render same app twice on the same page?
I ve managed to figure out how to pass data from main app to child app in order to tell on which path to render
But second component not renders and I get following error:
my code in the main app:
microApp.start({
plugins: {
modules: {
react1: [{
loader(code: string) {
//if (process.env.NODE_ENV === 'development') {
code = code.replace(/(from|import)(\s*['"])(\/app-react1\/)/g, (all) => {
return all.replace('/app-react1/', 'http://localhost:7002/app-react1/')
})
// }
return code
}
}],
react2: [{
loader(code: string) {
//if (process.env.NODE_ENV === 'development') {
code = code.replace(/(from|import)(\s*['"])(\/app-react1\/)/g, (all) => {
return all.replace('/app-react1/', 'http://localhost:7002/app-react1/')
})
// }
return code
}
}]
}
},
/**
* 自定义fetch
* @param url 静态资源地址
* @param options fetch请求配置项
* @returns Promise<string>
*/
async fetch(url, options, _appName) {
if (url === 'http://localhost:3001/error.js') {
return Promise.resolve('')
}
let config = null
if (url === 'http://localhost:3001/micro-app/react16/') {
config = {
headers: {
'custom-head': 'custom-head',
}
}
}
const res = await fetch(url, Object.assign(options, config));
return await res.text();
}
})
and declaring in component:
<template>
<div class="vite">
<micro-app
name='react1'
url='http://localhost:7002/app-react1/'
inline
>
<!-- destroy inline scopecss='false' -->
</micro-app>
</div>
<div class="vite">
+++++
<micro-app
name='react2'
url='http://localhost:7002/app-react1/'
inline
>
<!-- destroy inline scopecss='false' -->
</micro-app>
</div>
</template>
<script lang="ts">
import microApp, { EventCenterForMicroApp } from '@micro-zoe/micro-app';
//@ts-ignore
window.eventCenterForReact1 = new EventCenterForMicroApp('react1')
//@ts-ignore
window.eventCenterForReact2 = new EventCenterForMicroApp('react2')
microApp.setData('react1',{component_path:'/user-select'})
microApp.setData('react2',{component_path:'/selected-user-widget'})
</script>
<style>
</style>
in the child app i get both paths as it should.
What i am doing wrong? Thankyou.
micro app is vite?
yes
vite doesn't support yet
is there any workaround?
No, we're working on it
Maybe i can contribute with something? I am not an expert in mfe. but if I could get some documentations and some details what/where to search i can make a try
Update: I think i found kind of workaround problem is that sometime it shows only first component, and i cant understand why? data always is coming as it should.
ok:
renders only first instance of the app:

what i do:
First i declare as normal two
// TwiceFromSameMicroAppWithDiferentComponents.vue
<template>
<div class="vite">
<micro-app
name='react1'
url='http://localhost:7002/app-react1/'
inline
>
<!-- destroy inline scopecss='false' -->
</micro-app>
</div>
<div class="vite">
+++++
<micro-app
name='react2'
url='http://localhost:7002/app-react1/'
inline
>
<!-- destroy inline scopecss='false' -->
</micro-app>
</div>
</template>
<script lang="ts">
import microApp, { EventCenterForMicroApp } from '@micro-zoe/micro-app';
//@ts-ignore
window.eventCenterForReact1 = new EventCenterForMicroApp('react1')
//@ts-ignore
window.eventCenterForReact2 = new EventCenterForMicroApp('react2')
microApp.setData('react1',{component_path:'/user-select',__MICRO_APP_NAME__:'react1'})
microApp.setData('react2',{component_path:'/selected-user-widget',__MICRO_APP_NAME__:'react2'})
</script>
<style>
</style>
and in micro app i do following:
// main.tsx
import React from 'react'
import ReactDOM, { Root } from 'react-dom/client'
import App from './App'
import './index.css'
let root: Root|undefined
let gdata:{component_path?:string,__MICRO_APP_NAME__:string} |undefined
export function mount ():void {
if (!root) {
root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement)
}
root.render(
<React.StrictMode>
<App name = {gdata?.__MICRO_APP_NAME__}/>
</React.StrictMode>
)
}
export function unmount ():void {
root?.unmount()
}
// @ts-ignore
if (window.eventCenterForReact1) {
// @ts-ignore
window.eventCenterForReact1?.addDataListener((data:{component_path?:string,__MICRO_APP_NAME__:string}) => {
gdata = data
console.log('eventCenterForReact1', gdata)
// 当基座下发跳转指令时进行跳转
setGlobalMicroAppName()
console.log('push')
//@ts-ignore
window.eventCenterForReact1 = undefined
}, true)
//@ts-ignore
} else if(window.eventCenterForReact2) {
//@ts-ignore
window.eventCenterForReact2?.addDataListener((data:{component_path?:string,__MICRO_APP_NAME__:string}) => {
gdata = data
console.log('eventCenterForReact2', gdata)
// 当基座下发跳转指令时进行跳转
setGlobalMicroAppName()
console.log('push')
}, true)
}else {
mount()
}
function setGlobalMicroAppName(){
console.log('app name:',gdata?.__MICRO_APP_NAME__ )
//@ts-ignore
window[`micro-app-${gdata.__MICRO_APP_NAME__}`] = { mount, unmount }
}
if micro app is vite, we do not recommend using micro-app for the time being, it will cause a lot of problems, and this is exactly what we need to do
do you have any issue tracker related vite integration?