外部ライブラリもインストール・型解釈できる TypeScript playground を作った

俺得フロントエンド (1) LT 会
Leko

About me

Node.js, React, React Native
言語の中身読んだり AST 解析で遊ぶのが好き

本日話すこと

  • 俺が得するからやったこと
  • みんなの役に立つこと(になってほしい)

TypeScript playground(公式)

  • https://www.typescriptlang.org/play/
  • ブラウザだけで完結するTypeScriptのPlayground
  • ちょっとコード書いて型を試すのに便利
  • transpile結果も簡単に確認できる
  • シェア機能で型パズルの出題やTipsの共有も便利

いくつかの設定もトグル可能

型周りもうひと押しほしい 🤔

  • npmモジュール(@types etc)も絡めて型を確かめたいことがある

    • React, redux, reselect etc
  • tsconfig.jsonを直接いじりたい、それもシェアされてほしい

非公式TypeScript playgroundを作った

  • https://playground.type-puzzle.org
  • 型のチェックだけ、実行はできない
  • @typesやTS製npmモジュールをインストールし型解釈できる
  • tsconfig.jsonをフル※カスタマイズ可能

使用例

live demo

内部技術ピックアップ

  • monaco-editor 内部の TypeScript の LanguageService
  • monaco-editor に npm パッケージの型定義を読み込ませる
  • npm パッケージの検索
  • npm パッケージ(型定義ファイル)のインストール

monaco-editor と TypeScript

  • microsoft/monaco-typescript
  • monaco-editor(以下monaco)にはブラウザ用にインターフェースを実装したts LanguageServiceが入っている
  • monaco.Uriで仮想的なfileプロトコルをしゃべれる

npm moduleのインストール

参考実装

Babel repl

Algolia

高速でフルマネージドな全文検索エンジン(のWebサービス)

  • algolia/npm-search

    • npm registryのレプリカをAlgoliaに構築
  • algolia/instant-search

    • AlgoliaのAPIクライアント + UI
    • 多くのOSSのドキュメントのサイト内検索もこれ
  • とても高速。大量のレコード管理はちょっとお高い

npm Public Registry API

npm/registry

(Archiveされてるけど)npm registryのAPIドキュメント

おおまかな実装方針

  1. 何かしらのAPIでnpmパッケージを検索
  2. 選択されたパッケージのtarballをnpm registryからfetchし解凍
  3. package.jsonを読み依存ツリーを全探索
  4. monacoに読み込ませる

tarballとCORSの壁

— add support for CORS headers · Issue #108 · npm/npm-registry-couchapp

monaco に npm moduleの型を読ませる

  • 編集中のコードの仮想的なパスを指定(ex. /index.tsx)
  • .d.tsのコード(string)を手に入れる
  • 型解釈されるように配置(ex. /node_modules/xxx/index.d.ts)

任意のnpmモジュールのimportが型解釈が可能に!

詳細な仕様はTypeScript handbookやDefinitelyTypedのREADMEを参照

ハードコードして動かした図

UNPKG

https://unpkg.com
{package}@{version}/{path}→npm publishされたファイルの中身

  • かゆいところに手が届く機能いろいろ
  • CDNが手前にあるのでとても高速
  • CORSいける

— CDN Links – React

パッケージの中身の取得

API for Retrieving Package Tarball · Issue #69 · unpkg/unpkg.com

  • unpkg.comではパッケージ内の全ファイル一覧を取れる
  • 不要なファイルも取得するので遅いがパス解決不要

ServiceWorker runtime cachingである程度効率化できる

"依存pkgの依存pkg"のバージョン解決

UNPKGがsemverを解決してリダイレクトしてくれる

  • @types/react/

    • index.d.ts
    • node_modules/csstype/index.d.ts

ServiceWorker runtime caching

  • 🙈: .../@types/react@~16.7.0/...
  • 🙈: .../@types/react@^16.7.0/...
  • 👀: .../@types/react@16.7.22/...

他に使ってる技術

  • ブラウザでgzipかけてURLを圧縮・解凍
  • comlink-workerでのお手軽off the main thread

今後

  • Hooks 版 react-redux 使ってみよう
  • フィードバックもらって完成度あげたい
  • import のパスやパッケージ名の補完が効くように
    - 本家monaco-typescriptのCompletionProviderを改善したい
  • 公式 playground に還元したい

得してほしい情報

  • monacoとTypeScriptの成熟によりブラウザエディタが(私の中で)アツい
  • UNPKGは開発用途で可能性感じる
  • ちょっと複雑な型遊びがしたかったら、

https://playground.type-puzzle.org

Thanks

https://playground.type-puzzle.org
※"react"ではなく"@types/react"のインストールが必要です
※TS製パッケージや.d.tsが配布されてるパッケージはそのまま名前でOK

リポジトリ: Leko/type-puzzle