微服务qinakun.js搭建项目-进阶版(简化)(vue2+webpack3)

392 阅读2分钟

【前言】:通过之前的qiankun.js 微前端拆分vue+webpack项目-基础版,总结到了一些经验,发现如果拆分项目的话,不是所有的子应用都需要新建,如果已经写了部分子应用,可以直接通过配置部分文件,实现微服务的搭建。且看着👇👇👇

1. 搭建主应用

可参考前言中提到的文章,进行新建搭建,也可以在已有项目的基础上改造。

1.1 安装qiankun.js

在主应用的顶层打开终端,运行下面命令。

$ npm i qiankun -S

可在package.json中看到

'dependencies':{
    'qiankun':'^2.8.1'
}

1.2 微服务配置

1.2.1 新建 src/micros/apps.js文件

// apps.js
/* 子应用路由规格 */

// 子应用列表
const apps = [
    {
        name:'web1',
        entry:'//localhost:8081/web1',
        container:'#container',
        acticeRule:'/web1'
    },
    
    ...
];

export default apps;

1.2.2 新建 src/micros/index.js文件

可以设置默认子应用。

// index.js - qiankun
import { registerMicroApps, addGlobalUncaughtErrorHandler, start } from "qiankun";
import apps from './apps.js';

/**
 * @description: 注册微应用
 * 第一个参数 - 微应用的注册信息
 * 第二个参数 - 全局生命周期钩子
 */
registerMicroApps(apps,{
    beforeLoad: [
        app => {
            console.log('[LifeCycle] before load %c%s', 'color: green;', app.name);
        },
    ],
    beforeMount: [
        app => {
            console.log('[LifeCycle] before mount %c%s', 'color: green;', app.name);
        },
    ],
    afterUnmount: [
        app => {
            console.log('[LifeCycle] after unmount %c%s', 'color: green;', app.name);
            location.reload(true)
        },
    ],
})

// 设置默认子应用
setDefaultMountApp('/web1');

addGlobalUncaughtErrorHandler((event) => {
    const { msg } = event;
    if (msg && msg.includes('died in status LOADING_SOURCE_CODE')) {
        console.log('加载失败');
    }
});

/**
 * @description: 导出启动函数
 */
export default start;

1.3 配置主应用的main.js

// main.js

...

//引入qiankun注册文件
import startQiankun from "./micros";
//启动微应用
startQiankun();

1.4 配置webpack

// webpack.base.conf.js
const { name } = require('../package.json');

module.exports = {
    ...
    
    output:{
        ...
        
         // 需要以包的形式打包, 挂载window上
        library: `${name}-[name]`,
        libraryTarget: 'umd',
        jsonpFunction: `webpackJsonp_${name}` // webpack5废弃jsonpFunction
        // chunkLoadingGlobal: `webpackJsonp_${name}`,  
    }
}
// webpack.dev.conf.js

...

devServer: {
    // 配置跨域请求头,解决开发环境的跨域问题
    headers: {
        'Access-Control-Allow-Origin': '*',
    },
    
    ...
}
// webpack.prod.conf.js

...

new HtmlWebpackPlugin({
    
    ...
    
    chunks:['manifest','vendor','app']
})

// 对应的Plugin也按照上面的chunks挪动顺序
// config/index.js

module.exports = {

    ...
    
    // 配置代理
    proxyTable:{
        ‘/’:{
            target:'后台访问地址',
            changeOrigin: true,
            pathRewtite: {
              '^/': '/'
            },
            // 运行时打印请求记录
            logLevel: 'debug'
        }
    }
    
    dev:{
        // 配置访问端口 - 主应用的端口
        port:'8080',
        
        ...
    }
}

image.png

2. 配置子应用

这里我引入了以前开发的一个项目,完全独立的。 对这个倒霉的项目进行改造,作为一个子应用,要有该有的自觉🥰

2.1 修改子应用的main.js

// main.js

// new Vue({
//   el: '#app2',
//   router,
//   components: { App },
//   template: '<App/>'
// })
...

// 新增以下代码

let instance = null;
// 重新包装render方法
function render() {
  instance = new Vue({
    router,
    render: h => h(App)
    
    // 挂在的id为index.html中的id
  }).$mount('#container');
}



// 独立运行时直接渲染
if (!window.__POWERED_BY_QIANKUN__) {
  render();
}

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

export async function mount(props) {
  console.log('[vue] props from main framework', props);
  render(); // 作为子应用渲染时将主应用传入的配置作为参数去渲染
}

export async function unmount() {
  instance.$destroy();
  instance.$el.innerHTML = '';
  instance = null;
}

2.2 修改index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <link rel="shortcut icon" href="static/images/favicon.png" type="image/x-icon"/>
    <title>fs-museum-portal-site</title>
  </head>
  <body>
    <div id="container"></div>
    <!-- built files will be auto injected -->
  </body>
</html>

2.3 修改App.vue

App.vue可以不修改,但是为了方便我们看到子应用的dom元素是否加载出来,大胆的修改了App.vue

<template>
    <div id="container_1">
        <router-view />
    </div>
</template>

image.png

【👍注意】:在这里要区分下几个id:

  • index.html中的divid:当前应用的main.js中挂在的位置; image.png
  • App.vue中的divid:当前子应用中页面的外层dom节点 -- 结果如2.3中图所示;

2.4 修改webpack

子应用的webpack配置和主应用一样,不过子应用的代理不需要自己配置,主应用中配置后即可。配置此处见1.4

2.5 修改router/index.js

目前需要将路由中异步引入改为同步引入,不然会报错,具体问题见qiankun基础的Q5。 待后续精进后,此处再做修改补充。

3. 静态资源引入

可在static文件夹中放置静态资源,也可以用绝对路径引入静态资源。

  1. iconfont的使用
  2. 子理由的使用

4. 配置代理+axios请求

和正常的vue项目一样配置即可。

代理这里需要补充的话,可留言。

这里可以说明一点,代理可以只在主应用中配置,子应用中也可以调用。

【总结】:从上述过程看到,这里可以完整访问项目,但是也是一些基础容易懂的东西,后续遇到问题我会继续增加的。