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

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

启动

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

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

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

你可以创建这样一个启动脚本文件,命名为 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(){
    ...
})()
相关推荐
没有bug.的程序员11 分钟前
微服务基础设施清单:必须、应该、可以、无需的四级分类指南
java·jvm·微服务·云原生·容器·架构
郑州光合科技余经理15 分钟前
海外国际版同城服务系统开发:PHP技术栈
java·大数据·开发语言·前端·人工智能·架构·php
一行注释28 分钟前
前端数据加密:保护用户数据的第一道防线
前端
纪伊路上盛名在33 分钟前
记1次BioPython Entrez模块Elink的debug
前端·数据库·python·debug·工具开发
xiaoxue..35 分钟前
React 之 Hooks
前端·javascript·react.js·面试·前端框架
旧梦吟40 分钟前
脚本网页 三人四字棋
前端·数据库·算法·css3·html5
莫物42 分钟前
element el-table表格 添加唯一标识
前端·javascript·vue.js
我看刑43 分钟前
【已解决】el-table 前端分页多选、跨页全选等
前端·vue·element
-大头.1 小时前
数据库高可用架构终极指南
数据库·架构
我会一直在的1 小时前
Fiddler基础使用介绍
前端·测试工具·fiddler