手摸手教你用qiankun开发微前端项目(三)

444 阅读3分钟

  承接上一篇,下面我们来介绍如何配置vue子系统,在qiankun官网中只是讲解了vue2作为子系统的配置修改,所以我们也是以vue2为例来演示。
3.vue子系统:

  如果还没有安装vue的脚手架命令可以安装:

sudo npm install -g @vue/cli

  之后安装应用程序,选择vue2来安装,命令如下:

vue create vue-app

  在初始化完成后,我们开始修改vue的项目文件:

  (1)首先在 src 目录新增 public-path.js:

if (window.__POWERED_BY_QIANKUN__) {
  __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}

  (2)然后,修改入口文件 main.js,为了避免根 id #app 与其他的 DOM 冲突,需要限制查找范围为props中的container。在配置VueRouter时,如果是在qiankun环境下,base就是/vue,即vue子系统的路由。如果不是在qiankun环境下,直接执行render函数。后续导出qiankun框架规定的三个生命周期钩子函数:

import './public-path'
import Vue from 'vue'
import VueRouter from 'vue-router';
import App from './App.vue';

Vue.config.productionTip = false

let router = null;
let instance = null;

function render(props = {}) {
  const { container } = props;
  router = new VueRouter({
    base: window.__POWERED_BY_QIANKUN__ ? '/vue' : '/',
    mode: 'history',
  });

  instance = new Vue({
    router,
    render: h => h(App),
  }).$mount(container ? container.querySelector('#app') : '#app');
}

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(props);
}

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

  (3)最后打包配置修改(vue.config.js),配合基座启动端口设置为8080,允许跨域,并且需要设置htmlWebpackPlugin.options.title属性:

const path = require('path');
const { name } = require('./package');

function resolve(dir) {
  return path.join(__dirname, dir);
}

const port = 8080; // dev port

module.exports = {
  /**
   * You will need to set publicPath if you plan to deploy your site under a sub path,
   * for example GitHub Pages. If you plan to deploy your site to https://foo.github.io/bar/,
   * then publicPath should be set to "/bar/".
   * In most cases please use '/' !!!
   * Detail: https://cli.vuejs.org/config/#publicpath
   */
  outputDir: 'dist',
  assetsDir: 'static',
  filenameHashing: true,
  devServer: {
    hot: true,
    disableHostCheck: true,
    port,
    overlay: {
      warnings: false,
      errors: true,
    },
    headers: {
      'Access-Control-Allow-Origin': '*',
    },
  },
  // 自定义webpack配置
  configureWebpack: {
    resolve: {
      alias: {
        '@': resolve('src'),
      },
    },
    output: {
      // 把子应用打包成 umd 库格式
      library: `${name}-[name]`,
      libraryTarget: 'umd',
      jsonpFunction: `webpackJsonp_${name}`,
    }
  },
  chainWebpack: config => {
    config
        .plugin('html')
        .tap(args => {
            args[0].title = "My Vue App";
            return args;
        })
    }
};

  启动之后,即可通过基座系统切换到vue子项目中。

  微前端项目部署:

  以上讲完了微前端项目的调试环境,那么我们如何来进行线上部署呢?本次讲的部署方式基座系统和子系统都是属于单独的spa服务,都放在一个服务器中,只是把子系统打完包的静态文件放入基座系统的二级目录中即可。下面来讲解详细步骤:

  1.我们在部署的时候,希望把子系统的打包文件内容放入基座系统的child/reactapp/和child/vue/文件夹下,所以需要对基座系统注册子应用的配置文件做如下修改:

{
  name: 'reactapp',
  entry: '/child/reactapp/',
  // entry: 'http://localhost:3000',
  container: '#subapp-viewport',
  loader,
  activeRule: '/reactapp',
},
{
  name: 'vue',
  entry: '/child/vue/',
  // entry: 'http://localhost:8080',
  container: '#subapp-viewport',
  loader,
  activeRule: '/vue',
}

  2.对于react子应用,我们需要在打包时,需要publicPath指向的同样是/child/reactapp/,所以需要在package.json中直接加上配置项:

{
 "homepage": "/child/reactapp/"
}

  这样在打包之后:

npm run build

  所有对子应用的请求都会到/child/reactapp/这个目录下。

  3.对于vue子系统,同样需要修改构建时的publicPath指向/child/vue/,所以需要在vue.config.js中进行如下修改:

module.exports = {
  /**
   * You will need to set publicPath if you plan to deploy your site under a sub path,
   * for example GitHub Pages. If you plan to deploy your site to https://foo.github.io/bar/,
   * then publicPath should be set to "/bar/".
   * In most cases please use '/' !!!
   * Detail: https://cli.vuejs.org/config/#publicpath
   */
  publicPath: '/child/vue/'
}

  同样通过自身带的打包命令进行打包:

npm run build

  之后把打包文件的内容,转移到基座系统的/child/vue二级目录下面。

  这样部署就完成了,在联调环境中,主要注意配置跨域的问题,在部署的时候主要注意publicPath的配置问题。后续如果在开发中,有其他问题,再来分享。