【微前端】手把手从零开始带你实现一个React子应用的接入

前言

小伙伴们大家好。今天继续给大家分享关于微前端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子应用接入就完美实现了。

好了本次分享就到这里了,喜欢的小伙伴欢迎点赞关注加评论哦

猜你喜欢

转载自blog.csdn.net/lixiaosenlin/article/details/121104430