1、vite子项目接入qiankun
qiankun项目子项目采用vite构建,官方没有文档,我们可以参考网上解决方案vite-plugin-qiankun
,
它解决以下问题:
开发模式:在开发环境下,如果我们使用 vite 来构建 vue3 子应用,基于vite的构建机制,会在子应的 html 的入口文件的 script 标签上携带 type=module。而我们知道qiankun父应用引入子应用,本质上是将html做为入口文件,并通过import-html-entry这个库去加载子应用所需要的资源列表Js、css,然后通过eval直接执行,而基于vite构建的js中import、export并没有被转码,会导致直接报错(不允许在非 type=module 的 script 里面使用 import)
- vite.config.ts
import { defineConfig } from 'vite'
import qiankun from 'vite-plugin-qiankun'
export default defineConfig((mode) => {
return {
plugins: [
qiankun('subApp', { // 微应用名字,与主应用注册的微应用名字保持一致
useDevMode: true,
}),
],
}
})
- main.js
import { createApp } from 'vue'
import App from './App.vue'
import {
renderWithQiankun,
qiankunWindow,
QiankunProps,
} from 'vite-plugin-qiankun/dist/helper'
const render = (props: QiankunProps = {}) => {
const { container } = props
const app: string | Element = container?.querySelector('#subApp') || '#subApp' // 避免 id 重复导致微应用挂载失败
createApp(App).mount(app)
}
const initQianKun = () => {
renderWithQiankun({
bootstrap() {
console.log('微应用:bootstrap')
},
mount(props) { // 获取主应用传入数据
console.log('微应用:mount', props)
render(props)
},
unmount(props) {
console.log('微应用:unmount', props)
},
update(props) {
console.log('微应用:update', props)
},
})
}
qiankunWindow.__POWERED_BY_QIANKUN__ ? initQianKun() : render() // 判断是否使用 qiankun ,保证项目可以独立运行
2、问题描述
生产模式下依旧不支持publicPath
, 需要将vite.config.js
中base
配置写死。
导致多环境部署不便捷。无法像在webpack结合window.INJECTED_PUBLIC_PATH_BY_QIANKUN
+ publicpath
来解决
3、解决方案
- 增加webpack配置,让生产环境运用webpack打包,开发环境使用vite开发
- 将项目目录进行改造
├── tsconfig.json
├── package.json
├── vue.config.js
├── src
│ ├── main.ts
│ └── route.ts
├── vite
│ ├── tsconfig1.json
│ ├── package.json
│ ├── vite.config.js
│ ├── main.ts
│ ├── route.ts
│ ├── src
│ ├── App.vue
│ ├── components
│ ├── store
│ │ └── modules
│ └── views
│ ├── book
│ └── movie
└── README.md
- vite/src/main.ts 采用
vite-plugin-qiankun
插件; src/main.ts采用webpack
import './public-path';
import { createApp } from 'vue'
import { createRouter, createWebHashHistory } from 'vue-router'
import App from '@/App.vue';
import routes from './routes';
import pinia is from '@/store';
function render(){
const router = createRouter({
history: createWebHashHistory(),
routes
})
createApp(App).use(router).use(pinia).mount('#app')
}
// 独立运行时
if (!(window as any).__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() {
}
- vite/route.ts 采用
import.mata.glob(["@/views/**"])
; src/route.ts 采用require.context("@/views/",true,/.*\.vue/)
- vite/tsconfig.json里面
{@/*:./src/*}
,添加到gitignore不要提交到git仓库;tsconfig.json 里面{@/*: ./vite/src/*}
; - package.json 脚本设置
start:"cd ./vite && npm start",
build:"vue-cli-service build"
欢迎关注我的前端自检清单,我和你一起成长