4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

「esm.sh/tsx」で HTML に書いた TypeScript や React の処理をブラウザで直接扱う

Last updated at Posted at 2025-07-10

はじめに

この記事は、以下の esm.sh の公式ページに書かれている「esm.sh/tsx」に関する話です。

●ESM>CDN
 https://esm.sh/

これを使って、HTML に書いた TypeScript や React の処理をブラウザで直接扱ってみます。

esm.sh/tsx を使ってみる

esm.sh/tsx のページの内容を見てみる

esm.sh/tsx のページを( https://esm.sh/#tsx )を見ると、以下の内容が書かれています。

image.png

<!DOCTYPE html>
<html>
<head>
  <script type="importmap">
    {
      "imports": {
        "react": "https://esm.sh/react@19.1.0",
        "react-dom/client": "https://esm.sh/react-dom@19.1.0/client"
      }
    }
  </script>
  <script type="module" src="https://esm.sh/tsx"></script>
</head>
<body>
  <div id="root"></div>
  <script type="text/babel">
    import { createRoot } from "react-dom/client"
    createRoot(root).render(<h1>Hello, World!</h1>)
  </script>
</body>
</html>

React の処理を直接扱うサンプルになっているようです。

React の処理を書きかえてみる

上記の React の処理の部分を、以下の React公式のクイックスタートのものに置き換えて試してみます。

●Quick Start – React
 https://react.dev/learn

具体的には Updating the screen という部分の以下の処理を、少し書きかえて使います。

image.png

import { useState } from 'react';

export default function MyApp() {
  return (
    <div>
      <h1>Counters that update separately</h1>
      <MyButton />
      <MyButton />
    </div>
  );
}

function MyButton() {
  const [count, setCount] = useState(0);

  function handleClick() {
    setCount(count + 1);
  }

  return (
    <button onClick={handleClick}>
      Clicked {count} times
    </button>
  );
}

書きかえたコード

以下が書きかえたコードです。

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8" />
    <script type="importmap">
      {
        "imports": {
          "react": "https://esm.sh/react@19",
          "react-dom/client": "https://esm.sh/react-dom@19/client"
        }
      }
    </script>
    <script type="module" src="https://esm.sh/tsx"></script>
  </head>
  <body>
    <div id="root"></div>

    <script type="text/tsx">
      import React, { useState } from "react";
      import { createRoot } from "react-dom/client";

      function MyButton() {
        const [count, setCount] = useState(0);
        return (
          <button onClick={() => setCount(c => c + 1)}>
            Clicked {count} times
          </button>
        );
      }

      export default function MyApp() {
        return (
          <div>
            <h1>Counters that update separately</h1>
            <MyButton />
            <MyButton />
          </div>
        );
      }

      const rootEl = document.getElementById("root");
      createRoot(rootEl).render(<MyApp />);
    </script>
  </body>
</html>

これをブラウザで開いて操作してみたところ、以下のように意図通りに動作しました。

2025-07-10_22-26-58 (1).gif

TypeScript を試す

TypeScript で試してみます。以下のコードを試してみました。

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8" />
    <script type="module" src="https://esm.sh/tsx?dev"></script>
  </head>
  <body>
    <div id="output" style="font-family: sans-serif; font-size: 1.2rem"></div>

    <script type="text/ts">
      interface Person {
        name: string;
        age: number;
      }

      function greet(p: Person): string {
        return `${p.name} さん、こんにちは!あなたは ${p.age} 歳ですね。`;
      }

      const user: Person = { name: "太郎", age: 20 };

      const message = greet(user);

      console.log(message);
      document.getElementById("output")!.textContent = message;
    </script>
  </body>
</html>

これをブラウザで開いてみたところ、以下が表示されたのを確認できました。

image.png

【追記】

その後、この続きの第二弾・第三弾の記事も書きました。

●「esm.sh/tsx」を使って React と Tailwind CSS をブラウザで直接扱う - Qiita
 https://qiita.com/youtoy/items/cef54f08682b4386bc47

●「esm.sh/tsx」を使って React と daisyUI/Mantine をブラウザで直接扱う - Qiita
 https://qiita.com/youtoy/items/27b8101249c9be03ec0c

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?