前言
小伙伴们大家好。今天继续给大家分享关于微前端qiankun的相关知识。前面的文章我们基于qiankun+vue2.0已经实现了一个简单的微前端应用了,并且还实现了history和hash两种路由模式的切换。在该应用中无论是主应用还是子应用我们用的都是vue的技术栈,这并没有体现出微前端的最大特点(与技术栈无关)。因此本文将在原有微前端应用的基础上再接入一个react的子应用。
另外:本文目的仅仅是为了体现一下微前端与技术栈无关的特点,所以这里只描述一下接入react项目的简单步骤和关键代码,关于更多react相关的知识这里不再过多赘述。
创建react项目
为了让主应用能够接入一个react子应用,我们需要先创建一个react项目。
- 安装create-react-app脚手架 (npm install create-react-app -g)
- 利用create-react-app 创建一个react项目react-child
- 项目创建完成后,首先运行一下num run eject命令,将项目中的一些配置文件暴露出来
- 文件暴露后会多出个config目录,找到 config 目录下的 webpack.config.js 文件并定位找到 output 属性,并为其添加新的配置属性:library和libraryTarget,同时将 globalOjbect 的值改为:“window”
- 找到 config 目录下的 webpackDevServer.config.js并在module.exports的return中添加headers:“Access-Control-Allow-Origin”:“*” 设置允许跨域
- 打开src下的index.js文件,将原有渲染元素的代码封装到一个render函数中,便于分情况调用。
- 1.指定容器时需要指定元素的选择范围,避免与其他应用冲突
- 2.添加window.__ POWERED_BY_QIANKUN __ 来判断是主应用启动还是子应用独立运行
- 3.导出3个必需的方法bootstrap、mount和unmount
到这里子应用的相关配置就基本完成,已经满足接入主应用的条件。下面我们来看下关键代码实现:(这里只展示修改部分的关键代码,未提及到的表示均为改动,使用项目的默认代码即可)
- 安装脚手架
npm install create-react-app -g
- 创建项目 react-child
create-react-app react-child
- 切换到项目目录运行命令暴露相关配置文件
npm run eject
- 修改webpack.config.js,添加library和libraryTarget
// config/webpack.config.js
// ......省略
output:{
//...省略
globalObject: "window",
library:'react-child',//命名自己决定(可随意命名)
libraryTarget:'umd'
//...省略
}
// ......省略
- 修改webpackDevServer.config.js设置允许跨域
// config/webpackDevServer.config.js
// ......省略
module.exports = function(proxy, allowedHost){
return {
headers:{
"Access-Control-Allow-Origin":"*"
}
//...省略
}
}
// ......省略
- src/index.js完整代码
import React from 'react';
import ReactDOMfrom 'react-dom';
import './index.css';
import App from './App';
function render(props){
const {
container} = props;
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
container ? container.querySelector('#root'):document.getElementById('root')//这里需要圈定元素的可选范围避免与其他应用冲突
);
}
//判断应用是独立运行还是有主应用启动
if(window.__POWERED_BY_QIANKUN__){
/* global __webpack_public_path__:writable*/ //这句注释不加会报错
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;//主应用启动
}else{
render({
});//独立运行
}
//导出3个必需的方法
export async function bootstrap(props){
}
export async function mount(props){
render(props);
}
export async function unmount(props){
ReactDOM.unmountComponentAtNode(container ? container.querySelector('#root'): document.getElementById('root'));
}
在主应用中注册react子应用
按照上面的步骤就已经实现了子应用的相关配置,基本已经达到了接入的条件了。下面我们需要修改主应用中的代码,在主应用中注册react子应用
- 修改App.vue
- 在App.vue中新增一个router-link,标题为React,to属性值为 “/react”
- 在router-view标签下新增一个id为reactContainer的div盒子
- 修改src/main.js: 在apps数组中添加react子应用的相关配置信息进行注册
- name属性值:‘react-child’
- entry:’//localhost:3000’,
- container:’#reactContainer;
- activeRule:’#/react’
- App.vue
<!--省略-->
<router-link to="/react">React</router-link>
<div id="reactContainer"></div>
<!--省略-->
- main.js
//......省略
const apps = [
//......省略
{
name:'react-child',
entry:'//localhost:3000',
container:'#reactContainer',
activeRule:'#/react'
}
//......省略
]
//......省略
logo 404及解决方案
到此就已经实现了在Vue主应用中接入一个react的子应用。然鹅,当我们把应用运行起来后,你会发现子应用接入是成功了,但是react中那个转动的logo图片却没加载出来,这是因为 webpack在加载资源时没有使用正确的publicPath
官方给出了两种解决措施
- 方案一:使用webpack运行时publicPath配置,qiankun将会在微应用bootstrap之前注入一个运行时的publicPath变量,我们需要做的就是在入口文件的 顶部 添加如下代码:
__wepack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__
- 方案二:另一种方案就是将webpack.config.js下的output中的publicPath配置设置成一个绝对路径,例如:
{ output:{ publicPath: '//localhost:3000/' } }
显然方案二不是最理想的,那我们就按照方案一的方式去配置。然而向上翻一下发现这个变量 __ wepack_public_path __其实我们已经配置过了,但为什么没有生效呢,我们再仔细看一下方案一,哎这时你会发现它要求的是在入口文件的顶部添加代码,这样的话就得需要把代码添加到import语句的上面了,但是我们知道这样是不被允许的,那我们就只能再新建一个public-path.js文件并把代码添加到该文件中,然后再在入口文件的顶部引入该文件。
我们来看下修改后的最终代码:
- public-path.js
if(window.__POWERED_BY_QIANKUN__){
/* global __webpack_public_path__:writable*/ //这句注释不加会报错
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;//主应用启动
}
- index.js
import './public-path';
// ...省略
if(!window.__POWERED_BY_QIANKUN__){
render({
});//独立运行
}
// ...省略
总结
本文我们为大家分享了接入一个react子应用的步骤,并且分析了静态资源404的问题和解决方案,最终一个react子应用接入就完美实现了。
好了本次分享就到这里了,喜欢的小伙伴欢迎点赞关注加评论哦