qiankun-前端微服务化搭建

创建vue项目 vue create qiankun-base

安装qiankun 插件 $ yarn add qiankun # 或者 npm i qiankun -S

只需要在主应用安装qiankun 即可,最重要的是webpack版本必须在4.0.0,不然会报jsonpfunction 错误。

主应用  首先在主应用的 main.js里边只做了两件事,就是注册子应用和启动qiankun

 

import {

  registerMicroApps,

  start,

  setDefaultMountApp

} from "qiankun"
//当匹配到 activeRule 的时候,请求获取 entry 资源,渲染到 container 中
const apps = [{
    name: 'vueApp',
    entry: '//localhost:8081', //子应用的html入口
    container: '#container', //渲染入口节点
    activeRule: '/app-vue', //路由匹配规则
    props: {
      msg: "我是子应用app-vue"
    }
  },
  {
    name: 'reactApp',
    entry: '//localhost:8082',
    container: '#container',
    activeRule: '/app-react',
    props: {
      msg: "我是子应用app-react"
    }
  },
]
//微前端运行原理类似于SPA
registerMicroApps(apps);
// 启动 qiankun
start();
//默认渲染的子应用
// setDefaultMountApp("/app-vue");

 

主应用的app.vue 文件

 
<template>
  <div>
    <el-menu :router="true" mode="horizontal">
      <!-- 子应用 -->
      <el-menu-item index="/">home</el-menu-item>
      <el-menu-item index="/app-vue">vue</el-menu-item>
      <el-menu-item index="/app-react">react</el-menu-item>
    </el-menu>

    <!-- 主应用路由出口 -->
    <router-view />
    <div id="container"></div>
  </div>
</template>

 

 
vue子应用  main.js按如下修改
 
import './public-path';
import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router';
import routes from './router'
import store from './store'

Vue.config.productionTip = false

let router = null;
let instance = null;

function render(props = {}) {
  const {
    container
  } = props;
  router = new VueRouter({
    base: window.__POWERED_BY_QIANKUN__ ? '/app-vue/' : '/',
    mode: 'history',
    routes,
  });
  instance = new Vue({
    router,
    store,
    render: (h) => h(App),
  }).$mount(container ? container.querySelector('#app') : '#app');
}

// 独立运行时 加载的是当前文档的节点
if (!window.__POWERED_BY_QIANKUN__) {
  render();
}

//生命周期函数必须返回promise
export async function bootstrap() {
  console.log('初始化 只执行一次');
}
export async function mount(props) {
  console.log('渲染函数', props);
  render(props);
}
export async function unmount() {
  console.log("卸载函数");
  instance.$destroy();
  instance.$el.innerHTML = '';
  instance = null;
  router = null;
}

 

 
项目根目录中添加vue.config.js
 
let {
  name
} = require('./package');
module.exports = {
  devServer: {
    port: 8081,
    //允许跨域
    headers: {
      'Access-Control-Allow-Origin': '*',
    },
  },
  configureWebpack: {
    output: {
      library: `${name}-[name]`,
      libraryTarget: 'umd', // 把微应用打包成 umd 库格式
      jsonpFunction: `webpackJsonp_${name}`,
    },
  },
};
src目录下添加public-path.js
//webpack 在运行时生成的路径会自动拼接上这个全局变量(如果有的话)
if (window.__POWERED_BY_QIANKUN__) {
  __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}

 

 
package.json中添加  目的是暴漏 __webpack_public_path__ 
//暴漏全局变量
{
"eslintConfig": { "globals": { "__webpack_public_path__": true } } }

路由文件中 index.js
//history模式
const router = new VueRouter({
  mode: 'history',
  base: '/vue',
  routes
})
 
//hash模式
const router = new VueRouter({
  mode: "hash",
  base: window.__POWERED_BY_QIANKUN__ ? "/child/" : "/",
  routes,
});

 

react 子应用

   创建react项目 npx create-react-app qiankun-react


   重写webpack配置  yarn add react-app-rewired

   修改 package.json  文件

 
   "scripts": {
    "start": "react-app-rewired start",
    "build": "react-app-rewired build",
    "test": "react-app-rewired test",
     "eject": "react-app-rewired eject"
     },

 

react 子应用 index.js 文件配置

 
import './index.css';
import './public-path';
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

function render(props) {
  const {
    container
  } = props;
  ReactDOM.render( < App / > , container ? container.querySelector('#root') : document.querySelector('#root'));
}

if (!window.__POWERED_BY_QIANKUN__) {
  render({});
}

export async function bootstrap() {
  console.log('[react16] react app bootstraped');
}

export async function mount(props) {
  console.log('[react16] props from main framework', props);
  render(props);
}

export async function unmount(props) {
  const {
    container
  } = props;
  ReactDOM.unmountComponentAtNode(container ? container.querySelector('#root') : document.querySelector('#root'));
}

 

index.js 同级目录下添加public-pathpath.js文件
if (window.__POWERED_BY_QIANKUN__) {
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}

 

 
根目录下 手动添加 config-overrides.js 
 
const {
  name
} = require('./package');

module.exports = {
  webpack: (config) => {
    config.output.library = `${name}-[name]`;
    config.output.libraryTarget = 'umd';
    // config.output.jsonpFunction = `webpackJsonp_${name}`;
    config.output.globalObject = 'window';
    config.output.publicPath = 'http://localhost:8082/';
    return config;
  },

  devServer: (_) => {
    const config = _;

    config.headers = {
      'Access-Control-Allow-Origin': '*',
    };
    config.historyApiFallback = true;
    config.hot = false;
    config.watchContentBase = false;
    config.liveReload = false;

    return config;
  },
};

 

 
根目录 创建 .env 文件 配置端口
 
PORT=8082
WDS_SOCKET_PORY=8082    //默认的端口是3000

 

posted @ 2022-02-23 11:15  波仔、  阅读(116)  评论(0编辑  收藏  举报