軽いスケッチで GitHub Pages に簡単なページを載せるために、
HTML + JS のシンプルな構成で preact + htm が使いたいと思ったけど、
モジュール でコーディングすると VSCode で補完が効いてくれないので、
あるていど開発しやすくなる構成を考えてみた。
事前操作
VSCode
ext install bierner.lit-html
Term
npm init -y
npm i -D preact htm
.gitignore
node_modules/
preact.js
preact のインテリセンスを効かせたりする用。
hooks を使うときは const { useState } = hooks;
みたくする。
オリジナル関数 cp
は、コンポーネントの props の入力補完を補助するためのもの。
import {
html as _html,
render as _render,
} from "https://unpkg.com/htm/preact/index.mjs?module";
import * as _hooks from "https://unpkg.com/preact@latest/hooks/dist/hooks.module.js?module";
/** @type {import("htm/preact")} */
const html = _html;
/** @type {preact["render"]} */
const render = _render;
/** @type {import("preact/hooks")} */
const hooks = _hooks;
const cp = (component) => (props, children) =>
html`<${component} ...${props}>${children}<//>`;
export { html, render, hooks, cp };
types.d.ts
TypeScript を使ってなくても、VSCode が JSDoc で評価してくれる仕組みを利用する。
type CP<C> = (
props: C extends (props: infer R) => any ? R : never,
children?: any
) => any;
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<script type="module" src="./index.js"></script>
</head>
<body></body>
</html>
index.js
htm のテンプレートリテラルでは通常、props の入力補完は効かないが、
@type {CP<typeof ComponentName>}
と cp
を使うことで、
コンポーネントの props の入力補完を効かせた上でコンポーネントを指定できる。
import { html, cp, render } from "./preact.js";
import App from "./App.js";
/** @type {CP<typeof App>} */
const cpApp = cp(App);
render(html`<h1>${cpApp({ name: "World" })}</h1>`, document.body);
App.js
import { html } from "./preact.js";
/**
* @param {Object} props
* @param {string} props.name
*/
export default ({ name }) => {
return html`Hello <i>${name}</i> !`;
};
以上。こうすれば *.js であれば補完が効いてくれる。
ただし、ちゃんと厳密に型を決めてやりたいなら、素直に TypeScript 使ったほうがいい。
あくまでスケッチ向け。