基于qiankun微前端(支持vue2,vue3)及基于monorepo工作流的lerna改造前端项目(二)

入口应用

  1. 因为乾坤内部请求都是fetch来请求资源,所以子应用必须允许跨域
    webpack server中请求头需跨域: ‘Access-Control-Allow-Origin’: ‘*’
    2、main.js ,引入 registerMicroApps, start, initGlobalState
  2. 应用间通信(initGlobalState )
import { registerMicroApps, start, initGlobalState } from 'qiankun';

let propsData = {

}
const actions = initGlobalState(propsData);

// 主项目项目监听和修改(在项目中任何需要监听的地方进行监听)
actions.onGlobalStateChange((state, prev) => {

    // state: 变更后的状态; prev 变更前的状态
    console.log('改变前的值 ', prev);
    console.log('改变后的值 ', state);
});

// 将actions对象绑到Vue原型上,为了项目中其他地方使用方便
Vue.prototype.$actions = actions;
  1. 注册应用 (registerMicroApps)

const apps = [
    {
        name: 'webuiApp', // 应用的名字
        entry: 'https://localhost:997/index.html?remote=https://10.119.167.102#/index/overall_monitoring', // 默认会加载这个html 解析里面的js 动态的执行 (子应用必须支持跨域)fetch
        container: '#webui', // 容器名
        activeRule: '/main/webui', // 激活的路径
        props: propsData,
    },
    {
        name: 'easydeployApp',
        entry: 'http://127.0.0.1:3100', // 默认会加载这个html 解析里面的js 动态的执行 (子应用必须支持跨域)fetch
        container: '#easy',
        activeRule: '/main/easydeploy',
        props: propsData,
    },
    {
        name: 'vueApp',
        entry: 'https://localhost:8080', // 默认会加载这个html 解析里面的js 动态的执行 (子应用必须支持跨域)fetch
        container: '#vue',
        activeRule: '/main/vue',
        props: propsData,
    }
]

//注册子应用,在子应用激活时,创建运行沙箱,不同阶段调用不同的生命周期函数
//bootstrap - 初始化子应用,mount - 挂载子应用,unmount - 卸载子应用
registerMicroApps(apps, {

  // qiankun 生命周期钩子 - 微应用加载前
  beforeLoad: (app) => {
    // 加载微应用前,加载进度条
    NProgress.start();
    console.log("before load", app.name);
    return Promise.resolve();
  },
  // qiankun 生命周期钩子 - 微应用挂载后
  afterMount: (app) => {

    // 加载微应用前,进度条加载完成
    NProgress.done();
    console.log("after mount", app.name);
    return Promise.resolve();
  },
}); // 注册应用
  1. 开启
//预加载需要全局监听,在挂载第一个应用后预加载其他子应用的资源
//window.__POWERED_BY_QIANKUN__ 为true,在子应用判断是否运行在主应用容器中
start({
  prefetch: false // 取消预加载
});// 开启

路由加载和导航

      <el-container>
        <!-- 左侧导航 -->
        <el-aside>
          <el-menu
            default-active="1"
            class="el-menu-vertical-demo"
            background-color="#545c64"
            text-color="#fff"
            :router="true"
          >
            <el-menu-item index="/main/webui">
              <i class="el-icon-document"></i>
              <span slot="title">深信服SD-WAN安全智能路由器</span>
            </el-menu-item>
            <el-menu-item index="/main/easydeploy">
              <i class="el-icon-setting"></i>
              <span slot="title">云端易部署</span>
            </el-menu-item>
            <el-menu-item index="/main/vue">
              <i class="el-icon-setting"></i>
              <span slot="title">Vue2测试页面</span>
            </el-menu-item>
          </el-menu>
        </el-aside>
        <el-container>
          <!-- 内容 -->
          <el-main>
            <router-view></router-view>
            <div id="webui"></div>
            <div id="easy"></div>
            <div id="vue"></div>
          </el-main>
        </el-container>
      </el-container>

路由

import Main from '../views/Main';

Vue.use(VueRouter)

const routes = [
    {
        path: '/main/*',
        name: 'Main',
        component: Main,
    }

]

const router = new VueRouter({
    mode: 'history',
    // base: process.env.BASE_URL,
    base: '',
    routes
})

