我正试图从React组件构建Web组件,一切都运作良好,但有两个问题需要解决:
- 有没有一种方法可以将这种Web组件转换为纯Web组件(使用Webpack、转译或其他方式),以便不捆绑React和其他依赖项?
- 是否有一种方法只包含所需的依赖项部分或仅是全部/无部分,并且必须使用Webpack的外部设置来使用主机的版本?
谢谢。
我正试图从React组件构建Web组件,一切都运作良好,但有两个问题需要解决:
谢谢。
对于第一个问题,没有直接将React组件转换为Web Component的方法。您需要将其包装在Web Component Class中:
对于第一个问题,没有直接将React组件转换为Web Component的方法。您将不得不将其包装在Web Component Class中:
export function MyReactComponent() {
return (
<div>
Hello world
</div>
);
}
class MyWebComponent extends HTMLElement {
constructor() {
super();
// Do something more
}
connectedCallback() {
// Create a ShadowDOM
const root = this.attachShadow({ mode: 'open' });
// Create a mount element
const mountPoint = document.createElement('div');
root.appendChild(mountPoint);
// You can directly use shadow root as a mount point
ReactDOM.render(<MyReactComponent />, mountPoint);
}
}
customElements.define('my-web-component', MyWebComponent);
当然,您可以将其概括并创建可重复使用的函数,例如:
function register(MyReactComponent, name) {
const WebComponent = class extends HTMLElement {
constructor() {
super();
// Do something more
}
connectedCallback() {
// Create a ShadowDOM
const root = this.attachShadow({ mode: 'open' });
// Create a mount element
const mountPoint = document.createElement('div');
root.appendChild(mountPoint);
// You can directly use shadow root as a mount point
ReactDOM.render(<MyReactComponent />, mountPoint);
}
}
customElements.define(name, MyWebComponent);
}
register(MyReactComponent, 'my-web-component');
现在可以重复使用相同的注册函数,以使您要公开为Web组件的所有组件都能够使用。如果您的组件接受应该传递的props,则可以将此功能更改为接受第三个参数作为字符串数组,其中每个值都将使用Object.define
注册为此组件的setter。每次调用setter时,您只需再次调用ReactDOM.render
即可。
对于第二个问题,你尝试做的有多种情况。
import
或require
。为库进行打包稍微棘手,因为您必须决定输出格式(common.js、ES模块或UMD或全局或多个格式)。如果您正在为浏览器打包,则理想的格式是ES模块,因为它允许更好的树摇。以前Webpack不支持Module格式,最近开始支持它。总的来说,我建议对于应用程序使用Webpack,对于库使用Rollup.js。
/** Main.jsx */
import React from 'react'
import App from './App'
import { define } from 'remount';
define({'react-counter': App},
{
attributes: ['defaultValue'],
shadow:false
})
/** App.jsx */
import React from "react";
import Counter from "./components/Counter.jsx";
function App({defaultValue}) {
return (
<div>
<h1>Counter Component</h1>
<Counter defaultValue={defaultValue}/>
</div>
)
}
export default App;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React</title>
</head>
<body>
<react-counter defaultValue="5"></react-counter>
<script type="module" src="/src/main.jsx"></script>
</body>
</html>
React并不是一个用于构建本地Web组件的库。
手动编写Web组件也不是最佳选择,因为它无法处理条件、循环、状态变化、虚拟DOM和其他基本功能。
React、Vue、Svelte和其他自定义库确实有一些优点,而本地Web组件则具有许多其他优点,如生态系统的简单性以及被浏览器和W3C支持。
以下是一些可帮助您以现代和便捷方式编写本地Web组件的库:
如果您真的想将React组件包装成本地Web组件,可以尝试以下方法:
class MyComponent extends HTMLElement {
constructor() {
this.innerHTML = '<MyReactComponent />'
}
}
customElements.define('my-component', MyComponent)
并在您的HTML页面中使用它 <my-component />