zoukankan      html  css  js  c++  java
  • 微前端实践

    微前端的方案采用

    一.iframe

    只需简单的几句代码,就可以将子应用内嵌入主应用中,但是有各种缺点,所以不建议使用

    二.single-spa

    安装single-spa

    npm install single-spa --save

     主应用

    1.需要手动的加载子应用的资源

    import * as singleSpa from "single-spa";
    import axios from "axios";
    const runScript = (url) => {
      return new Promise((resolve, reject) => {
        const script = document.createElement("script");
        script.src = url;
        script.onload = resolve;
        script.onerror = reject;
        const firstScript = document.getElementsByTagName("script")[0];
        firstScript.parentNode.insertBefore(script, firstScript);
      });
    };
    const getManifest = (url, bundle) =>
      new Promise(async (resolve, reject) => {
        const { data } = await axios.get(url);
        const { entrypoints, publicPath } = data;
        const assets = entrypoints[bundle].assets;
        for (let i = 0; i < assets.length; i++) {
          await runScript(publicPath + assets[i]).then(() => {
            if (i === assets.length - 1) {
              resolve();
            }
          });
        }
      });
    singleSpa.registerApplication(
      "vue-child",
      async () => {
          let vueChild = null
          await getManifest("http://127.0.0.1:3000/stats.json",'app').then(resp=>{
            vueChild = window.vueChild
          })
        // await runScript("http://127.0.0.1:3000/js/chunk-vendors.js"); 如果资源较少 可以直接写死需要加载的资源
        // await runScript("http://127.0.0.1:3000/js/app.js");
        return vueChild;
      },
      (location) => location.pathname.startsWith("/vue") //路由匹配规则,返回true就渲染
    );
    
    singleSpa.start();

    2.设置需要挂载的节点

      <div id="vue">
      </div>

    3.设置路由,访问路径

    import VueRouter from 'vue-router'
    import Vue from 'vue'
    Vue.use(VueRouter)
    const routes = [{
        path:'/vue',
        name:'vue'
    
    }]
    const router = new VueRouter({
        mode:'history',
        routes
    })
    export default router

    子应用

    1.main.js里面暴露出给父应用调用的方法

    import Vue from "vue";
    import App from "./App.vue";
    import router from "./router";
    import singleSpaVue from "single-spa-vue";
    Vue.config.productionTip = false;
    
    const appOptions = {
      el: "#vue", //挂载在父应用中的id为vue的标签中
      router,
      render: (h) => h(App),
    };
    const vueLifeCycles = singleSpaVue({
      Vue,
      appOptions,
    });
    //协议接入,父应用会调用这些方法
    export const bootstrap = vueLifeCycles.bootstrap;
    export const mount = vueLifeCycles.mount;
    export const unmount = vueLifeCycles.unmount;
    
    //如果是父应用引用我 动态设置子应用的publicPath
    if (window.singleSpaNavigate) {
      __webpack_public_path__ = "http://localhost:10000/";
    }
    //没有调用我的时候,我自己可以跑起来
    if (!window.singleSpaNavigate) {
      delete appOptions.el;
      new Vue(appOptions).$mount("#app");
    }

    2. 路由base设置成主应用访问的链接 例如 /vue

    3.vue.config.js里面配置

    const StatsPlugin = require("stats-webpack-plugin"); //可以统计打包的数据,方便主应用加载资源
    module.exports = {
      publicPath: "//127.0.0.1:3000",
      configureWebpack: {
        output: {
          library: "vueChild",
          libraryTarget: "window", //或者umd 
        },
        plugins: [
          new StatsPlugin('stats.json',{
            chunkModules: false,
            entryPoints: true,
            source: false,
            chunks: false,
            modules: false,
            assets: false,
            children: false,
            exclude: [/node_modules/],
          }),
        ],
      },
    };

    4.需要手动处理css隔离,新建postcss.config.js

    module.exports ={
        plugins:{
            'postcss-selector-namespace':{
                namespace(){
                    return '.single-vue-child'
                }
            }
        }
    }

    single-spa最大的作用就是加载资源,其他的缺点还是挺多的,隔离这块就没有很好地处理

    三.qiankun

    安装qiankun 

    npm install qiankun --save

    是踩在single-spa的肩膀上

    主应用

    1.注册子应用

    import { registerMicroApps, start } from "qiankun";
    const apps = [
      {
        name: "vue",
        entry: "//localhost:8080",
        container: "#vue",
        activeRule: "/vue",
      },
    ];
    registerMicroApps(apps)
    start()

    2.挂载子应用

    <div id="vue"></div>

    子应用

    1.在main.js中暴露方法

    let instance = null;
    function render() {
      instance = new Vue({
        router,
        store,
        render: h => h(App)
      }).$mount("#app");
    }
    if (window.__POWERED_BY_QIANKUN__) {
      __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
    }
    if (!window.__POWERED_BY_QIANKUN__) {
      render();
    }
    export async function bootstrap() {
    }
    export async function mount(props) {
      render();
    }
    export async function unmount() {
      instance.$destroy();
    }

    2.vue.config.js的配置

    解决跨域问题 

       headers: {
          "Access-Control-Allow-Origin": "*"
        },

    配置导出的文件名

     configureWebpack: {
        output: {
          library: "vue",
          libraryTarget: "umd"
        },
    }

     四.qiankun的各种踩坑

    1.路由切换css样式出错,部署后刷新404 

    这些是没处理主应用history模式下的各种配置问题,需要设置vue.config.js 里面的publicPath:'/',nginx配置

     location / {
             try_files $uri $uri/ /index.html;
        }

    2.微应用打包之后,css中的字体文件和图片加载404

    //vue-cli3项目写法 
    chainWebpack(config) {
        // set svg-sprite-loader
        config.module
          .rule("svg")
          .exclude.add(resolve("src/icons"))
          .end();
     //处理icons
        config.module
          .rule("icons")
          .test(/.svg$/)
          .include.add(resolve("src/icons"))
          .end()
          .use("svg-sprite-loader")
          .loader("svg-sprite-loader")
          .options({
            symbolId: "icon-[name]",
          })
          .end();
        //fonts
        config.module
          .rule("fonts")
          .use("url-loader")
          .loader("url-loader")
          .options({})
          .end();
    }

    3.未完待续

  • 相关阅读:
    01视频传输,监控,直播方案摄像头如何采集的图像,MCU如何读取的图像数据
    203ESP32_SDK开发softAP+station共存模式
    2视频传输,监控,直播方案搭建视频流服务器,推送视频流,拉取视频流观看(RTMP,m3u8)
    F# (Part one)
    测试驱动开发(一)我们要的不仅仅是“质量”
    软件开发中的破窗效应
    结对编程神奇的力量
    《高性能网站建设指南》笔记
    【线程呓语】Thread
    【线程呓语】与线程相关的一些概念
  • 原文地址:https://www.cnblogs.com/alhh/p/14282567.html
Copyright © 2011-2022 走看看