export default router

主业务应用(vue2, lerna)

lerna.json                    lerna配置

{
“packages”: [“packages/"],
“npmClient”: “yarn”,
“useWorkspaces”: true,
“version”: “0.0.1”,
“ignoreChanges”: ["**/
.md”],
“bootstrap”: {
“npmClientArgs”: ["–no-package-lock", “–force-local”]
}
}


package.json		

```typescript
{
    "name": "SDWR",
    "private": true,
    "scripts": {
        "add-dep": "lerna add",
        "add-dep:webui": "lerna add --scope=@sdwr/webui",
        "init:dep": "yarn install && lerna bootstrap && yarn build && yarn dev:webui",
        "clean:dep": "yarn clean:sub-dep && rm -rf node_modules",
        "clean:sub-dep": "lerna clean -y",
        "reinstall:dep": "yarn clean:dep && yarn init:dep",
        "dev": "cross-env JOINT_DEBUGGING=1 yarn dev:webui",
        "dev:webui": "yarn kill-ports 997 && yarn cp-dep:webui && yarn run-script dev --scope=@sdwr/webui",
        "build": "yarn build:util && yarn build:common && yarn build:components && yarn build:idb && yarn build:webui",
        "build:components": "yarn cp-dep:components && yarn run-script build --scope=@sdwr/webui-component",
        "build:webui": "yarn cp-dep:webui && yarn run-script build --scope=@sdwr/webui",
        "build:util": "yarn cp-dep:components && yarn run-script build --scope=@sdwr/webui-util",
        "build:common": "yarn cp-dep:common && yarn run-script build --scope=@sdwr/webui-common",
        "build:idb": "yarn run-script build --scope=@sdwr/idb",
        "cp-dep": "yarn cp-dep:webui",
        "cp-dep:webui": "cp -rn node_modules/less-loader/ packages/webui_base/node_modules/",
        "cp-dep:components": "cp -rn node_modules/less-loader/ packages/webui_component/node_modules/",
        "cp-dep:util": "cp -rn node_modules/less-loader/ packages/webui_util/node_modules/",
        "cp-dep:common": "cp -rn node_modules/less-loader/ packages/webui_common/node_modules/",
        "run-script": "lerna run --stream --no-prefix",
        "run-script:serial": "yarn run-script --concurrency 1",
        "run-script:serial-only-change": "yarn run-script:serial --since HEAD --exclude-dependents",
        "kill-ports": "kill-port --port",
        "test": "jest",
        "eslint": "yarn run-script eslint",
        "eslint-fix": "yarn run-script eslint-fix",
        "stylelint": "yarn run-script stylelint",
        "stylelint-fix": "yarn run-script stylelint-fix",
        "pre-commit": "npx ls-lint && yarn run-script:serial-only-change pre-commit"
    },
    "dependencies": {
        "babel-runtime": "^6.26.0",
        "@sxf/i18n": "1.0.12",
        "@sxf/intl-polyfill": "~1.2.0",
        "@sxf/sf-theme": "~0.1.17",
        "@sxf/vue-intl": "~1.9.1",
        "axios": "~0.20.0",
        "js-sha256": "~0.9.0",
        "jsrsasign": "~10.3.0",
        "lodash-es": "4.17.11",
        "uuid": "~8.3.2",
        "vue": "2.6.12",
        "vue-class-component": "~7.1.0",
        "vue-property-decorator": "~9.0.0",
        "@vue/babel-helper-vue-jsx-merge-props": "~1.2.1",
        "@vue/babel-preset-jsx": "~1.2.4",
        "core-js": "~3.12.0",
        "@sxf/sf-vue-component": "~2.20.12",
        "@types/clone": "^0.1.30",
        "clone": "^2.1.2",
        "copy": "^0.3.2",
        "path-browserify": "^1.0.1",
        "shelljs": "^0.8.3"
    },
    "devDependencies": {
        "@babel/core": "~7.4.5",
        "@babel/plugin-proposal-nullish-coalescing-operator": "~7.14.5",
        "@babel/plugin-proposal-optional-chaining": "~7.14.5",
        "@babel/preset-env": "~7.12.7",
        "@babel/preset-typescript": "~7.12.7",
        "@babel/plugin-syntax-jsx": "^7.0.0",
        "babel-eslint": "^10.0.1",
        "babel-helper-vue-jsx-merge-props": "^2.0.3",
        "babel-plugin-syntax-jsx": "^7.0.0-beta.3",
        "@commitlint/cli": "~12.1.4",
        "@commitlint/config-conventional": "~12.1.4",
        "@jest/types": "~27.0.6",
        "@ls-lint/ls-lint": "~1.9.0",
        "@sxf/eslint-config-idux": "~0.0.12",
        "@sxf/eslint-plugin-i18n": "~0.0.5",
        "@sxf/eslint-plugin-i18n-next": "~0.3.1",
        "@types/jest": "~26.0.24",
        "@types/jsrsasign": "^8.0.1",
        "@types/node": "~16.3.2",
        "@types/uuid": "^8.3.1",
        "@typescript-eslint/eslint-plugin": "~4.28.3",
        "@typescript-eslint/parser": "~4.28.3",
        "@uedc/api-utils": "~0.14.0",
 

packages
webui_base

{
    "name": "@sdwr/webui",
    "private": true,
    "version": "1.0.0",
    "description": "",
    "main": "index.js",
    "repository": {
        "type": "git",
        "url": "[email protected]:13594/learn.git"
    },
    "scripts": {
        "build": "npm run update:url-map && npm run eslint && sfx2 build",
        "dev": "sfx2 dev",
        "test": "node --max-old-space-size=8192 ./node_modules/jest/bin/jest --maxWorkers=50% --all --passWithNoTests --detectOpenHandles",
        "test:change": "node --max-old-space-size=8192 ./node_modules/jest/bin/jest --maxWorkers=50% -o --passWithNoTests --detectOpenHandles",
        "test:ci": "node --max-old-space-size=8192 ./node_modules/jest/bin/jest --runInBand --all --passWithNoTests --silent --ci --detectOpenHandles",
        "test:dev": "node --max-old-space-size=8192 ./node_modules/jest/bin/jest --maxWorkers=25% --passWithNoTests --detectOpenHandles --watch",
        "eslint": "eslint --ext .vue,.js,.ts src",
        "fix": "eslint --ext .vue,.js,.ts src --fix",
        "count_component_usage_frequency": "node ./build/scanning_component_usage_frequency.js sf-,sdwr- ../dist/static/js ../usage_frequency.json",
        "update:url-map": "node ./build/auto_create_url_map.js"
    },
    "devDependencies": {
        "@babel/helper-module-imports": "~7.0.0",
        "@babel/plugin-syntax-dynamic-import": "~7.2.0",
        "@babel/plugin-syntax-jsx": "~7.0.0",
        "@babel/plugin-transform-runtime": "~7.4.4",
        "@babel/runtime": "~7.4.5",
        "@babel/runtime-corejs2": "~7.4.5",
        "@sxf/tpl-loader": "~1.1.1",
        "@types/echarts": "~4.6.5",
        "@types/jest": "~26.0.23",
        "@types/store": "~2.0.2",
        "autoprefixer": "~9.6.0",
        "babel-plugin-transform-es2015-modules-commonjs": "~6.26.2",
        "babel-plugin-transform-strict-mode": "6.24.1",
        "babel-polyfill": "~6.26.0",
        "babel-preset-es2015": "6.24.1",
        "babel-preset-stage-0": "6.24.1",
        "css-loader": "~4.2.2",
        "fake-indexeddb": "~3.1.2",
        "file-loader": "~6.1.0",
        "jest-canvas-mock": "~2.3.1",
        "jsdom": "~16.4.0",
        "jsdom-global": "~3.0.2",
        "parse-comments": "~1.0.0",
        "prettier": "~2.3.1",
        "style-loader": "~1.2.1",
        "sugarss": "~2.0.0",
        "url-loader": "~4.1.0",
        "vue-hot-reload-api": "2.3.4",
        "vue-template-compiler": "2.6.12"
    },
    "dependencies": {
        "@babel/plugin-proposal-class-properties": "~7.5.5",
        "@babel/plugin-proposal-decorators": "~7.4.4",
        "@babel/plugin-proposal-object-rest-spread": "~7.5.4",
        "@sdwr/webui-common": "~0.0.1",
        "@sdwr/webui-component": "~0.0.1",
        "@sdwr/webui-util": "~0.0.1",
        "@sxf/pineapple": "~2.7.10",
        "@uedc/login": "1.0.6",
        "axios": "~0.20.0",
        "echarts": "~4.6.0",
        "highcharts": "5.0.6",
        "idb": "~6.1.2",
        "store": "~2.0.12",
        "ts-loader": "~8.0.3",
        "typescript": "~4.1.5",
        "v-viewer": "~1.4.0",
        "vue-loader": "~15.9.0",
        "vue-router": "~3.0.6",
        "vuex": "~3.6.2",
        "webpack": "~4.41.5",
        "wind-dom": "0.0.3"
    },
    "keywords": [],
    "author": "",
    "license": "ISC",
    "husky": {
        "hooks": {
            "pre-commit": "ls-lint && lint-staged && npm run eslint && yarn test:change",
            "commit-msg": "npx --no-install commitlint --edit \"$1\""
        }
    },
    "lint-staged": {
        "*.{json}": [
            "prettier --write"
        ],
        "*.{js,ts,vue}": [
            "eslint --fix"
        ]
    },
    "vetur": {
        "tags": "./build/global_components/tags.json",
        "attributes": "./build/global_components/attributes.json"
    }
}

业务中应用
import { openDB } from ‘…/…/…/webui_idb/dist/index.js’;

webui_common
	公共的过滤函数,全局变量等
webui_component
	webui的自身组件库
	拥有install方法。Vue.component 全局注册
webui_idb
	支持ie11 的idb库
webui_util
	util函数

# 副业务应用(vue3)
支持vue3 需要一个插件vite_plugin_qiankun

```typescript
'use strict';

var cheerio = require('cheerio');

function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }

