ブックマーク / zenn.dev/qnighy (21)

  • WebAssembly所感

    WebAssemblyをちょっといじってみて思ったところをまとめてみます。 設計思想 WebAssembly/designに設計文書がまとまっています。特にHighLevelGoals.mdから読み取れるポイントは以下の4点です。 サンドボックス化された環境であること。 移植性があること。つまり、特定の実CPUアーキテクチャ等に依存しないこと。 少なくともC/C++の(十分に高速な)コンパイルターゲットとして機能すること。 安定した仕様を持つこと。 サンドボックスという観点からは、先行技術として以下のようなものが特筆に値します。 Webサンドボックス JavaScript および asm.js Javaアプレット Flash (ActionScript) NaCl, PNaCl Web以外のサンドボックス OSのユーザーランド、特にLinux userland これらのサンドボックスとの比

    WebAssembly所感
    kkeisuke
    kkeisuke 2024/05/13
  • JSのデザインパターンライブラリを試作した話と、それをJSRにアップロードしたら無茶苦茶簡単で感動した話

    デザインパターンライブラリを作った JSRの話だけ読みたい人は読み飛ばしてもOKです。 JavaScriptのtry-catchはC++の影響を受けており、以下の特徴があります。 (A) throwは大域脱出的である。 (B) try-catchはブロック内の全ての例外副作用に対して一括で作用する。 (C) try-catchは文であり、値を返せない。 (D) TypeScriptにおいて、例外型は明示されない。 このうち (B), (C), (D) の問題を解決するため、RustのResultや類似のパラダイムをJSに輸入する試みがしばしば行われています。しかしこの解決手段にはいくつかの問題があり、 (E) rethrowの専用構文がないためボイラープレートが増える。 (F) 出力ストリームに対するwriteなど、戻り値を持たない副作用関数に対するエラーハンドリングが抜け落ちないようにL

    JSのデザインパターンライブラリを試作した話と、それをJSRにアップロードしたら無茶苦茶簡単で感動した話
    kkeisuke
    kkeisuke 2024/05/04
  • tsconfig.json 設定項目備忘録

    型推論オプション 型推論の結果が変わるもの。 ⭐strict ... 以下のセット alwaysStrict strictNullChecks T | null や T | undefined が T に縮退しなくなる。 例 strictBindCallApply Function の各種メソッドが any に縮退しなくなる。 例 strictFunctionTypes コールバック関数の引数が共変でもunifyするようになる結果、型変数の推論優先度が変わることがある。 例 strictPropertyInitialization noImplicitAny 宣言型がない場合にflow typeが使われる機会が増える。 例 noImplicitThis thisの宣言型がない場合に文脈から型が決定される機会が増える。 例 useUnknownInCatchVariables catch (

    tsconfig.json 設定項目備忘録
    kkeisuke
    kkeisuke 2023/01/24
  • `*.d.ts` ファイルをコミットする前に知ってほしい4つのこと

    export type Bookmark = { id: number; url: string; comment: string; }; このファイルには型しか書いてありませんね。ということは、「型定義ファイル」として bookmark.d.ts という名前にするべきでしょうか。実はそうではなく、この場合は bookmark.ts とするべきです。 「型定義ファイル」とは、「どこか別の場所にある実装に型をつけるためのファイル」です。たとえば、以下のファイルは「どこか別の場所にある実装」に型をつけているから、 *.d.ts にするのは自然です。 いっぽう、 type Bookmark は別のどこかにある *.js の型を与えているわけではないので、 *.ts でよいです。 このように来 *.ts であるべきものを *.d.ts にしてしまうことには問題があります。代表的な問題として型エラ

    `*.d.ts` ファイルをコミットする前に知ってほしい4つのこと
    kkeisuke
    kkeisuke 2023/01/17
  • TypeScriptのexhaustiveness checkをスマートに書く

    TypeScriptではデザインパターンとしてtagged unionによる直和がよく使われます。このときパターンマッチに相当する処理はswitchで行われますが、そこで直和に対する分岐が網羅的であることの保証を実行時と型検査時の両方で賢く行う方法がこれまでも模索されてきました。 今回、ヘルパー関数を導入せずにいくつかの問題を同時に解決する賢い方法を思い付いたので共有します。 コード これだけです。 // switch (action.type) { ... default: throw new Error(`Unknown type: ${(action as { type: "__invalid__" }).type}`); // .. } 以下、より詳しく説明します。 問題 TypeScriptではオブジェクトに type プロパティーを用意し、決まった文字列を入れることで直和を実現

    TypeScriptのexhaustiveness checkをスマートに書く
    kkeisuke
    kkeisuke 2022/08/15
  • Learn CSS学習メモ

    Learn CSS を眺めているので学習メモ。 規格 関連する規格がAll CSS Specificationsにまとまっているので、適宜参照する。CSSCSS2を部分的に置き換える形で定義されているが、そのパッチの一覧をまとめたCSS Snapshot 2021等の文書がある。 ボックスとレイアウトについて 001 Box Model, 008 Layout box modelはCSS2§8を置き換える形でCSS-BOX-3で定義されている。 特にborderの扱いはbackgroundの扱いとあわせてCSS-BACKGROUNDS-3で定義されている。これはCSS2§8.5とCSS2§14.2を置き換える。 フラグメンテーションはCSS2§13.3を大幅に拡張し置き換える形でCSS-BREAK-3で定義されている。 Box modelに関するMDNの入門記事もよくまとまっている。 L

    Learn CSS学習メモ
    kkeisuke
    kkeisuke 2022/04/10
  • 主なNode.js独自API

    // CommonJS Modules の場合 const fs = require("fs"); const fs = require("node:fs"); // ES Modules の場合 import fs from "fs"; import fs from "node:fs"; process のように、グローバル変数としても組み込みモジュールとしても提供されているAPIもあります。 global globalThisの別名です。Webブラウザでは window と self がglobalThisの別名として定義されていますが、Node.jsには window や self はなく、かわりに global が定義されています。 Buffer ArrayBuffer, TypedArray (Uint8Arrayなど), DataView はJavaScriptの標準機能です。

    主なNode.js独自API
    kkeisuke
    kkeisuke 2022/02/26
  • JavaScriptの参照レコードとthisバインディング

    JavaScriptの仕様には「参照レコード」という概念があります。参照を意識することで、JavaScriptにおけるメソッド呼び出しの理解と左辺式の評価順序の理解を同時に深めることができます。稿ではこの「参照レコード」の動機と詳細の説明を試みます。 ※ 記事ではECMAScriptの規格で「参照レコード」と呼ばれている概念を説明します。JavaScriptのオブジェクトは参照渡しのような使い方ができますが、これは稿で説明する「参照」とは少しだけ異なります。 参照レコードの目的 JavaScriptにおける参照レコードは以下の2つの目的で存在しています。 左辺式の中間評価結果を表現するため。 メソッドのレシーバーを決定するため。 左辺式の中間評価結果とは たとえば a[f()] += 2; というコードを考えます。 function f() { console.log("f()");

    JavaScriptの参照レコードとthisバインディング
    kkeisuke
    kkeisuke 2022/02/20
  • Native ESM + TypeScript 拡張子問題: 歯にものが挟まったようなスッキリしない書き流し

    Node.jsのNative ESM対応は夢の機能ですが、夢を詰め込みすぎたせいかCJSからの移行を難しくしているポイントが依然として存在します。そのひとつが拡張子問題で、Node.jsのNative ESMではモジュールの拡張子を明示しなければいけなくなりました。 (これはWebブラウザの挙動に近づけるための判断だと考えられます。) 特にTypeScriptと他のツール (JestやWebpack) と組み合わせて利用している状態でのNative ESM化は実質的に未解決の状態だと言えます。稿ではこの現状についてできる範囲で状況説明を試みます。 Node.jsの拡張子の扱い Node.jsはCJSとESMの2つのモジュールフォーマットをサポートしていますが、これらは単にパーサーが異なるだけではなく、実質的には「2種類の異なるモジュールシステムがFFIで繋がっている」程度には隔たりがあり

    Native ESM + TypeScript 拡張子問題: 歯にものが挟まったようなスッキリしない書き流し
    kkeisuke
    kkeisuke 2022/02/12
  • JavaScriptの演算子の優先順位と「禁止ルール」の一覧

    ただし、種別は以下の通りです。 prefix (前置演算子) …… もとの式の手前に何個でもつけられる演算子。 例: -~-~x postfix (後置演算子) …… もとの式の直後に何個でもつけられる演算子。 例: x.foo()`bar`[0] postfix once …… もとの式の直後に1個だけつけられる演算子。 例: x++ は可能だが x++-- はパースされない。 逆に ++--x はパースされるが、構文とは別のルールで禁止される。 (後述) infixL …… 中置演算子で左結合 (演算子の優先度が同じ場合は左側にあるほうが優先される) 例: 0.1 + 1.0 - 1.0 は (0.1 + 1.0) - 1.0 になる infixR …… 中置演算子で左結合 (演算子の優先度が同じ場合は右側にあるほうが優先される) 例: 2 ** 2 ** 3 は 2 ** (2 **

    JavaScriptの演算子の優先順位と「禁止ルール」の一覧
    kkeisuke
    kkeisuke 2022/02/07
  • JavaScriptのレガシー挙動を定めたAnnex Bをひたすら読む記事

    ECMAScript Annex Bおよび関連する仕様を読みます。 おことわり 言うまでもありませんが、ここで説明されている機能は使わないようにしましょう。 筆者がJavaScriptを書き始めたのは2005年頃で、その後2010年代は実質的な空白期間でした。そのため記事に含まれる歴史的背景の説明は、2005年頃の筆者が学んだ内容に加えて、当時の資料を遡って調査した結果に基づいて記載されています。できる限り信頼性の高い情報を見つけた上で記述するよう心がけましたが、当時常識だった知識の欠落等により不正確な記述になっている部分があるかもしれません。もし誤り等があったら指摘いただけると嬉しいです。 現在のzennでは <sub></sub> や <ins></ins> は描画されていませんが、心の目で下付き文字や下線装飾に読み替えてください。 ECMAScript Annex B とは ECM

    JavaScriptのレガシー挙動を定めたAnnex Bをひたすら読む記事
    kkeisuke
    kkeisuke 2022/01/16
  • TypeScriptのdeclareやinterface Windowを勘で書くのをやめる2022

    おことわり 個々の関数や変数に正しい型をつける話はしません。TypeScript HandbookのDeclarationの章などを読むことをおすすめします。 かわりに、稿では関数や変数の型宣言をどこにどう置くべきかの指針を与えます。 モジュールとスクリプト declareを正しく使うにはまずモジュールとスクリプトの区別を理解し、意識することが大切です。 ブラウザやNode.jsは外部からの指定でモジュールとスクリプトを区別しますが、TypeScriptでは原則としてファイルの内容でモジュールとスクリプトを区別します。 import 宣言または export 宣言が1つ以上あればモジュール。 CommonJSモジュールの場合はTypeScript専用構文である import = 宣言、 export = 宣言を使う。 それ以外の場合はスクリプト。 ただし、JavaScriptファイル (

    TypeScriptのdeclareやinterface Windowを勘で書くのをやめる2022
    kkeisuke
    kkeisuke 2022/01/01
  • Node.jsのネイティブES Modulesサポートが抱える問題を解決するBabelプラグインを書いた

    babel-plugin-node-cjs-interop というパッケージを作ったのでその紹介です。 (GitHub) 何が問題か Node.jsのネイティブES ModulesサポートとBabelやTypeScriptのES Modulesサポートを併用したときに問題が起きます。 ESMとCJS JavaScriptには標準のモジュールシステム (ES Modules, ESM) がありますが、ESMの策定前に先だっていくつかのコミュニティー定義のモジュールシステムが存在していました。そのうちNode.jsを中心として使われていたのがCommonJS Modules (CJS) です。そのNode.js界隈でもESMへの移行が進んでいます。 移行にあたって問題になることのひとつが、ESMとCJSのエクスポートモデルの違いです。 ESMでは、モジュールは0個以上の名前つきエクスポートを定

    Node.jsのネイティブES Modulesサポートが抱える問題を解決するBabelプラグインを書いた
    kkeisuke
    kkeisuke 2021/12/30
  • TypeScriptのJSDocサポートでできること、できないこと

    TypeScriptの主要な入力ファイルは .ts, .tsx, .mts, .cts ですが、JavaScriptファイル (.js, .jsx, .mjs, .cjs) も読み込んで処理することができます。JSDocによる型アノテーションを認識するため、生のJavaScriptでもそれなりに型をつけることができます。 稿ではタイトル通り、TypeScriptJSDocサポートでできることとできないこと (.ts でしかできないこと) をまとめます。 おことわり 記事はTypeScript 4.4時点での実装状況に基づいています。なるべくソースコード中の関係する箇所を参照するようにしたので、今後の変更はご自分で検証してください。 (TypeScript Playgroundで試すだけでも有用です JavaScriptモードで開始できるリンク) JSDocの機能一覧・TypeScri

    TypeScriptのJSDocサポートでできること、できないこと
    kkeisuke
    kkeisuke 2021/11/10
  • JavaScriptの非同期処理をじっくり理解する (1) 実行モデルとタスクキュー

    対象読者と目的 非同期処理の実装方法は知っているが、仕組みを詳しく知らないのでベストプラクティスがわからないときがある 実行順序の保証がよくわからないので自信をもってデプロイできない変更がある より詳しい仕組みを理解することでより計画的な実装をできるようになりたい という動機で書かれた記事です。同様の課題を抱える人を対象読者として想定しています。 目次 実行モデルとタスクキュー Promise async/await AbortSignal, Event, Async Context WHATWG Streams / Node.js Streams (執筆中) 未定 入門記事へのリンク プロミスの使用 - JavaScript | MDN Promise, async/await (現代の JavaScript チュートリアル) JSの初心者にPromiseとasync/awaitの使い方

    JavaScriptの非同期処理をじっくり理解する (1) 実行モデルとタスクキュー
    kkeisuke
    kkeisuke 2021/09/25
  • JavaScriptのIterator / Generatorの整理

    目的と対象読者 IteratorとIterableとGeneratorとGenerator Functionの区別が曖昧な人 (記事前半) Generatorの制御フローを完全理解したい人 (記事後半) の理解を深めるための記事です。 まとめ IteratorとIterableの関係 Iteratorは狭義には呼び出し元の next 呼び出しに応じて要素を出力するインターフェースである。 IterableはIteratorを生成するインターフェースである。 IterableだからといってIteratorとは限らず、IteratorだからといってIterableとは限らない。しかし実際には多くのIteratorはIterableのインターフェースも実装している。 Iterableとコレクションは相互変換可能である。 Iterableは for-of ループで処理できる。 IteratorとG

    JavaScriptのIterator / Generatorの整理
    kkeisuke
    kkeisuke 2021/09/05
  • CORSの仕様はなぜ複雑なのか

    Webアプリケーションを実装していると高確率で CORS の問題にぶつかります。CORSがどのようなものかはリンクしたMDNなど既存の解説を読むのが手っ取り早いと思いますが、「なぜそのように設計されたのか」という観点での説明はあまり見ないため、昔の資料の記述や現在の仕様からの推測をもとに整理してみました。 CORSとは 現代のWebはドメイン名をもとにした オリジン (Origin) という概念 (RFC 6454) をもとに権限管理とアクセス制御を行っています。その基となるのが以下のルールです。 Same-origin policy (同一生成元ポリシー): 同じオリジンに由来するリソースだけを制御できる。 上記Wikipedia記事によるとSOPの概念は1995年のNetscape 2.02に導入されたのが最初のようです。当時のドキュメンテーションを読む限り、これはウインドウ越しに別

    CORSの仕様はなぜ複雑なのか
    kkeisuke
    kkeisuke 2021/07/31
  • Array.prototype[@@iterator] ←この @@ って何?

    MDNにはたまにアットマークを2つ並べた @@ という記法が登場します。 Array.prototype[@@iterator]() The @@iterator method is part of The iterable protocol, that defines how to synchronously iterate over a sequence of values. しかし、この記法をそのままJavaScriptTypeScriptの処理系に入力しても構文エラーになります。 console.log(Array.prototype[@@iterator]()); // => Uncaught SyntaxError: Invalid or unexpected token ではこの @@ はどこから来て、何を意味する記法なのでしょうか。 結論 これはドキュメント用のwell-

    Array.prototype[@@iterator] ←この @@ って何?
    kkeisuke
    kkeisuke 2021/01/11
  • Mapped Typesのあれこれ

    Mapped Typesの基Mapped Typesの基形は { [P in K]: T } です。 P は T の中で使える型変数です。このとき、 P はこのMapped Typeの引数型 (parameter type) K はこのMapped Typeの制約型 (constraint type) T はこのMapped Typeのテンプレート型 (template type) と呼びます。 T の中で P がどのように振る舞うかに注目すると type Element<P extends K> = T; という形の定義と相似であることから、P が引数型、 K が制約型と呼ばれる理由がうかがえるかと思います。 Mapped Typesの基形で、 T が P に依存しないケースには Record<K, T> という名前がついています。 type Record<K extends

    Mapped Typesのあれこれ
    kkeisuke
    kkeisuke 2021/01/10
  • TypeScriptにはanyが4種類、undefinedが3種類、……

    このツイートの解説をします。 TypeScriptにはanyは4種類、undefinedは3種類、nullは2種類、trueは2種類、falseは2種類、neverは5種類あるのか。普通に使ってる分にはわからないが…… TypeScriptでは表面上は同じ名前でも内部的に異なる型が割り振られている場合がいくつかあります。そのようなもののうち、プリミティブな型についてまとめました。 対象TypeScriptバージョンは4.1.3です。 2021-01-09 update: 数え方を見直しました。 any が4種類から6種類に増えました。 注意 ここに書かれていることを知らなくても、TypeScriptプログラミングにおいて全く困りません。あくまでコンパイラの機微を楽しむつもりでお読みください。 前提知識 any, undefined, null, true, false, never 型につ

    TypeScriptにはanyが4種類、undefinedが3種類、……
    kkeisuke
    kkeisuke 2021/01/02