<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
      xsnow
      機遇總是留給有準備的人

      路由為hash模式

      一、主應用配置

      1、安裝 qiankun
      yarn add qiankun 或者 npm i qiankun -S
      
      2、注冊微應用并啟動
      import { registerMicroApps, start } from 'qiankun';
      
      const isDev = process.env.NODE_ENV === "development";
      const apps = [
        {
          name: 'FirstMicroApp',
          entry: isDev ? '//localhost:8082' : '/first-micro-app/',
          container: '#microAppContainer',
          activeRule: '#/exhibitionHall',
        },
      ];
      registerMicroApps(apps, {
        beforeLoad: [
          // app => {
          //   console.log("before load", app);
          // }
        ],
        beforeMount: [
          // app => {
          //   console.log("before mount", app);
          // }
        ],
        afterUnmount: [
          // app => {
          //   console.log("after unMount", app);
          // }
        ],
      });
      
      // 啟動 qiankun
      start();
      

      二、微應用配置

      1、在 src 目錄新增 public-path.js
      /* eslint-disable */
      if (window.__POWERED_BY_QIANKUN__) {
        __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
      }
      
      2、入口文件 main.ts 修改
      import './public-path';
      import { createApp } from 'vue';
      import Antd from 'ant-design-vue';
      import App from './App.vue';
      import router from './router';
      import store from './store';
      import 'ant-design-vue/dist/antd.css';
      
      // createApp(App).use(store).use(router).mount('#app');
      
      type Props = {
        container?: HTMLElement;
      }
      
      let app: any = null;
      
      function render(props: Props = {}) {
        const { container } = props;
        app = createApp(App);
        app.use(router);
        app.use(store);
        app.use(Antd);
        app.mount(container ? container.querySelector('#app') : '#app');
      }
      
      // 獨立運行時
      // eslint-disable-next-line
      if (!window.__POWERED_BY_QIANKUN__) {
        render();
      }
      
      export async function bootstrap(): Promise<void> {
        console.log('vue app bootstraped');
      }
      
      export async function mount(props: Props): Promise<void> {
        render(props);
      
        // 注冊全局主應用路由 mainRouter
        // const { mainRouter } = props;
        // app.config.globalProperties.$mainRouter = mainRouter;
      }
      
      export async function unmount(): Promise<void> {
        app.unmount();
        app = null;
      }
      
      3、打包配置 vue.config.js 修改
      const { name } = require('./package.json');
      const port = 8082;
      const isDev = process.env.NODE_ENV === 'development';
      
      module.exports = {
        publicPath: dev ? '/' : '/first-micro-app/',
        devServer: {
          port,
          headers: {
            'Access-Control-Allow-Origin': '*',
          },
        },
        configureWebpack: {
          output: {
            library: `${name}-[name]`,
            libraryTarget: 'umd',
            jsonpFunction: `webpackJsonp_${name}`,
          },
        },
      }
      

      三、批量打包

      1、在主應用與微應用同級新增 package.json 文件
      {
        "name": "qiankun-vue3",
        "version": "1.0.0",
        "private": true,
        "scripts": {
          "install:all": "node scripts/index.js --serial install",
          "serve:all": "node scripts/index.js --parallel serve",
          "build:all": "yarn run buildApp && yarn run cpApp",
          "buildApp": "node scripts/index.js --serial build",
          "cpApp": "node scripts/build.js" 
        }
      }
      
      2、在主應用與微應用同級新增 scripts 文件夾
      2.1 批量 install、serve、build

      scripts 文件夾中新增 spawn.js 文件

      const crossSpawn = require("child_process").spawn;
      
      function kill() {
        const platform = process.platform;
        if (platform === "win32") {
          crossSpawn("taskkill", ["/F", "/T", "/PID", this.pid]);
        } else {
          crossSpawn.kill(this.pid);
        }
      }
       
      module.exports = function spawn(command, args, options) {
        const child = crossSpawn(command, args, options);
        child.kill = kill;
      
        return child;
      }
      

      scripts 文件夾中新增 index.js 文件

      /**
       * argv[1]為 --parallel / --serial
       * argv[2]為 install / serve / build
       */
      const path = require('path');
      const fs = require('fs');
      const spawn = require('./spawn');
      
      const entry = path.resolve();
      const microApps = fs.readdirSync(entry).filter(app => /app$/.test(app));
      
      const remove = (array, x) => {
        const index = array.indexOf(x);
        if (index > -1) {
          array.splice(index, 1);
        }
      };
      
      const runApp = (app, task) => {
        let cp = null;
        const promise = new Promise((resolve, reject) => {
          const command = 'npm';
          const args = [];
          if (task === 'install') {
            args.push(task);
          } else {
            args.push('run', task);
          }
          
          const { stdin, stdout, stderr } = process;
          const options = {
            stdio: [stdin, stdout, stderr],
          };
          if (app) {
            options.cwd = path.resolve(app);
          }
      
          cp = spawn(command, args, options);
      
          cp.on("error", (err) => {
            cp = null;
            reject(err);
          });
      
          cp.on("close", (code) => {
            cp = null;
            resolve({ app, code });
          });
        });
      
        // kill pid
        promise.abort = () => {
          if (cp) {
            cp.kill();
            cp = null;
          }
        };
      
        return promise;
      };
      
      const runApps = (apps) => {
        return new Promise((resolve, reject) => {
          if (apps.length === 0) {
            resolve([]);
            return;
          }
      
          const results = apps.map(app => ({ name: app, code: undefined }))
          const queue = apps.map((app, index) => ({ name: app, index }))
          const promises = [];
          let error = null;
          let aborted = false;
      
          const done = () => {
            if (error) {
              reject(error);
            }
            resolve(results);
          };
      
          const abort = () => {
            if (aborted) {
              return;
            }
            aborted = true;
            if (promises.length) {
              for (const p of promises) {
                p.abort();
              }
              Promise.all(promises).then(done, reject);
            } else {
              done();
            }
          };
          
          const next = (task) => {
            if (aborted) {
              return;
            }
            if (!queue.length) {
              if (!promises.length) {
                done();
              }
              return
            }
      
            const app = queue.shift();
            const promise = runApp(app.name, task);
            promises.push(promise);
            promise.then(
              result => {
                remove(promises, promise);
                
                if (aborted) {
                  return;
                }
      
                results[app.index].code = result.code
                
                if (result.code) {
                  error = {
                    name: result.app,
                    code: result.code,
                    results: results,
                  };
                  abort();
                  return;
                }
      
                next(task);
              },
              err => {
                remove(promises, promise);
                error = err;
                abort();
                return;
              },
            );
          };
      
          const [mode, task = ''] = process.argv.slice(2);
          
          if (!['--parallel', '--serial'].includes(mode)) {
            const error = 'process.argv第三個參數只能為--parallel、--serial其中之一';
            return reject(error);
          }
          if (!['install', 'serve', 'build'].includes(task)) {
            const error = 'process.argv第四個參數只能為install、serve、build其中之一';
            return reject(error); 
          }
          const len = mode === '--parallel' ? apps.length : 1;
          for (let i = 0; i < len; i++) {
            next(task);
          }
        });
      };
      
      // console.log('microApps', microApps);
      runApps(microApps)
        .then(result => {
          // console.log('ok');
        })
        .catch(error => {
          console.error('error: ', error);
        });
      
      2.2 批量拷貝 build 后的 dist 文件夾到 外層 dist 目錄
      /**
       * build
       * 先build到各自文件夾下的dist目錄,再拷貝到最外層dist目錄
       * 1、先刪除上次的dist目錄 rm -rf dist
       * 2、拷貝主應用dist到最外層dist cp -rf 20f6e232--cloud--FirstMainMicroApp/dist dist
       * 3、拷貝微應用dist到最外層dist中,且改名為對應微應用名稱 cp -rf 20f6e232--cloud--FirstSubMicroApp/dist dist/FirstSubMicroApp
       */
      // const { resolve, resolve: pathResolve } = require('path');
      const { resolve: pathResolve } = require('path');
      const { access, constants, readdirSync } = require('fs');
      const { spawn } = require('child_process');
      
      const entry = pathResolve();
      // const microApps = readdirSync(entry).filter(app => /app$/.test(app));
      const mainAppFolderName = 'main-app';
      const microAppFolderName = 'micro-app';
      const appNameRegex = new RegExp(`(${mainAppFolderName}|${microAppFolderName})$`)
      console.log('appNameRegex', appNameRegex);
      const microApps = readdirSync(entry).filter(app => appNameRegex.test(app));
      console.log('microApps', appNameRegex, microApps);
      
      // 文件夾是否存在
      const isExist = (dir) => {
        return new Promise((resolve, reject) => {
          access(dir, constants.F_OK, err => {
            // err為null時表示存在文件夾dir
            console.log('isExist', err);
            resolve(err);
          })
        })
      };
      
      // 刪除最外層目錄下文件夾
      const removeDir = (dir) => {
        return new Promise((resolve, reject) => {
          console.log('removedir', dir);
          const cp = spawn('rm', ['-rf', dir], { cwd: entry });
      
          cp.on('error', err => {
            console.error(`removeDir err: ${err}`);
            reject(err);
          });
      
          cp.on('close', code => {
            // 此時code為0
            console.log(`removeDir exited with code ${code}`);
            resolve({ code });
          });
        });
      };
      
      // 拷貝文件夾
      // cp -rf 20f6e232--cloud--FirstMainMicroApp/dist dist
      // cp -rf 20f6e232--cloud--FirstSubMicroApp/dist dist/FirstSubMicroApp
      const copyDir = (src, dst) => {
        return new Promise((resolve, reject) => {
          const cp = spawn('cp', ['-rf', src, dst], { cwd: entry });
      
          cp.on('error', err => {
            reject(err);
          });
      
          cp.on('close', code => {
            // 此時code為0
            resolve({ code });
          });
        })
      };
      
      // 先拷貝主應用dist到最外層目錄
      const copyMainDir = (dist) => {
        return new Promise((resolve, reject) => {
          const mainApp = microApps.find(app => app.includes(mainAppFolderName));
          const src = pathResolve(mainApp, dist);
          copyDir(src, dist)
            .then(res => resolve(res))
            .catch(err => reject(err));
        });
      };
      
      // 再拷貝微應用dist到主應用dist中, 且給微應用dist重命名
      const copySubDir = (dist) => {
        const promises = [];
        const subApps = microApps.filter(app => app.includes(microAppFolderName));
        console.log('subApps: ', subApps);
        subApps.forEach(app => {
          let rename = app;
          if (app.includes('--')) {
            const appNames = app.split('--');
            const len = appNames.length;
            rename = appNames[len - 1];
          }
          const src = pathResolve(app, dist);
          const dst = pathResolve(dist, rename);
          const promise = copyDir(src, dst);
          promises.push(promise);
        });
      
        return promises;
      };
      
      // 拷貝主應用與微應用所有dist目錄
      const copyDirs = (dir) => {
        copyMainDir(dir)
          .then(res => {
            Promise.all(copySubDir(dir))
              .then(res => {
                console.log('復制dist目錄成功');
              })
              .catch(err => { 
                console.log('復制微應用dist目錄失敗', err);
              });
          })
          .catch(err => {
            console.log('復制主應用dist目錄失敗', err);
          });
      };
      
      const buildMicroApps = async (dir) => {
        try {
          const isNull = await isExist(pathResolve(dir));
          if (!isNull) {
            const removeRes = await removeDir(dir);
            console.log('removeRes', removeRes);
            if (!removeRes.code) {
              copyDirs(dir);
            }
          } else {
            copyDirs(dir);
          }
        } catch(err) {
          console.log(err);
        }
      };
       
      buildMicroApps('dist');
      
      3、參考文件npm-run-all
      posted on 2022-02-15 09:56  xsnow  閱讀(936)  評論(0)    收藏  舉報

      主站蜘蛛池模板: 亚洲国内精品一区二区| 污污内射在线观看一区二区少妇| 亚洲综合在线日韩av| 蜜桃精品成人影片| 柠檬福利第一导航在线| 九九热免费公开视频在线| 国产午夜精品久久精品电影| 人妻少妇88久久中文字幕| 久久热在线视频精品视频| 亚洲国产精品一区二区久久| 精品国产午夜理论片不卡| 国产成人精品中文字幕| 无码av中文字幕免费放| 国产精品男女爽免费视频| 国产精品中文第一字幕| 秋霞av鲁丝片一区二区 | www插插插无码免费视频网站| 色综合AV综合无码综合网站| 中文字幕av中文字无码亚 | 国产成人精彩在线视频| 艳妇乳肉豪妇荡乳av| 狠狠躁天天躁中文字幕无码| 中美日韩在线一区黄色大片| 中文字幕日韩国产精品| 亚洲一区二区三区18禁| 国产办公室秘书无码精品99| 无码av中文一区二区三区桃花岛| 精品久久久久久无码不卡| 超碰伊人久久大香线蕉综合| 亚洲国产精品自产拍久久| 久久精品国产亚洲av麻豆长发| 少妇无码av无码一区| 人妻无码久久久久久久久久久| 亚欧乱色精品免费观看| 国产绿帽在线视频看| 免费一区二三区三区蜜桃| 国产精品无码久久久久| 国产剧情视频一区二区麻豆| 亚洲精品一区二区动漫| 日韩成人高精品一区二区| 精品国产自在久久现线拍|