var cheerio__default = /*#__PURE__*/_interopDefaultLegacy(cheerio);

var createQiankunHelper = function (qiankunName) { return "\n  const createDeffer = (hookName) => {\n    const d = new Promise((resolve, reject) => {\n      window.proxy && (window.proxy[`vite${hookName}`] = resolve)\n    })\n    return props => d.then(fn => fn(props));\n  }\n  const bootstrap = createDeffer('bootstrap');\n  const mount = createDeffer('mount');\n  const unmount = createDeffer('unmount');\n\n  ;(global => {\n    global.qiankunName = '" + qiankunName + "';\n    global['" + qiankunName + "'] = {\n      bootstrap,\n      mount,\n      unmount,\n    };\n  })(window);\n"; };
var createImportFinallyResolve = function (qiankunName) {
    return "\n    const qiankunLifeCycle = window.moudleQiankunAppLifeCycles && window.moudleQiankunAppLifeCycles['" + qiankunName + "'];\n    if (qiankunLifeCycle) {\n      window.proxy.vitemount((props) => qiankunLifeCycle.mount(props));\n      window.proxy.viteunmount((props) => qiankunLifeCycle.unmount(props));\n      window.proxy.vitebootstrap(() => qiankunLifeCycle.bootstrap());\n    }\n  ";
};
var htmlPlugin = function (qiankunName) {
    var isProduction;
    return {
        // enforce: 'post',
        name: 'qiankun-html-transform',
        configResolved: function (config) {
            isProduction = config.command === 'build' || config.isProduction;
            "http://127.0.0.1:" + (config.server.port || 3000) + config.base;
        },
        transformIndexHtml: function (html) {
            var $ = cheerio__default['default'].load(html);
            var moduleTags = $('script[type=module]');
            if (!moduleTags || !moduleTags.length) {
                return;
            }
            moduleTags.each(function (i, moduleTag) {
                var script$ = $(moduleTag);
                var moduleSrc = script$.attr('src');
                if (isProduction) {
                    script$.removeAttr('src');
                    script$.removeAttr('type');
                    script$.html("import('" + moduleSrc + "').finally(() => {\n            " + createImportFinallyResolve(qiankunName) + "\n          })");
                    return;
                }
            });
            $('body').append("");
            var output = $.html();
            return output;
        },
    };
};

module.exports = htmlPlugin;

即可支持
ViteQiankunPlugin(‘easydeployApp’)

你可能感兴趣的:(前端框架,node.js,css,git)