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

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

启动

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

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

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

你可以创建这样一个启动脚本文件,命名为 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 中都会多出 bootstrap、mount、unmount 这三个方法。(vue3 和 react16 是在 vue.config.js 和 webpack.config.js 中分别定义的 library 名字)。

原理分析

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

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

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

js 复制代码
var react16 = (function(){
    ...
})()
相关推荐
星栈7 分钟前
pnpm 12 升级实测
前端·javascript
欣欣之王来了13 分钟前
Python入门:什么是Python以及为什么选择它
学习·架构·面向对象·项目·python教程
Sirens.22 分钟前
Java并发锁详解:六类锁策略与 synchronized 底层原理
java·前端·算法
代码方舟1 小时前
零信任架构实战:基于天远运营商三要素简版V即时版查询构建自动化电子投保实名核验网关
大数据·人工智能·架构·自动化
特创数字科技2 小时前
一个纯本地运行的图片处理工具:压缩 / 裁剪 / 九宫格 / 圆角 / 滤镜 / 拼图 / 水印,终生使用
前端
诚心呈意共享外卖配送系统2 小时前
众包配送调度系统选什么?聊聊派单、抢单、合单与结算的技术设计
架构·系统架构·创业创新
IT_陈寒2 小时前
Vue的v-if和v-for混用居然是个天坑
前端·人工智能·后端
天衍四九-2 小时前
【无标题】
前端·spring boot·mysql·nginx·docker
广州华水科技2 小时前
2026年单北斗GNSS变形监测系统推荐榜单,解锁GNSS位移监测新高度
前端
xcyxiner3 小时前
DicomViewer24 修复编译bug(window test 失败)
前端·qt