背景介绍
虽然在日常工作中很少会碰到跨技术栈的组件引用这种骚操作,但是不同项目组、甚至是一个集团的不同子公司之间还是有相互嵌入页面、组件的需求,本文主要为了解决这一问题。
方案介绍
经过一顿搜索,最终确定的方案是通过 web components
做中间层(兼容性查看 caniuse)。
但是这里有一个难题是,怎么把 react 或者 vue 组件转为 web components 以及怎么传入函数?这里推荐用字节跳动的 @magic-microservices/magic 仓库,它的就是为了解决上述问题的!
我们以 react 组件嵌入 Vue 为例:
创建 react 组件
mkdir react-hello && cd react-hello
yarn add father-build -D # 用于构建 react 组件
yarn add react react-dom
touch index.js # 创建 index.js
复制代码
# 创建 father-build 的配置文件
echo "export default {
entry: './index.js',
esm: 'rollup'
}" > .fatherrc.js
复制代码
// index.js
import React, { createElement } from 'react';
import ReactDOM from 'react-dom';
// 定义组件
const Hello = ({name}) => {
return <div>hello { name }</div>
}
// 初始化
export function bootstrap() {}
// 挂载
export function mount(container, props) {
console.log(props)
ReactDOM.render(createElement(Hello, props, null), container);
}
// 更新
export function updated(attrName, value, container, props) {
ReactDOM.render(createElement(Hello, props, null), container);
}
复制代码
修改 package.json
,增加 version 和 name:
{
"name": "react-hello",
"version": "0.0.1",
"main": "./dist/index.esm.js",
"scripts": {
"build": "father-build"
},
"dependencies": {
"react": "^17.0.2",
"react-dom": "^17.0.2"
},
"devDependencies": {
"father-build": "^1.20.1"
}
}
复制代码
执行 yarn link
进行全局链接。
Vue 项目渲染 React 组件
yarn create @vitejs/app my-vue-app --template vue
复制代码
安装如下内容:
yarn link "react-hello" # 链接组件
yarn add react react-dom # 因为是打包为 es module 形式,所以这里需要安装依赖
yarn add @magic-microservices/magic # 安装 magic
复制代码
修改 main.js
:
import { createApp } from 'vue'
import App from './App.vue'
import magic from '@magic-microservices/magic';
import * as ReactHello from 'react-hello';
// 全局注册组件
magic('react-hello', ReactHello, {
// 这里很重要,web components 要求一定要显示声明属性
propTypes: {
name: String
},
});
createApp(App).mount('#app')
复制代码
修改 vite.config.js
:
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [
vue({
template: {
compilerOptions: {
// 将所有包含短横线的标签作为自定义元素处理
isCustomElement: tag => tag === 'react-hello'
}
}
})
]
})
复制代码
修改 App.vue
<template>
<react-hello name="react"></react-hello>
</template>
复制代码
DEMO 链接为:[email protected]:dream2023/cross-stack…
完结撒花 ✿✿ヽ(°▽°)ノ✿