美文网首页
微前端-qiankun

微前端-qiankun

作者: Mr无愧于心 | 来源:发表于2022-04-21 11:00 被阅读0次

    微前端提供通过不同技术栈、能够以单独发布的方式将多个子应用构建成一个主应用的技术方案。
    所以结构分为主框架,和任意多个子应用。

    核心价值
    1. 和技术栈无关,每个子应用可以选择不同的技术栈
    2. 子应用可以单独开发、部署,部署完后主框架自动完成同步更新。
    3. 每个子应用可以独立运行
    使用场景

    一般适用于较大型的项目,需要将项目拆分成多个子应用并合并,不同的业务模块之间相对独立,可单独开发部署的项目。

    Dome
    1. 建三个项目,包括一个主应用(qiankun-base),两个子应用(qiankun-vue、qiankun-react) 可以用脚手架生成(vue create 、create-react-app)
    2. 安装包 qiankun
    3. 尽量端口号不一样,保证三个项目能够同时跑起来
    主应用(qiankun-base)

    dome选择vue作为基座
    修改入口文件src/App.vue

    <template>
      <div id="app">
        <el-menu :router="true" mode="horizontal">
          <!--基座中可以放自己的路由-->
          <el-menu-item index="/">Home</el-menu-item>
          <!--引用其他子应用路由-->
          <el-menu-item index="/vue">vue应用</el-menu-item>
          <el-menu-item index="/react">react应用</el-menu-item>
        </el-menu>
        <!-- 主应用自己的路由 -->
        <router-view></router-view>
        <!-- 子应用的渲染位置 -->
        <div id="vue"></div>
        <div id="react"></div>
      </div>
    </template>
    

    修改src/main.js引入qiankun

    // 引入qiankun
    import { registerMicroApps, start } from 'qiankun';
    
    const apps = [
      {
        name: 'vueApp', // 子应用的名字
        entry: '//localhost:8081', // 默认会加载这个html 解析里面的js 动态的执行 (子应用必须支持跨域)fetch
        container: '#vue', // App.vue中容器名(此项目页面中定义的容器id,用于把对应的子应用放到此容器中)
        activeRule: '/vue', // 激活的路径
        props: { a: 1 } // 传递的值(可选)
      },
      {
        name: 'reactApp',
        entry: '//localhost:20000', // 默认会加载这个html 解析里面的js 动态的执行 (子应用必须支持跨域)fetch
        container: '#react',
        activeRule: '/react',
      }
    ]
    registerMicroApps(apps); // 注册应用
    start({
      prefetch: false // 取消预加载
    });// 开启
    const router = new VueRouter({
        mode: "history",
        routes,
      });
    new Vue({
        router,
        render: h => h(App),
      }).$mount('#app')
    
    子应用(qiankun-vue)

    src/main.js

    import Vue from 'vue'
    import App from './App.vue'
    // import router from './router'
    
    // Vue.config.productionTip = false
    
    let instance = null
    function render(props) {
      instance = new Vue({
        // router,
        render: h => h(App)
      }).$mount('#vueApp'); // 这里是挂载到自己的html中  基座会拿到这个挂载后的html 将其插入进去
    }
    
    if (window.__POWERED_BY_QIANKUN__) { // 动态添加publicPath
      __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
    }
    if (!window.__POWERED_BY_QIANKUN__) { // 默认独立运行
      render();
    }
    
    // 父应用加载子应用,子应用必须暴露三个接口:bootstrap、mount、unmount
    // 子组件的协议就ok了
    export async function bootstrap(props) {
    
    };
    
    export async function mount(props) {
      render(props)
    }
    
    export async function unmount(props) {
      instance.$destroy();
    }
    
    

    public/index.html

    <div id="vueApp"></div>
    

    vue.config.js

    module.exports = {
        lintOnSave: false,  // 关闭eslint检测
        devServer: {
            port: 8080,//这里的端口是必须和父应用配置的子应用端口一致
            headers: {
                //因为qiankun内部请求都是fetch来请求资源,所以子应用必须允许跨域
                'Access-Control-Allow-Origin': '*'
            }
        },
        configureWebpack: {
            output: {
                //资源打包路径
                library: 'vueApp',
                libraryTarget: 'umd'
            }
        }
    }
    
    子应用(qiankun-react)

    安装包:react-app-rewired
    src/index.js

    import React from 'react';
    import ReactDOM from 'react-dom';
    import './index.css';
    import App from './App';
    
    function render(){
      ReactDOM.render(
        <React.StrictMode>
          <App />
        </React.StrictMode>,
        document.getElementById('root')
      );
    }
    
    if(!window.__POWERED_BY_QIANKUN__){
      render();
    }
    
    export async function bootstrap(){
     
    }
    export async function mount() {
      render()
    }
    export async function unmount(){
      ReactDOM.unmountComponentAtNode( document.getElementById('root'));  // 卸载节点
    }
    

    qiankun-react下创建config-overrides.js

    module.exports = {
        webpack: (config) => {
            config.output.library = 'reactApp';
            config.output.libraryTarget = 'umd';
            config.output.publicPath = 'http://localhost:20000/';   // 此应用自己的端口号
            return config;
        },
        devServer: (configFunction) => {
            return function (proxy, allowedHost) {
                const config = configFunction(proxy, allowedHost);
                config.headers = {
                    "Access-Control-Allow-Origin": '*'
                }
                return config
            }
        }
    }
    

    qiankun-react下创建.env文件

    PORT=20000
    BROWSER=none
    

    修改package.json的启动命令

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

    相关文章

      网友评论

          本文标题:微前端-qiankun

          本文链接:https://www.haomeiwen.com/subject/elqglrtx.html