bouzuya.hatenablog.com

ぼうずやのにっき

TypeScript で Twitter に投稿する bouzuya/bbn-tt をつくった

2016 年最初の RALLY の release ではなく、 2016-01-06 につくった bouzuya/bbn-tt のことを書く。

bouzuya/bbn-tt は指定した値に Twitter の status を変更する script 。2016-01-06 に書いた bouzuya/bbn-t と同じものだ。 bouzuya/bbn-tbouzuya/bbn-tt は別物だ。 typo ではない。TypeScript の t を足している。

今回の目的は 2016-01-06 で諦めた TypeScript 利用の再挑戦だ。

実装は TypeScript で書かれており Node.js で動く。npm package "twitter" を利用している。言語が CoffeeScript → TypeScript である点を除けばほとんど同じものだ。

TypeScript および es6 module style を選択していることで tsd や babel を併用することになっている。

tsd は .d.ts (declaration source file) を取得するための command-line tool だ。.d.ts が bundle されるものが増えれば tsd は不要になっていくだろう。tsd の難点は command-line option が分かりにくいことだと思う。$ tsd query <package> --save --resolve --action install をまどろっこしいと感じる。

babel は es2015 から es5 に変換するための transpiler 。 TypeScript の出力する es6 を Node.js が完全には解釈できないために利用している。TypeScript に commonjs 形式で出力しても module 以外の部分で動かないことがあるので諦めて babel を噛ませている。

babel 5 から 6 に移ってから分かりにくくなった。

各種機能の npm package が分離されて plugin 化されたのはひとつの理由だ。それぞれを把握していればいいのだけど、ぼくは把握できていないので分かりづらい。具体例を挙げる。 $ npm install --save-dev babel-cli babel-preset-es2015 で install する。 $ $(npm bin)/babel --preset es2015 --out-dir lib/ src/ で変換する。以前は不要だった option が必要になった。

また破壊的変更をいくつか含んでいる。export default の扱いがそうだ。

// foo.js
export default function(x, y) {
  return x + y;
};
// bar.js
const foo = require('./foo').default; // { default: [Function] } になる

// hoge.js
const hoge = {};
export default hoge; // これは許されない例
// ... ここで hoge.piyo を追加する

// fuga.js
const { piyo } = require('./hoge');

この変更は es6 modules が export を動的に書き換えることを許さないのを考慮したものだ。

However, because the ES6 specification states that imports and exports must be statically analyzable, you can’t accomplish this dynamic behavior in ES6.

この変更が問題になるのは Node.js require と es6 module を併用する場面だ。TypeScript で npm package を書いて、JavaScript から利用すればこの問題に直面する。今回は /bin/bbn-tt から /lib/index.js を呼び出す際に発生した。

tsd / babel についてはひとまずこれくらい。

2016-01-06 の 'Cannot find module "twitter"' 問題に改めて挑戦したところ原因は tsd twitter/twitter.d.ts が npm package "twitter" のための declaration source file (*.d.ts) ではないことだった。.d.ts を読んでいれば気づいたのだけど……。そこで必要十分な declaration source file を自作した。どこに配置するのが良いのか分からなかったので tsd.d.ts にした。tsd で install した .d.ts をまとめるもののようなので、適当な配置ではなさそうだけど、ひとまず動いた。

今年はなるべく CoffeeScript から TypeScript にしていく。理想は CoffeeScript like な syntax で TypeScript を使いたいのだけど……。