qiankun icon indicating copy to clipboard operation
qiankun copied to clipboard

vue3项目,webpackage启用externals,loadMicroApp加载子应用时主应用根节点的内容会被子应用的App.vue替换

Open zwj9297 opened this issue 2 years ago • 2 comments

现象:

vue3项目,webpackage启用externals,loadMicroApp加载子应用时主应用根节点的内容会被子应用的App.vue替换

  • 主应用,子应用的容器id不一致
  • 替换的时机发生在子应用bootstrap之前

https://user-images.githubusercontent.com/26342286/139656491-935ca4af-e902-4300-b2ab-d4f975257f37.mp4

  1. 创建2个空白的vue3应用,分别为主应用和子应用
  2. 主应用项目改造 · 新建vue.config.js
module.exports = {
  configureWebpack: {
    externals: {
      vue: 'Vue'
    }
  }
}
  • 修改 public/index.html 2.1 引用https://unpkg.com/vue@next 2.2 修改根节点id为"mainApp"
<!DOCTYPE html>
<html lang="">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <title><%= htmlWebpackPlugin.options.title %></title>
    <script src="https://unpkg.com/vue@next"></script>
  </head>
  <body>
    <noscript>
      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <div id="mainApp"></div>
    <!-- built files will be auto injected -->
  </body>
</html>
  • 修改 src/main.ts
import { createApp } from 'vue'
import App from './App.vue'

createApp(App).mount('#mainApp')
  • 修改 src/App.vue
<template>
  <div>
    <h1>This is Main App!</h1>
    <div id="container">
      <button @click="load">load micro app</button>
    </div>
  </div>
</template>

<script>
import { loadMicroApp } from 'qiankun'

export default {
  methods: {
    load(e) {
      e.target.innerHTML = 'loading...'
      loadMicroApp({
        name: 'microApp',
        entry: 'http://localhost:7777/',
        container: '#container'
      })
    }
  }
}
</script>
  1. 子应用项目改造
  • 新建vue.config.js
const port = 7777
const name = 'micro'

module.exports = {
  configureWebpack: {
    externals: {
      vue: 'Vue'
    },
    devServer: {
      port,
      // 跨域
      headers: {
        'Access-Control-Allow-Origin': '*',
      }
    },
    output: {
      // 把子应用打包成 umd 库格式(必须)
      library: `${name}-[name]`,
      libraryTarget: 'umd',
      jsonpFunction: `webpackJsonp_${name}`,
    }
  }
}
  • 修改 public/index.html 3.1 子应用根节点id改为"microApp"
<!DOCTYPE html>
<html lang="">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <title><%= htmlWebpackPlugin.options.title %></title>
  </head>
  <body>
    <noscript>
      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <div id="microApp"></div>
    <!-- built files will be auto injected -->
  </body>
</html>
  • 修改 src/mian.ts
import { createApp } from 'vue'
import App from './App.vue'

let instance: any = null // 根组件实例

async function render(props: any) {
  const { container } = props
  instance = createApp(App)
  instance.mount(container ? container.querySelector('#microApp') : '#microApp')
}

// webpack打包公共文件路径
if (window.__POWERED_BY_QIANKUN__) {
  __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__
}

// 生命周期
export async function bootstrap() {
  console.log('[vue] vue app bootstraped')
}
export async function mount(props: any) {
  console.log('mounted')
  console.log('[vue] props from main framework', props)
  render(props)
}
export async function unmount() {
  console.log('unmounted')
  instance.unmount()
}
  • 修改 src/App.vue
<template>
  <div>this is micro app!</div>
</template>
  1. 启动两个项目,现象如上面视频所示

##项目依赖 vue: ^3.0.0 qiankun: 2.4.10

zwj9297 avatar Nov 01 '21 10:11 zwj9297

备注一点:在禁用了externals之后是正常的

zwj9297 avatar Nov 01 '21 11:11 zwj9297

我这边碰到同样的问题。我的场景是因为vue-loader开发环境热更新是通过文件相对路径生成hash值,嵌套子应用的时候hash值相同所以导致主应用被覆盖,设置webpack的mode或者NODE_ENV为production都可以解决

Liaozzzzzz avatar Aug 25 '22 09:08 Liaozzzzzz