Download - TypeScript による今風の web アプリ開発
2
TYPESCRIPT とは……次世代 JS - ECMAScript2015 の上位互換 + 型Microsoft 製オープンソース各種エディタのサポートが充実
MS 製だけど Visual Studio は別に必要ない。IntelliSense 並みのコード補完を実現するための仕組みが附属。
Vim でも補完できる!
3
ECMASCRIPT2015 で追加された文法
Class & ModuleArrow Function () => {}Block Scope Variables let, constRest / Spread Parameters (a, b, ...args) => {}New Object Literals {some, more, props}Map / Set, Promise, Generator, Symbol, ...今後まだまだ増える予定(ES2017 以降?)
Decorator, async / await, ...
4
MODULE LOADINGsome_module.js
export const hoge = "ほげ"; export function fuga { console.log("ふが"); }
app.jsimport {hoge, fuga} from "./some_module";
console.log(hoge); fuga();
5
今までの JS はモジュールという概念がなかった。変数のスコープは関数スコープのみ。function(){ var hoge; }
複数のファイルで変数・関数を共有したいと思ったらグローバル汚染するしかなかった。ブラウザーなら window.hoge = "ほげ"
グローバル汚染せずに複数ファイルに分けて開発が可能になった!他の言語なら当たり前の機能がやっと……!
6
TYPESCRIPT は ES2015 + 型let hoge: string = "ほげ";
// hoge = 1; #=> 型が string でないのでエラー!
// オリジナルの型を定義できる type LogLevel = "debug" | "info" | "warn" | "error" | "fatal";
function log(level: LogLevel, message: string) { console.log(̀[${level}] ${message}̀); }
// log("waaarn", "fugafuga"); // #=> 第1引数の型が LogLevel と合致しないのでエラー!
7
コンパイル時にエラーを見つけてくれる。とかくフリーダムになりがちな JavaScript では凄く助かる。今回のプロジェクトではテストとかないのに、コンパイル通ったら一発で動いた!スゴイ!テストは書くべきだけどね……(結局書いてない)
8
実践TypeScript を Rails プロジェクトで使ってみた。その中で遭遇した諸々。
9
既存ライブラリーはNPM で管理
jQuery とか underscore.js とかいろいろ使いたいときもある。
大体のライブラリーは に登録してあるし、してないものは github から直で入れる。
bower? 何それ (^q^)
npm
# jQuery のインストール npm install -DE jquery
10
ツールはグローバルにインストールしない
今までは gulp や typescript 等の関連ツールをグローバルにインストールして使ってた。
これだと各人が入れたバージョンを管理できない><ビルドした結果が違うと開発に齟齬を来す。
npm install -g typescript # /usr/local/bin/typescript に入る
11
各種ツールは NPM 経由で実行ツールのインストール先はプロジェクトローカル。
gulp や browserify 等のツールも全部 npm 経由で実行する。package.json にタスクを書いて、npm run で実行。
こうすると、必ずプロジェクトにローカルなバージョンに固定されるので開発者も戸惑わない。
npm install -DE gulp # node_modules/.bin/gulp に入る
npm start # gulp 起動 npm run build # TS をコンパイル & browserify npm run clean # ビルド済みのファイルを削除 npm run tslint # TS の文法チェック npm run typedoc # ドキュメント作成 ...
12
パッケージのバージョン管理
各人の環境で、jQuery その他のライブラリや、TypeScript や gulp 等のツール類もバージョンを揃える必要がある。package.json と npm-shrinkwrap.json で可能。
Ruby で言うなら Gemfile.lock みたいなもの。
13
再び TYPESCRIPT の話
14
既存の JS ライブラリと共存する
最初から TypeScript で書いてあるライブラリなんてほとんどない。jQuery プラグインとか使いたい!それ、型定義ファイルでできるよ。
15
型定義ファイル既存のライブラリーが export する関数・変数などについての型情報が書いてある。メジャーなライブラリーについては に揃ってる。メジャーじゃないものは……自分で書くしかない。
De�nitelyTyped
16
書いてみた例
使用例 jquery-easy-loading.d.ts
17
書いてみた結果……型定義ファイルを書くためにはライブラリーのソースを読んで理解しないといけない。ドキュメントに返値の型までちゃんと書いてあれば楽
なんだけどね……結構大変だけど書かないと開発始められない。全部 any 型にキャストすれば何とかならんでもない。
既存のライブラリーを使いたいときはこのコストとのトレードオフ。
18
複数ファイルをまとめる(TypeScript でも)複数ファイルでアプリを構成することはできるが、<script> をたくさん書くとパフォーマンス的にアレ。複数のモジュールを一つにまとめ、場合によっては難読化する。
19
BROWSERIFYbrowserify myapp.js > bundle.js
BEFORE<script src="http://example.com/jquery.min.js"></script> <script src="http://example.com/underscore.min.js"></script> <script src="http://example.com/backbone.min.js"></script> <script src="http://example.com/bootstrap.min.js"></script> <script src="http://example.com/myapp.js"></script>
AFTER<script src="http://example.com/bundle.js"></script>
ファイルサイズは相当でかくなるけどね。
20
RAILS のアセットパイプライン
アセットパイプラインとは……
簡単に言うと、複数の JS, CSS を連結・圧縮してくれる便利機能。Coffee や Sass からの透過的な変換もやってくれる。スーパー便利すぎるが故に闇が深い><
アセットパイプライン | Rails日本語ドキュメント |Ruby STUDIO
21
アセットパイプラインと共存する
Sprockets(アセット(略)の主要 gem)を全部JavaScript で置き換えてしまった が、ここまでやるのは大変。折衷案として、browserify でビルドした一つの JS をpublic/assets に置く。app/assets/javascripts は無視
パッケージによっては個別の CSS / img が必要なこともある。(bootstrap とか)これらは app/assets/... に手でコピーしてアセットパイプラインに載せる。
スゴイ人も居る
22
タスクの自動化定型タスクを自動化する。
TypeScript をコンパイル。複数ファイルをビルドしてまとめる。(必要なら)難読化する。(必要なら)スクリプトを所定の場所に移動する。などなど……
gulp がデファクトスタンダード。Grunt? 何それ (^q^)
JS 界はこんなんばっかり……
23
GULP定型タスクの例
// JS の文法チェックを eslint で行う gulp.task( 'eslint', () => gulp.src('gulp/**/*.js') .pipe(plumber({errorHandler: handleErrors})) .pipe(eslint()) .pipe(eslint.failOnError()) .pipe(plumber.stop()) );
24
だいぶ秘伝のタレ化してしまった。プロジェクト固有のバッドノウハウの固まりなので一般
化できない。メンテもしにくい。せめて ES2015 で書いて eslint かけることで品質を担保。gulp 自体バージョン変わると文法もごりごり変わるし、プロダクト自体すぐにオワコン化する。Grunt ェ……
この辺はホント JS キツイ。根本的な解決策は今のところない。
25
フロントエンドのログを取りたい!
普通の Web アプリなら console.log() で十分。でも WebView で表示してるときのログは見れない。本番環境ではユーザーの端末で致命的なエラーが起こったときに教えて欲しい。
26
ログをバックエンドに送るモジュールを書く
Logger.fatal = (message: string): JQueryPromise<{}> => { const level = "fatal"; return $.post("/log", {level, message}); };
// 他にも Logger.info とか Logger.debug とか……
でもこれだと、どこでログを吐いたのか分からない。(´・ω・`)
27
STACKTRACE-JShttps://github.com/stacktracejs/stacktrace.js
// logger.ts Logger.fatal = (message: string): Promise<{}> => { const level = "fatal"; return StackTrace .get() .then((stackframes: StackTrace.StackFrame[]) => Promise.resolve( $.post("/log", {level, message, stackframes}) ) ); };
// hogehoge.ts export class hoge { fuga() { Logger.fatal("ERROR!!!"); } }
28
スタックトレースが取れるスゴイやつ。Perl とか Ruby の caller みたいなの。なんでこんな基本的なものが JS には標準でないの(怒)
Promise を返すことから分かるように、非同期に動作する。ソースマップなどを加味して分かりやすいログを吐いてくれるけど、結構重い。複数のスタックトレースを同時に生成しようとするとうまく吐けない。
29
まとめJS 界隈は常に勉強して(≒空気を読んで)行かないとすぐにおいて行かれる。Rails のような頼れる存在はいないので自分で道を切り開く必要がある。
30
メリット
スゴイ勉強になる(意識高い感)何もないからこそ、自分の思い通りに作れる万能感。
デメリット
使ってるプロダクトがすぐオワコン化する。書いたソースがすぐ暗黒化する。一年後の自分ですらメンテできない。
ドキュメント大事!!!