如何用最新版React创建可嵌入Widget并解决渲染报错
创建可嵌入任意网站的React Widget(React 18+版本)
一、修复当前渲染代码报错
你遇到的错误是因为React 18彻底移除了ReactDOM.render API,改用createRoot进行渲染。修正后的代码如下:
import React from 'react'; import { createRoot } from 'react-dom/client'; import App from './App'; // 查找页面中所有标记为.proc_widget的容器 const widgetContainers = document.querySelectorAll('.proc_widget'); widgetContainers.forEach(container => { // 为每个容器创建根节点 const root = createRoot(container); // 渲染Widget组件,传入容器上的data-symbol属性作为props root.render( <React.StrictMode> <App symbol={container.dataset.symbol} /> </React.StrictMode> ); });
二、完整Widget创建与打包流程
1. 初始化项目
推荐用Vite初始化React项目(比Create React App更灵活、打包更快):
npm create vite@latest my-widget -- --template react cd my-widget npm install
2. 编写Widget核心组件
在src/App.jsx中编写你的Widget逻辑(以聊天类Widget为例):
export default function App({ symbol }) { return ( <div style={{ width: '300px', height: '400px', border: '1px solid #ccc', borderRadius: '8px', padding: '16px', fontFamily: 'Arial, sans-serif', boxShadow: '0 2px 8px rgba(0,0,0,0.1)' }}> <h3>专属Widget:{symbol}</h3> <div className="chat-area" style={{marginTop: '20px'}}> <p>这是嵌入的Widget内容</p> {/* 在这里添加聊天交互、业务逻辑 */} </div> </div> ); }
3. 配置打包输出为UMD格式
要让Widget能嵌入任意网站,必须打包成**UMD(通用模块定义)**格式,支持直接通过script标签引入。
Vite配置方式
修改vite.config.js,添加build相关配置:
import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; export default defineConfig({ plugins: [react()], build: { lib: { entry: 'src/main.jsx', // 你的项目入口文件路径 name: 'MyEmbeddableWidget', // 全局变量名,嵌入网站时会用到 fileName: (format) => `my-widget.${format}.js`, }, rollupOptions: { // 排除React和ReactDOM,避免嵌入网站重复加载 external: ['react', 'react-dom'], output: { // 为外部依赖映射全局变量 globals: { react: 'React', 'react-dom': 'ReactDOM', }, }, }, }, });
Create React App配置方式
需要安装工具修改默认配置:
npm install react-app-rewired customize-cra --save-dev
创建config-overrides.js文件:
const { setWebpackConfig } = require('customize-cra'); module.exports = setWebpackConfig({ output: { library: 'MyEmbeddableWidget', libraryTarget: 'umd', globalObject: 'this', }, externals: { react: 'React', 'react-dom': 'ReactDOM', }, });
修改package.json中的scripts:
"scripts": { "start": "react-app-rewired start", "build": "react-app-rewired build", "test": "react-app-rewired test", "eject": "react-scripts eject" }
4. 执行打包
运行打包命令生成可嵌入文件:
npm run build
打包后会在dist(Vite)或build(Create React App)目录下生成UMD格式的js文件,比如my-widget.umd.js。
5. 嵌入到目标网站
在需要嵌入Widget的网站中,添加以下代码:
<!-- 先引入React和ReactDOM的生产版CDN(如果目标网站未自带) --> <script crossorigin src="React官方CDN地址"></script> <script crossorigin src="ReactDOM官方CDN地址"></script> <!-- 引入你的Widget打包文件 --> <script src="你的Widget文件部署路径"></script> <!-- 添加Widget容器,通过data-symbol传递自定义参数 --> <div class="proc_widget" data-symbol="USER_001"></div> <div class="proc_widget" data-symbol="USER_002"></div>
注:如果目标网站已引入React和ReactDOM,可跳过前两个script标签,避免重复加载。
三、额外注意事项
- 样式隔离:用CSS Modules、styled-components或Tailwind CSS前缀功能,确保Widget样式不会影响宿主网站。
- 全局变量冲突:打包时指定的全局变量名(如
MyEmbeddableWidget)要避开宿主网站已有的全局变量。 - 兼容性:如需兼容低版本浏览器,可在打包配置中添加Babel转译和必要的polyfill。
内容的提问来源于stack exchange,提问作者Atul Verma
相关产品推荐
相关产品推荐

