qiankun本地搭建

158 阅读1分钟

目标

乾坤的本地搭建

相关介绍

  1. 项目没有使用vue-cli工具,如果使用工具需要做一些调整
  2. 主项目使用vue2, 子项目一个是vue2,一个vue3

本地搭建

  1. 主项目(vue2)引入qiankun
// main.js
import App from '@/view/App'
import Vue from 'vue'
import VueRouter from 'vue-router'
import router from '@/router/index'
import 'element-ui/lib/theme-chalk/index.css'
import ElementUI from 'element-ui'
// ---  qiankun start  -------
import { registerMicroApps, start } from 'qiankun'
// 根据环境生成入口
const createEntry = (port = 33901, ip = '0.0.0.0') => {
    return process.env.NODE_ENV === 'development' ? `http://localhost:${port}` : `http://${ip}:${port}`
}
registerMicroApps([
    {
        name: 'comp1',
        entry: createEntry(33901),
        activeRule: '/comp1',
        container: '#sub-container'
    },
    {
        name: 'comp2',
        entry: createEntry(33902),
        activeRule: '/comp2',
        container: '#sub-container'
    }
])
start()
// --- qiankun end -----
  1. 子项目根目录下添加publish-path.js文件
if (window.__POWERED_BY_QIANKUN__) {
  __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
  1. 子项目设置跨域,并向主应用暴露项目信息
// webpack.config.js
const packageName = require('../package.json').name;
module.exports = {
    output: {
        filename: '[name].js',
        library: `${packageName}-[name]`,
        libraryTarget: 'umd',
        publicPath: '/'
    },
    devServer: {
        headers: {
            'Access-Control-Allow-Origin': '*'
        }
    }
}
  1. 子项目入口文件,顶部引入publish-path.js,添加render函数,暴露qiankun需要的生命周期钩子函数,vue2和vue3有一些差别
  • vue2-子项目入口文件
// main.js
import '../public-path'
import App from '@/view/App'
import Vue from 'vue'
import VueRouter from 'vue-router'
import routes from '@/router'
import 'element-ui/lib/theme-chalk/index.css'
import ElementUI from 'element-ui'

Vue.use(VueRouter)
Vue.use(ElementUI)

let router = null;
let instance = null;

function render({ container } = {}) {
  router = new VueRouter({
    // 这里做了区分,当子项目单独启动时不需要前缀
    base: window.__POWERED_BY_QIANKUN__ ? '/comp1' : '/',
    mode: 'history',
    routes,
  });
  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 app bootstraped');
}

export async function mount(props) {
  console.log('props from main framework', props);
  render(props);
}

export async function unmount() {
  instance.$destroy();
  instance.$el.innerHTML = "";
  instance = null;
  router = null;
}
  • vue3子项目入口文件
// main.js
import '../public-path'
import { createApp } from 'vue'
import App from '@/App.vue'
import routes from '@/router'
import store from '@/store'
import 'element-plus/dist/index.css'
import ElementPlus from 'element-plus'
import { createRouter, createWebHistory } from 'vue-router';

let router = null
let instance = null 
const baseRoute = window.__POWERED_BY_QIANKUN__ ? '/comp2' : '/'

const render = ({ container } = {}) => {
    router = createRouter({
        history: createWebHistory(baseRoute),
        routes
    })
    instance = createApp(App)
    instance.use(router).use(store).use(ElementPlus).mount(container ? container.querySelector('#app') : '#app')
}

if (!window.__POWERED_BY_QIANKUN__) {
    render()
}

export async function bootstrap () {
    console.log( 'vue3 app bootstraped')
}

export async function mount (props) {
    console.log('mount: props', props)
    render(props)
}

export async function unmount () {
    instance.unmount()
    instance._container.innerHTML = ''
    instance = null
    router = null
}
  1. 启动主项目和子项目