TypeScript のパースに Babel を使う
2018/07/03 
ソースコードのふりがな生成で TypeScript にもふりがなを振れないかと思って調べたメモ
TypeScript
MS を中心に開発しているオープンソースな言語
通常は
tsc
(TypeScript Compiler)でコンパイル(→JavaScript)するBabel 7 からBabel が TypeScript をパースできるようになった
babe-plugin-transform-typescript
babel-preset-typescript
も提供されている オプションによって
typescript
, jsxPragma
, TSX
のプラグインが入ったり入らなかったりする とくに
jsxPragma
などが必要なければ babel-plugin-transform-typescript
だけ入れれば良い babel-preset-es2015
のように「たくさんのプラグインをまとめたもの」ではないTypeScript をサポートしよう
babel-types
に TypeScript の型定義の実装がある TS~ から始まる型定義がたくさんある
よく見たら
@types/babel-types
に全部入ってた!? 全部コピーしたつもりだったのに、抜けていたらしい
これをふりがな生成の Visitor 関数リストに追加すれば辞書を作れる
とりあえずパースできれば一応 TypeScript でも動くことにはなる
その場合は
enum
とかアノテーションとかが無視されるはず Issue の流れを軽く読んだ感じだと、キッカケは@drosenwasser(TypeScript Program Manager)達とのやりとり
それとは別の流れとして、 ESLint チームはこれまで独自に TypeScript サポートを行ってきた
TypeScript →
typescript-eslint-parser
→ ESTree → ESLint ルールで構文チェック、という流れ TSLint というのもあるのだが、そっちは微妙らしい
TypeScriptのLinterはTSLintがデファクトだが、TSLintはESLintと比べて実装されているルールがだいぶ少なかったり、同じルールでも名前が違ったりする。
この手のツールは時代を追っかけながらコミットし続けて行く必要があるので、注目度の高さがツールのクオリティに直結するのだろう。ESLint の方が歴史も長く利用者も圧倒的に多い
つまり TypeScript の構文エラーを見つけるために、TypeScript のパーサの実装が進められていた
#320 で@JamesHenry(MVP of TypeScript)が
typescript-eslint-parser
について言及している ... just wanted to note in advance that it would be great to avoid duplicating the efforts we have already made on https://github.com/eslint/typescript-eslint-parser, ...
@JamesHenryは ESLint のコミッターでもあり、パーサの実装について Slack にまとめたとも発言している
Babel 6 以前で Babylon は ESTree を読んだり書いたりできなかった(?)
@danezがそれをできるようにした(?)
このPRによって
typescript-eslint-parser
と連携できるようになり、Babel の骨子を保ったまま、TypeScript のサポートが可能になった(たぶん) 「我々のチームはメンテするリソースを持っていない」と言いながらもこれだけのことを半年足らずでやってのける
むしろリソースの限られた戦い方をしているからこそ Babel はスケールしたのかも知れない
2018/07/05
babel-types に書いてあった名前を全部 Visitor 関数に突っ込んでみた
謎のランタイムエラーが出た
real-example.js
/Users/teramotodaiki/github/transform-jp/node_modules/babel-traverse/lib/path/context.js:57
Rejected promise returned by test. Reason:
TypeError {
message: `enter(path, state) {␊
const { line, column } = path.node.loc.start;␊
set(state, line, column, '別の場所からとってこい');␊
} is not iterable!`,
}
NodePath._call (node_modules/babel-traverse/lib/path/context.js:57:135)
NodePath.call (node_modules/babel-traverse/lib/path/context.js:48:17)
NodePath.visit (node_modules/babel-traverse/lib/path/context.js:105:12)
TraversalContext.visitQueue (node_modules/babel-traverse/lib/context.js:150:16)
TraversalContext.visitMultiple (node_modules/babel-traverse/lib/context.js:103:17)
TraversalContext.visit (node_modules/babel-traverse/lib/context.js:190:19)
Function.traverse.node (node_modules/babel-traverse/lib/index.js:114:17)
NodePath.visit (node_modules/babel-traverse/lib/path/context.js:115:19)
TraversalContext.visitQueue (node_modules/babel-traverse/lib/context.js:150:16)