当前位置: 首页 > article >正文

微前端Webpack集成Vite子应用避坑指南

目录

1、Vite和qiankun框架的兼容性问题

2、vite-plugin-qiankun插件的使用

简介

快速开始

3、子应用集成的页面不断刷新,不显示页面的问题

4、Uncaught (in promise) ReferenceError: global is not defined

5、子应用跨域问题

6、本地连调时,静态资源404无法获取的问题

7、父子微前端应用接口代理冲突问题

8、globalState问题

9、React多自定义render页,在qiankun框架内找不页面的问题。


1、Vite和qiankun框架的兼容性问题

2024/12/30,目前qiankun框架官方还未完全适配vite应用。通过qiankun集成vite子应用还需使用对应的插件,若直接按qiankun官网来进行配置,很可能会报以下错误:

[import-html-entry]: error occurs while executing normal script ...

这是因为vite底层是通过script标签的module形式来进行加载的,而qiankun框架默认不支持这种方式。解决方案见2。

2、vite-plugin-qiankun插件的使用

这个插件可以解决vite使用qiankun集成的问题,详见:

https://www.npmjs.com/package/vite-plugin-qiankun

注意事项:

(1)这个插件虽然可以解决大体上的问题,但仍然遗留了隐患,使用该插件会破坏qiankun原有的沙箱环境,可能导致一些页面参数的冲突。

(2)本地连调时记得开启useDevMode = true ,否则可能出现反复刷新页面不显示的问题。

(3)qiankunWindow.__POWERED_BY_QIANKUN__  可用于判断是否为qiankun子应用时的环境,设置basename时很有用:

//window.INJECTED_ROUTER_BASE_BY_QIANKUN 这个全局参数是父应用自定义的子应用访问前缀,在父应用中声明即可。

<BrowserRouter

          basename={

            qiankunWindow.__POWERED_BY_QIANKUN__

              ? // qiankun 子应用时

              `${window.INJECTED_ROUTER_BASE_BY_QIANKUN || ''}/`

              : // 非 qiankun 子应用时

              '/'

          }

        >
简介

vite-plugin-qiankun: 帮助应用快速接入乾坤的vite插件

  • 保留vite构建es模块的优势

  • 一键配置,不影响已有的vite配置

  • 支持vite开发环境

快速开始

1、在 vite.config.ts 中安装插件

// vite.config.ts

import qiankun from 'vite-plugin-qiankun';

export default {
 // 这里的 'myMicroAppName' 是子应用名,主应用注册时AppName需保持一致
 plugins: [qiankun('myMicroAppName')],
 // 生产环境需要指定运行域名作为base
 base: 'http://xxx.com/'
}

2、在入口文件里面写入乾坤的生命周期配置

// main.ts
import { renderWithQiankun, qiankunWindow } from 'vite-plugin-qiankun/dist/helper';

// some code
renderWithQiankun({
 mount(props) {
   console.log('mount');
   render(props);
 },
 bootstrap() {
   console.log('bootstrap');
 },
 unmount(props: any) {
   console.log('unmount');
   const { container } = props;
   const mountRoot = container?.querySelector('#root');
   ReactDOM.unmountComponentAtNode(
     mountRoot || document.querySelector('#root'),
   );
 },
});

if (!qiankunWindow.__POWERED_BY_QIANKUN__) {
 render({});
}

3、dev下作为子应用调试

因为开发环境作为子应用时与热更新插件(可能与其他修改html的插件也会存在冲突)有冲突,所以需要额外的调试配置

// useDevMode 开启时与热更新插件冲突,使用变量切换
const useDevMode = true

const baseConfig: UserConfig = {
 plugins: [
   ...(
     useDevMode ? [] : [
       reactRefresh()
     ]
   ),
   qiankun('viteapp', {
     useDevMode
   })
 ],
}

上面例子中 useDevMode = true 则不使用热更新插件,useDevMode = false 则能使用热更新,但无法作为子应用加载。

4、其它使用注意点 qiankunWindow

因为es模块加载与qiankun的实现方式有些冲突,所以使用本插件实现的qiankun微应用里面没有运行在js沙盒中。所以在不可避免需要设置window上的属性时,尽量显示的操作js沙盒,否则可能会对其它子应用产生副作用。qiankun沙盒使用方式

import { qiankunWindow } from 'vite-plugin-qiankun/dist/helper';

qiankunWindow.customxxx = 'ssss'

if (qiankunWindow.__POWERED_BY_QIANKUN__) {
 console.log('我正在作为子应用运行')
}

3、子应用集成的页面不断刷新,不显示页面的问题

(1)插件未开启useDevMode = true;

(2)entry对应子应用服务器的路径不对,如:

{

name: 'child-micro-app',

entry:

  process.env.NODE_ENV === 'development' ? '//localhost:4000' : '/page',  // 当页面处于生产环境时,同域名下,若没有 /page的页面对应该子应用的服务器页面,则可能会出现该异常。

},

4、Uncaught (in promise) ReferenceError: global is not defined

这个问题一般出现这vite项目环境中,一般中入口文件中配置如下,即可解决vite项目中global的问题,但集成到父应用时也可能报该异常,此时,需要在父项目的入口文件中也配置该global对象:

(window as any).global = window;

5、子应用跨域问题

(1)当entry为另一个域名的微前端应用时,需要考虑跨域问题,如:

entry: "https://other.example.com"  // 和当前域名不同时。

可以在Nginx下配置以下参数:

add_header 'Access-Control-Allow-Origin' 'https://允许跨域的域名.com';

(2)子应用的有些接口跨域,可能需要在父应用中配置代理来解决。

6、本地连调时,静态资源404无法获取的问题

