なぜlitでもpreactでもなく、ReactでWeb Componentsを作成するのか?
どうしてもReactでなければ動かないライブラリがあるから。
どうやって作るのか?
まずはpnpm create vite
でReact+TypeScriptの環境をつくります。
そのフォルダに入った状態だと考えてください。
npm install -D react-to-webcomponent
index.html
<!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 + TS</title>
</head>
<body>
<my-element name="yuumillar"></my-element>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
こんな感じで、my-elementを使います。普段は<div id="root"></div>
のようになっているところを、自分の作成したいWeb Componentsにします。
main.tsx
import React from "react";
import ReactDOM from "react-dom/client";
import r2wc from "react-to-webcomponent";
import { App } from "./App";
const myElement = r2wc(App, React, ReactDOM, {
props: {
name: "string",
},
});
customElements.define("my-element", myElement);
こんな感じでmy-elementを定義してあげます。
App.tsx
type AppProps = {
name: string;
};
export const App = ({ name }: AppProps) => <div>{name}</div>;
これが最低限の実装です。html側のpropsを変更すると、App.tsxのnameが変更されます。
どうやってビルド後に使用するか?
いつも通りにnpm run buildを実行して、distフォルダを作成します。
そこにあるjsファイルを読み込めば、Web Componentsを使用することができます。
anyhoge.html
<!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 + TS</title>
</head>
<body>
<my-element name="yuumillar"></my-element>
<script type="module" src="/dist/src_main.tsx.1e2b0b6f.js"></script>
</body>
こんな感じですな。
これで好きなところでコンポーネントとして扱えます。PHPで動いているレガシーなシステムでもReactが使えます。便利だね。