タグ

ブックマーク / zenn.dev/mizchi (39)

  • TypeScriptの型と値とバリデーション

    TypeScript質的に自分に型が付与されていると思っているだけの JavaScript です。 いくら型を付与しようが、それが実行時に影響を与えることはありません。 コードレビューをしているとここを誤解している人が当に多いです。何度も解説しているのですが、なかなか浸透しないので、TypeScript におけるバリデーションという視点で記事を書くことにしました。 あと TS でバリデータ使って色々作ろうとしている友人と、プログラミング始めたてで zodopenapi を使っいる友人がいたので、彼らが想定読者です。 型と値の名前空間 TypeScript 上での名前空間(スコープ)は2つに分類できます。 値: 実行時にランタイム上のメモリに存在するもの 型: 静的解析時にのみ参照可能なもの。コンパイル時に完全に消滅する。 TypeScript は基的に JavaScript

    TypeScriptの型と値とバリデーション
  • Deno first でやっていく

    去年末ぐらいから Deno を使う割合がグッと増えてきた。最近のJS関連は7割ぐらい deno 環境の VSCode でコードを書いている気がする。 今回はいくつかの実例を示しながら、実際に Deno 使えるじゃんというイメージを持ってもらうためのユースケースを紹介していく。 というか、 deno が普及してくれないと、自分が作ったツールの紹介を全部 deno のインストールから書かないといけなくなる。みんなインストールしといて。 最初に: なぜ Deno を使いたいか 一番の問題点、Node は新しいプロジェクトを一式整えるための手間が非常に重い。 とくに ts で書いたものを他の環境に渡すための方法が未だにしんどい。ある環境で動いたコードをそのままコピーしても、プロジェクト設定の非互換を踏む可能性が非常に高い。 deno にそういう側面がないとは言わないが、非常に少ない。とくに TS

    Deno first でやっていく
  • TypeScript の条件型と分配法則、あるいはユニオン型の写像

    TypeScript の Extract について調べていたら、自分がユニオン型の分配法則について何も理解していなかったことに気づいたので、記事にまとめておく。 Extract の基的な使い方 // https://typescriptbook.jp/reference/type-reuse/utility-types/extract type Grade = "A" | "B" | "C" | "D" | "E"; type FailGrade = Extract<Grade, "D" | "E">; //=> "D" | "E" これは単に ("A" | "B" | "C" | "D" | "E") & ("D" | "E") のインターセクションを取ってるだけなのでは? と今まで考えていたが、全然違った。 Extract 型の TypeScript 上の定義はこうなっている。

    TypeScript の条件型と分配法則、あるいはユニオン型の写像
  • インストール不要。ペライチHTMLでReact+TSX+Tailwind のフロントエンド一式を動かす

    プロトタイピング向けにペライチで最低限のフロントエンドスタックを動かす方法について。 注意: 番で使わないでください。tailwind は CDN モードで動かしているし、 esm.sh はスクリプトを動的にビルドするのでパフォーマンスは良くないです。 前提 jsconf.jp で色々なツールを使えばそれっぽいバンドルレス実現できる(けどパフォーマンスに難)という話を書きました。 具体的には NativeESM + importmaps + esm.sh 等の組み合わせます。 <script type="importmap"> - HTML: ハイパーテキストマークアップ言語 | MDN ESM>CDN これに、 esm.sh の v135 の新機能を使って tsx をバンドルするのを組み合わせる話です。 esm.sh/run 使い方は簡単。 <!-- esm.sh からランナーをロード

    インストール不要。ペライチHTMLでReact+TSX+Tailwind のフロントエンド一式を動かす
  • d1 + prisma + kysely-prisma の環境を作る

    注意: 記事で扱う d1 や miniflare v3 はまだ安定してないので、将来的にこの記事のコードは動かなくなる可能性が高い。 大部分を次の記事を参考にしている。 が、現時点で色々動いたり動かなかったりしたので、だいぶアレンジしている。たぶん .wrangler/state/v3 のローカルDBのパスが頻繁に変わることが予想される。 この記事は何 prisma で d1 を migrations したい d1 は kysely-d1 を prisma の型定義を使って動かす wrangler dev/pages 以外の環境からでもテスト用に wokrerd から d1 の binding を取得する 最終的にはこれが動く import type { D1Database } from "@cloudflare/workers-types"; import type { DB } f

    d1 + prisma + kysely-prisma の環境を作る
  • 2023年のシェル環境構築

    tl;dr fig starship zsh fzf sheldon なぜ vscode の .vscode/tasks.json が fishと非常に相性が悪い。とくに fish-nvm を使っていると、fish 経由のパス実行時に node と npm へパスが通らない。 そもそも fish を使っていた理由は autocomplete を快適にするためだったが、1年ぐらい Fig を使っていて、補完はこれを任せていいと気づいた。 Fig はこういうやつ そもそも fish の拡張コマンドを使わないように生活していた。方言を覚えたくない。というか bash 拡張や zsh 拡張もあんまり覚えたくない。

    2023年のシェル環境構築
  • 「理論上は最強」の Qwik/QwikCity を、フロントエンドの共通基盤にできないか

    Qwik をマイクロフロントエンド基盤として使えないか検討していて思いついた色々。副産物で色々作った。 tl;dr Qwik は理論上は最強。だが難しい qwik-react を使えば選択的に Qwik/React を切り替えられるので、 Astro と同じメタフレームワークとして使えそう React 以外もその気になれば対応できるはず => qwik-svelte と qwik-vue を実装した 最終的な問題は Qwik が流行るかどうか Qwik/QwikCity とは何か Qwik は SSR First なUIライブラリで、 .tsx の React 方言からコンポーネントを生成する。 import { component$, useSignal } from '@builder.io/qwik'; export default component$(() => { return

    「理論上は最強」の Qwik/QwikCity を、フロントエンドの共通基盤にできないか
  • AI 時代のコードの書き方, あるいは Copilot に優しくするプロンプターになる方法

    Copilot をオープンベータ直後から長く使っていて、また補助的に ChatGPT も使いながらコードを書いていて、なんとなくコツがわかるようになってきた。 自分は生成モデルのことは表面的な理解しかしてない。雑にバックプロパゲーションの実装の写経したり、Transformer の解説とかは読んだが、にわかの域を出ていない。 あくまで利用者として生成モデルから吸い出したプラクティスになる。 基的に TypeScriptRust での経験が元になっているが、他の言語にも適用できる話ではあると思う。自分は TypeScript はかなり得意だが、 Rust はあんまり書けるわけではなく、Rust の学習で ChatGPT を頼ろうとして失敗しているというステージ。 Copilot / ChatGPT とどう付き合うか まず、前提として ChatGPT も Copilot も、コード生成

    AI 時代のコードの書き方, あるいは Copilot に優しくするプロンプターになる方法
  • TypeScript 本体のコードを読んでみよう

    みんなお世話になっている TypeScript のコードを読みたいと思ったことはないだろうか。読んだ。 一週間ぐらいかかった。完全に読み切ったとは言えないが、概要は掴んだ。 なかなかに複雑でドメイン知識を得るのが難しかったので、これから読む人向けに、登場人物や概念を整理して紹介したい。 読んだのは 2023/6/8 時点で git clone したコード。 最初に: 自分のゴール設定 複数ファイルにまたがった参照を、 TypeScript の Language Service が提供する findReferences() や findRenameLocations(), goToDefinitions() を使って、インクリメンタルに書き換えたかった。 Terser を使うと、今触ってるオブジェクトが何で、何のメンバを書き換えたかの情報が残らない。これを TypeScript のレイヤーで

    TypeScript 本体のコードを読んでみよう
  • コンポーネントベースで開発する時の CSS の書き方とコンポーネントの分類 (自己流)

    ReactSvelte でコンポーネントベースで開発するとき特有の CSS ノウハウってあんまり効かない気がする Twitter に書いたら反響があったので、自己流だけどまとめておく React Component の管理単位と、CSS としてのレイアウトの管理ポリシーは違うよね、みたいな話をマークアップエンジニアに時折されるが、そんな話は無視して完全一致させる。そういう星のもとで開発している コンポーネントの分類 ロジックコンポーネント レイアウトコンポーネント ブロックコンポーネント インラインコンポーネント 定義 ロジックコンポーネント Provider や hooks などのデータ処理だけを扱い、子に渡すコンポーネント 一切の CSS や DOM 実体を持たない レイアウトコンポーネント レイアウトコンポーネントは複数の子ブロックコンポーネント(または slot)を持ち、子ブ

    コンポーネントベースで開発する時の CSS の書き方とコンポーネントの分類 (自己流)
  • CSSを持たない Headless な UI ライブラリと ChatGPT によるマークアップ生成を試してみる

    いまさら気づいたけど Headless 系のUIライブラリが一番 AI と相性いいのではないか。 ロジックはプログラマで書けて自由度高いし、コンポーネントのネスト構造から意図を読み取れるだろうし、class 名は自由に書けるから意図を表明しやすい。 それをプロンプトとして ChatGPT or Codex にそのまま投げて書かせる、ができる。 というわけで vite + react + radix-ui + vanilla-extract で実験してみた。 プロンプト あなたは凄腕のマークアップエンジニアです。 radix-ui は Headless UI ライブラリで、UIとしてのセマンティクスのみを持っています。 次のコードは React + radix-ui + vanilla-extract で書かれた React コンポーネントです。 // Popover.tsx import

    CSSを持たない Headless な UI ライブラリと ChatGPT によるマークアップ生成を試してみる
  • lizod: 1kb 未満の zod の精神的後継

    作った。 lightweight-zod だから lizod。 npm install lizod -S で使える。 tl;dr 各種フロントエンドCloudflare Workers で zod のビルドサイズが邪魔になっている メソッドチェーンと便利なユーティリティを全部捨てた zod 風のバリデータを作った zod の 57kb に対して lizod は 1kb 以下 これが動く // Pick validators for treeshake import { $any, $array, $boolean, $const, $enum, $intersection, $null, $number, $object, $opt, $regexp, $string, $symbol, $undefined, $union, $void, type Infer, type Valid

    lizod: 1kb 未満の zod の精神的後継
  • フロントエンドの main() を合成関数として副作用を集約する

    これは未実装のアイデアを含む記事です。(後述する lint rule が未実装です) 要は EffectSystem を作ろうとしました。 https://www.eff-lang.org/ void に意味を込めたい こういうフロントエンドのコードについて考えてみましょう。 function mount(): void { const div = document.createElement('div'); div.textContent = "hello"; document.body.append(div); } function print(): void { console.log("hello"); } function maybeError(): void { // 低確率で例外が起こる関数 if (Math.random() > 0.999) { throw new Err

    フロントエンドの main() を合成関数として副作用を集約する
  • cloudflare の better micro frontend を読む

    これはなにか cloudflare スタックを使ったマイクロフロントエンドの提案。 特に service-binding を活用することで異なるサービス(ここでは cloudflare worker)から配信されるフロントエンドを統一的にSSRしつつ、開発単位を分離している。 RTT最適化のために qwik で書かれているが、SSR を意識しなければ他のライブラリを採用しても良い。 $ tree . -I node_modules . ├── README.md ├── body │ ├── package.json │ ├── public │ │ └── favicon.ico │ ├── src │ │ ├── Body.css │ │ ├── entry.ssr.tsx │ │ └── root.tsx │ ├── tsconfig.json │ ├── vite.config.t

    cloudflare の better micro frontend を読む
  • Cloudflare Workers を活かしきるスタックを考えた(remix+d1 on pages-functions) + 残タスク

    Cloudflare Workers を活かしきるスタックを考えた(remix+d1 on pages-functions) + 残タスク このスクラップ で試行錯誤していたまとめ。 最終形はここにアップロードした。 docs の下に、このリポジトリを生成した手順、セットアップ方法、リリース方法を書いてある。 (remix-validated-form や vitest のテストの追加でもうちょっといじるとは思う) なぜ cloudflare-workers + d1 のポテンシャルは最強で、近い未来、開発者|個人開発者の銀の弾丸になると思っているのだが、それを活かす開発スタックが知られていない(要出典)。この記事では GW の間に自分で周辺ライブラリを使い倒しながら選定していった。 2021年 は Fullstack Next.js 元年なので、有望な Next.js 系フレームワークを

    Cloudflare Workers を活かしきるスタックを考えた(remix+d1 on pages-functions) + 残タスク
  • Cloudflare D1 で ORM を使う (drizzle-orm)

    tl;dr 生産性を上げる & SQL インジェクションを防ぐために ORM を使うのがよいとされている(諸説あります) cloudflare workers + d1 はウェブの破壊的イノベーション(諸説あります) モダンフロントエンドで大切なのは TypeScript との親和性と言われている(諸説減ってきた) 当は理想の ORM を自作したいのけど、drizzle が現状一番自分のゴールに近いので、試したら良さそうだった 既存の問題と drizzle-orm 今までのあらすじ というわけで d1 に全振りするのが今後の生存戦略として有効だと思っているんですが、d1 client は専用のAPIからクエリ文字列を送り込む形式なので、native driver を使ってる prisma や typeorm 等が使えません。 自分が Mongodb + たまに Rails ActiveR

    Cloudflare D1 で ORM を使う (drizzle-orm)
  • フロントエンドとSPA職人の目指したものの歴史と概略

    年末年始にフロントエンド論みたいな記事をいくつか見たが、僕ら古のSPA職人がやってきたフロントエンドという職域と目指していたものが失伝しかけている気がするので、ここに時代ごとに何を考えていたか、雑に書き殴る。 注意点として、 2004から始まるが、自分がプログラミングを始めたのが2010, 業務としてコードを書き始めたのが 2012 なので、解像度が高いのはそれ以降になる。 tl;dr 2004: 動き出す HTML 2011: 構造化のはじまり 2015: 贅沢品としてのSPAとコミュニティ分化 2017: 貧者のSPA 2019: 守破離としてのパフォーマンス 2004: 動きだす HTML AJAX の時代。要は XMLHTTPRequest で取得したコンテンツに応じて、動的書き換えをDOM書き換えを行うこと。今では名付けるほどでもない操作だが、HTMLが静的なものをやめたことは、

    フロントエンドとSPA職人の目指したものの歴史と概略
  • Cloudflare D1 がヤバい

    まだ検証足りないけど、マジで想像通りのブツなら魂震えるかもしれん…。 Announcing D1: our first SQL database Cloudflare D1 = Edge SQLite Cloudflare D1 は Cloudflare Worker で、つまり CDN Network 上で sqlite が動きます。これだけなら普通の sqlite ホスティングなんですが、もちろん Cloudflare が出すからにはそれだけではなく、CDN Edge 上に Read Replica がバラ撒かれた sqlite になります。ヤバくないですか? 僕はヤバいと思いました。 このヤバさを知るために、Cloudflare が開発した基盤についていくつか抑えておく必要があります。 Durable Objects は CDN 上の Actor モデルを構築できます。この Acto

    Cloudflare D1 がヤバい
  • イベントループと TypeScript の型から理解する非同期処理

    このは、ブルーベリーの 8 章からインスパイアされて、 TS の型が示す情報から Promise というものを理解してみる、というアプローチで書いたJSの非同期処理の解説です。 これらの資料と合わせて読むことを推奨します。 JSのイベントループのイメージを掴む JSでは中々意識することが少ないですが、正しく理解するには OS レベルのスレッドの視点で考え始める必要があります。 ブラウザや Node.js では一つのスクリプト実行単位を1つのスレッドに割り当てます。それをメインスレッドと呼んだり、ブラウザだったら UI スレッドと呼んだりします。 例えばブラウザでは、これは秒間60回、つまり 16.6ms ごとにループを呼び出します。(node だったらこれがもっと短いです) 仮に setTimeout の実装がなかったとして、それ相当の擬似コードを書くのを試みます。 let handl

    イベントループと TypeScript の型から理解する非同期処理
  • プロを目指す人のためのTypeScript 本の感想 #ブルーベリー本

    自分も教える事が多いので、読み手にどういう風に学んでほしいか、自分がどういう風に伝えるべきか、という視点で読んだ。 1章・イントロダクション そもそもTypeScript とはなにかみたいな話。 コンパイルエラーが出ている状態ではプログラムが完成したとは言えません。 力強い コンパイルエラーをただ避けるのではなく、利用する気持ち で TypeScript プログラミングに臨みましょう。 初心者に型違反の向き合い方を諭す話。IDEの補助になるとか。 TS年表で取り上げてるのが特徴的。exactOptionalProperty を取り上げてたり。 TSの型はランタイムに影響しない、という話を何度も解説している。これは初心者の誤解がとても多いので、必要だと思う。何度いっても、伝わって欲しい人に伝わらないのだが… enum や namespace については意図的に解説しない。過去のTS独自路線だ

    プロを目指す人のためのTypeScript 本の感想 #ブルーベリー本