vite子应用的资源,本地直接子父应用中访问可能出现资源根域名仍然是父应用根域名的情况。

解决方案有两个:

(1)建立一个公共的资源地址,让父子应用都从里面获取静态资源;

(2)vite本地连调时,配置origin:

export default defineConfig(({ mode }) => ({

server: {

  //用于定义开发调试阶段生成资源的 origin。

  origin: 'http://localhost:4000',  // 子应用的ip和端口

......

线上时,配置base为子应用当前域名:

// qiankun生产环境需要指定运行域名作为base

// base: 'https://child.domain.com',

7、父子微前端应用接口代理冲突问题

问题描述:父应用localhost:8070,子应用localhost:4000,它们都使用自己独立的/api代理,当子应用集成到父应用中时,子应用发出的/api即可被父应用的/api代理提前拦截代理掉,导致子应用代理的路径不对的问题。

解决方案:

(1)子应用配置baseUrl:

import { qiankunWindow } from 'vite-plugin-qiankun/dist/helper';

// 被qiankun集成作为子应用时baseUrl是/childApi,单独访问时是/api

const baseUrl = qiankunWindow.__POWERED_BY_QIANKUN__ ? "/childApi/api" : '/api';

(2)父应用配置对应的代理,如:

"/childApi/": {  // 子应用对应/api代理的写法

target: "子应用/api代理的target",

changeOrigin: true,

pathRewrite: {'^/childApi': ''},

}

(3)也可将baseUrl写死为绝对路径,如:http://localhost:8000/api,但这样会造成诸多不便,不推荐。

注意,有时配置可能会少写/api这样的访问路径,导致接口报405或404,检查接口是否在正确的路径上。

8、globalState问题

有时,子应用可能需要一些全局参数,若子应用调用了,但没有,可能会报错。以下是gloablState的案例代码:

(1)父应用中设置,当然,你也可以自定义优化一下

import {registerMicroApps, start, initGlobalState} from 'qiankun';

// 全局状态管理

const state = {count: 1};

const action = initGlobalState(state);

action.onGlobalStateChange((value, prev) => {

 console.log('main app change', value, prev);

});

action.setGlobalState(state);

(2)子应用中获取

​
let app: any;

if (!qiankunWindow.__POWERED_BY_QIANKUN__) {

 createApp(App).use(router).use(ElementPlus).mount('#app');

} else {

 renderWithQiankun({

   mount(props) {

     app = createApp(App).use(router).use(ElementPlus);

     app.mount(props.container?.querySelector('#app'));

     console.log('vue app mount get props', props);

     props.onGlobalStateChange((state: any, prev: any) => console.log(`子应用 [onGlobalStateChange - ${props.name}]:`, state, prev));

     props.setGlobalState({count: 100});

   },

     // bootstrap、update、unmount三个生命周期省略。。。。

 });

}

​

9、React多自定义render页,在qiankun框架内找不页面的问题。

问题描述:子应用有多个root.render页面,用于处理不同的渲染逻辑,直接访问子应用的这些页面,一切正常;但在父应用中访问某些页面时,页面找不到了。经过控制台打印检查,发现子应用根本没有走自定义render页的逻辑,连自定义html里script module也未使用。检测发现,qiankun框架直接选择了react里src/main.tsx作为了入口文件,其他的直接没检测到,这是问题的原因。

解决方案:在src/main.tsx里配置对应的自定义render逻辑,如:

import goCustomRender from './app/custom/main';

const goMainRender = () => {

let root: ReactDOM.Root;

function render(props: any) {

........

  }

renderWithQiankun({

.......

});

if (!qiankunWindow.__POWERED_BY_QIANKUN__) {

  render({});

}

}

// 在父应用中设置window.GO_CUSTOM_PAGE全局参数为true,即可表示需要走自定义render逻辑

if (window.GO_CUSTOM_PAGE) {

goCustomRender()

} else {

goMainRender()

}

解决以上问题,基本可以成功配置完毕子应用为vite的应用,亲测有效!


http://www.kler.cn/a/465595.html

相关文章:

  • C#—SynchronizationContext类详解 (同步上下文)
  • 如何使用SparkSql
  • 用python编写一个放烟花的小程序
  • 对一个双向链表,从尾部遍历找到第一个值为x的点,将node p插入这个点之前,如果找不到,则插在末尾。使用C语言实现
  • Excel重新踩坑5:二级下拉列表制作;★数据透视表;
  • AI大模型的搭建和训练
  • 微信小程序获取后端数据
  • PS4代理伺服器指南
  • JavaScript 基础2
  • 【网络安全】PostMessage:分析JS实现XSS
  • .e01, ..., .e0n的分卷压缩包怎么解压
  • 多目标优化算法——基于分解的多目标进化算法(MOEA-D)
  • [C++]vector(超详细)
  • Docker入门常用命令总结
  • 软考教材重点内容 信息安全工程师 第 12 章网络安全审计技术原理与应用
  • 牛客网刷题 ——C语言初阶——OR76 两个整数二进制位不同个数
  • 计算效率提升 10 倍,存储成本降低 60%,灵犀科技基于 Apache Doris 建设统一数据服务平台
  • Swift Combine 学习(三):Subscription和 Subscriber
  • React Router 用法概览
  • Redis的数据过期清除策略
  • 周亚辉投资笔记2025系列第1篇:机器人时代的社会结构模型与十年后中国首富预测
  • xdoj ROT13加密
  • 【现代摄像头作为一种视频输入摄像头】
  • B4004 [GESP202406 三级] 寻找倍数
  • /ete/security/limits.conf参数详解
  • 小程序学习07—— uniapp组件通信props和$emit和插槽语法