🧊

Preact w/ SignalsをバンドルせずCDN経由で使う

ちゃんとしたアプリ開発ならまだしも、ほんのちょっとしたGUIを作ろうってなったくらいで、バンドラやら一式をセットアップするのはやはり面倒で。

こういう時に便利な選択肢としては、やはりPreactが推しなのです。

というわけで

以下が、Preact+Hooks+Signals+Htmの全部入りが、CDN経由で単一HTMLからシュッと動くテンプレです。

<!doctype html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Preact w/ Signals by CDN</title>
  </head>
  <body>
    <script type="importmap">
      {
        "imports": {
          "preact": "https://esm.sh/preact@10.19.3",
          "preact/hooks": "https://esm.sh/preact@10.19.3/hooks?external=preact",
          "@preact/signals": "https://esm.sh/@preact/signals@1.2.2?external=preact",
          "htm": "https://esm.sh/htm@3.1.1"
        }
      }
    </script>
    <script type="module">
      import htm from "htm";
      import { h, render } from "preact";
      import { useEffect } from "preact/hooks";
      import { useSignal } from "@preact/signals";

      const html = htm.bind(h);

      const App = ({ data }) => {
        const now = useSignal(Date.now());
        useEffect(() => {
          const timer = setInterval(() => (now.value = Date.now()), 500);
          return () => clearInterval(timer);
        });

        return html`<div>
          <h1>Hello at ${now}!</h1>
        </div>`;
      };

      render(html`<${App} />`, document.body);
    </script>
  </body>
</html>

ちなみに、Signalsなしでよければ、公式サイトにあるようimport { html, render } from "https://esm.sh/htm/preact/standalone"が最短手。

ポイント

importmapでやってることが地味に重要で、

  • バージョンを揃える
  • ?externalで同一のPreactのインスタンスを参照する

というのがポイント。

バージョンはそのうち古くなると思うけど、その時はいったんバージョンなしでアクセスしてみて、リダイレクトされたバージョンで更新すればいい。