Skip to content

Instantly share code, notes, and snippets.

@podhmo
Last active January 6, 2025 10:24

esm.shでreact@19は依存関係を適切に指定しないと動かない -> 直ってた。

昔はそうだったみたいだけれど今は動くみたい。以前はschedulerあたりのバージョンの不整合で動いていなかった気がする。

以下のような感じでバージョンを指定してあげるか?devで動かしてあげないと動かなかった。

16,18c16,18
< import { StrictMode, useState } from "https://esm.sh/react@19";
< import { createRoot } from "https://esm.sh/react-dom@19/client";
< import { Fragment, jsx, jsxs } from "https://esm.sh/react@19/jsx-runtime";
---
> import { StrictMode, useState } from "https://esm.sh/react@19.0.0";
> import { createRoot } from "https://esm.sh/react-dom@19.0.0/client?deps=react@19.0.0,scheduler@0.25.0";
> import { Fragment, jsx, jsxs } from "https://esm.sh/react@19.0.0/jsx-runtime";
16,18c16,18
< import { StrictMode, useState } from "https://esm.sh/react@19";
< import { createRoot } from "https://esm.sh/react-dom@19/client";
< import { Fragment, jsx, jsxs } from "https://esm.sh/react@19/jsx-runtime";
---
> import { StrictMode, useState } from "https://esm.sh/react@19.0.0";
> import { createRoot } from "https://esm.sh/react-dom@19.0.0/client?deps=react@19.0.0,scheduler@0.25.0";
> import { Fragment, jsx, jsxs } from "https://esm.sh/react@19.0.0/jsx-runtime";
import { join as pathjoin } from "jsr:@std/path@1.0.8/join";
import { type Context, Hono } from "jsr:@hono/hono@4.6.15";
import { HTML, tsxToJs } from "jsr:@podhmo/glue@0.2.2/mini-webapp";
// serve for development
// $ deno run -A jsr:@podhmo/glue@0.2.2 serve --port 8080 ./app.ts
//
// bunle to single html file
// $ deno run -A jsr:@podhmo/glue@0.2.2 bundle --output-style html --html-id app ./client.tsx > index.html
const app = new Hono();
app.get("/", async (ctx: Context) => {
const filepath = pathjoin(import.meta.dirname ?? "", "./client.tsx");
const code = await tsxToJs(filepath);
const html = HTML({ code, id: "app", title: "Counter" });
return ctx.html(html);
});
export default app;
/** @jsxRuntime automatic */
/** @jsxImportSource npm:react@19 */
/** @jsxImportSourceTypes npm:@types/react@19 */
import { StrictMode, useState } from "npm:react@19";
import { createRoot } from "npm:react-dom@19/client";
function Counter() {
const [count, setCount] = useState(0);
const onIncrement = () => setCount((prev: number) => prev + 1);
const onDecrement = () => setCount((prev: number) => prev - 1);
return (
<>
<p>Count: {count}</p>
<button onClick={onIncrement}>Increment</button>
<button onClick={onDecrement}>Decrement</button>
</>
);
}
function App() {
return (
<>
<h1>Counter</h1>
<Counter />
</>
);
}
// main
const root = createRoot(document.getElementById("app"));
root.render(
<StrictMode>
<App />
</StrictMode>,
);
{
"version": "4",
"specifiers": {
"npm:@types/react@19": "19.0.2",
"npm:react-dom@19": "19.0.0_react@19.0.0",
"npm:react@19": "19.0.0"
},
"npm": {
"@types/react@19.0.2": {
"integrity": "sha512-USU8ZI/xyKJwFTpjSVIrSeHBVAGagkHQKPNbxeWwql/vDmnTIBgx+TJnhFnj1NXgz8XfprU0egV2dROLGpsBEg==",
"dependencies": [
"csstype"
]
},
"csstype@3.1.3": {
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
},
"react-dom@19.0.0_react@19.0.0": {
"integrity": "sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==",
"dependencies": [
"react",
"scheduler"
]
},
"react@19.0.0": {
"integrity": "sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ=="
},
"scheduler@0.25.0": {
"integrity": "sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA=="
}
}
}
<!DOCTYPE html>
<html data-theme="dark">
<head>
<meta charset="utf-8" />
<title>client.tsx</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="color-scheme" content="light dark" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css" />
</head>
<body>
<main id=app class="container">
<h1>...</h1>
</main>
<script type="module">
// client.tsx
import { StrictMode, useState } from "https://esm.sh/react@19";
import { createRoot } from "https://esm.sh/react-dom@19/client";
import { Fragment, jsx, jsxs } from "https://esm.sh/react@19/jsx-runtime";
function Counter() {
const [count, setCount] = useState(0);
const onIncrement = () => setCount((prev) => prev + 1);
const onDecrement = () => setCount((prev) => prev - 1);
return /* @__PURE__ */ jsxs(Fragment, { children: [
/* @__PURE__ */ jsxs("p", { children: [
"Count: ",
count
] }),
/* @__PURE__ */ jsx("button", { onClick: onIncrement, children: "Increment" }),
/* @__PURE__ */ jsx("button", { onClick: onDecrement, children: "Decrement" })
] });
}
function App() {
return /* @__PURE__ */ jsxs(Fragment, { children: [
/* @__PURE__ */ jsx("h1", { children: "Counter" }),
/* @__PURE__ */ jsx(Counter, {})
] });
}
var root = createRoot(document.getElementById("app"));
root.render(
/* @__PURE__ */ jsx(StrictMode, { children: /* @__PURE__ */ jsx(App, {}) })
);
</script>
</body>
</html>
<!DOCTYPE html>
<html data-theme="dark">
<head>
<meta charset="utf-8" />
<title>client.tsx</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="color-scheme" content="light dark" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css" />
</head>
<body>
<main id=app class="container">
<h1>...</h1>
</main>
<script type="module">
// client.tsx
import { StrictMode, useState } from "https://esm.sh/react@19.0.0";
import { createRoot } from "https://esm.sh/react-dom@19.0.0/client?deps=react@19.0.0,scheduler@0.25.0";
import { Fragment, jsx, jsxs } from "https://esm.sh/react@19.0.0/jsx-runtime";
function Counter() {
const [count, setCount] = useState(0);
const onIncrement = () => setCount((prev) => prev + 1);
const onDecrement = () => setCount((prev) => prev - 1);
return /* @__PURE__ */ jsxs(Fragment, { children: [
/* @__PURE__ */ jsxs("p", { children: [
"Count: ",
count
] }),
/* @__PURE__ */ jsx("button", { onClick: onIncrement, children: "Increment" }),
/* @__PURE__ */ jsx("button", { onClick: onDecrement, children: "Decrement" })
] });
}
function App() {
return /* @__PURE__ */ jsxs(Fragment, { children: [
/* @__PURE__ */ jsx("h1", { children: "Counter" }),
/* @__PURE__ */ jsx(Counter, {})
] });
}
var root = createRoot(document.getElementById("app"));
root.render(
/* @__PURE__ */ jsx(StrictMode, { children: /* @__PURE__ */ jsx(App, {}) })
);
</script>
</body>
</html>
clean:
rm -f deno.json deno.lock index.html index2.html
.PHONY: clean
init:
deno run -A jsr:@podhmo/glue@0.2.2 init
.PHONY: init
index.html: clean
deno run -A jsr:@podhmo/glue@0.2.2 bundle --output-style html --html-id app client.tsx > $@
index2.html:
echo {} > deno.json
deno cache *.tsx
deno run -A jsr:@podhmo/glue@0.2.2 bundle --output-style html --html-id app client.tsx > $@
diff:
$(MAKE) index.html
$(MAKE) index2.html
diff index.html index2.html > a.diff
@podhmo
Copy link
Author

podhmo commented Jan 6, 2025

codepenで共有というのは良いかもしれない。

https://codepen.io/podhmo-the-animator/full/Wbedvdd

@podhmo
Copy link
Author

podhmo commented Jan 6, 2025

(全く同じような内容のgistを以前にも挙げていた 💫 )

https://gist.github.com/podhmo/8239468c4228e432b8142314eb33241b

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment