微前端之子应用的启动与改造

本文假设你已经创建好了所有子应用。

启动

微前端中往往有多个子应用。

如果要同时启动所有的子应用,你当然可以一个一个的去启动。

如果你嫌这样麻烦的话,接着往下看。

你可以创建这样一个启动脚本文件,命名为 run.js。这个脚本会通过 child_process 创建多个 shell 命令,每个命令负责一个应用,具体代码如下:

js 复制代码
const childProocess = require('child_process')
const path = require('path')

const filePath = {
  vue2: path.join(__dirname, '../vue2'),
  vue3: path.join(__dirname, '../vue3'),
  react15: path.join(__dirname, '../react15'),
  react16: path.join(__dirname, '../react16'),
  main: path.join(__dirname, '../main'),
}
// 进入子目录 npm start 启动项目
function runChild () {
  Object.values(filePath).forEach(item => {
    childProocess.spawn(`cd ${item} && npm start`, {
      stdio: "inherit",
      shell: true
    })
  })
}
runChild()

修改最外层 package.json

json 复制代码
{
  "scripts": {
    "start": "node run.js"
  }
}

执行 npm start,所有应用都会被启动。

注意:每个子应用的启动脚本要统一为 npm start

改造

子应用要想接入微前端,肯定得需要改造,主要调整是在入口文件。

这里分别拿 Vue3 和 React16 举例。

Vue3

改造前:

js 复制代码
import { createApp } from 'vue'
import App from './App.vue'

import router from './router'
createApp(App).use(router).mount('#app')

改造后:

js 复制代码
import { createApp } from 'vue'
import App from './App.vue'

import router from './router'

let instance = null

const render = () => {
  instance = createApp(App)
  instance.use(router).mount('#app')
}

// 不在微前端环境
if(!window.__MICRO_WEB__) {
  render()
}

export const bootstrap = () => {
  console.log('开始加载');
}

export const mount = () => {
  render()
  console.log('渲染成功')
}

export const unmount = () => {
  console.log('卸载', instance)
}

React16

改造前:

js 复制代码
import React from 'react'
import "./index.scss"
import ReactDOM from 'react-dom'
import BasicMap from './src/router';

ReactDOM.render((
    <BasicMap />
  ), document.getElementById('app-react'))

改造后:

js 复制代码
import React from 'react'
import "./index.scss"
import ReactDOM from 'react-dom'
import BasicMap from './src/router';

const render = () => {
  ReactDOM.render((
    <BasicMap />
  ), document.getElementById('app-react'))
}

// 不在微前端环境
if (!window.__MICRO_WEB__) {
  render()
}

export const bootstrap = () => {
  console.log('开始加载');
}

export const mount = () => {
  render()
}

export const unmount = () => {
  console.log('卸载')
}

改造完成后,在 window.vue3 或 window.react16 中都会多出 bootstrapmountunmount 这三个方法。(vue3 和 react16 是在 vue.config.jswebpack.config.js 中分别定义的 library 名字)。

原理分析

webpack 默认打包成立即执行函数:

js 复制代码
(function(){
    ...
})()

如果设置了 library,webpack 将会把打包的结果赋于 library 定义的变量:

js 复制代码
var react16 = (function(){
    ...
})()
相关推荐
三声三视几秒前
React 19 正式发布!17 个新特性深度解析与迁移指南(2026 实战版)
前端·javascript·reactjs·react
滴滴答答哒3 分钟前
c#将平铺列表转换为树形结构(支持孤儿节点作为独立根节点)
java·前端·c#
雨季mo浅忆3 分钟前
第四项目梳理
前端·面试·vue2
a1117764 分钟前
三维地图可视化 ThreeJS vue 开源项目
前端·javascript·vue.js
接着奏乐接着舞。2 小时前
部署BFF与前端的踩坑与经验记录
前端·node.js
小李子呢02119 小时前
前端八股CSS(2)---动画的实现方式
前端·javascript
不懂的浪漫10 小时前
mqtt-plus 架构解析(六):多 Broker 管理,如何让一个应用同时连接多个 MQTT 服务
spring boot·分布式·物联网·mqtt·架构
GreenTea11 小时前
从 Claw-Code 看 AI 驱动的大型项目开发:2 人 + 10 个自治 Agent 如何产出 48K 行 Rust 代码
前端·人工智能·后端
不懂的浪漫11 小时前
mqtt-plus 架构解析(十):从内部项目到开源框架,mqtt-plus 的抽取过程与决策
spring boot·mqtt·架构·开源