1
TYPESCRIPT による
今風の
WEB アプリ開発by 陣内靖(じんのうちやすし)
@delphinus35
2
TYPESCRIPT とは……
次世代JS - ECMAScript2015 の上位互換+ 型
Microsoft 製
オープンソース
各種エディタのサポートが充実
MS 製だけどVisual Studio は別に必要ない。
IntelliSense 並みのコード補完を実現するための仕組み
が附属。
Vim でも補完できる!
3
ECMASCRIPT2015 で
追加された文法
Class & Module
Arrow Function ()=>{}
Block Scope Variables let,const
Rest / Spread Parameters (a,b,...args)=>{}
New Object Literals {some,more,props}
Map / Set, Promise, Generator, Symbol, ...
今後まだまだ増える予定(ES2017 以降?)
Decorator, async / await, ...
4
MODULE LOADING
some_module.js
exportconsthoge="ほげ";
exportfunctionfuga{console.log("ふが");}
app.js
import{hoge,fuga}from"./some_module";
console.log(hoge);
fuga();
5
今までのJS はモジュールという概念がなかった。
変数のスコープは関数スコープのみ。
function(){varhoge;}
複数のファイルで変数・関数を共有したいと思ったらグ
ローバル汚染するしかなかった。
ブラウザーならwindow.hoge="ほげ"
グローバル汚染せずに複数ファイルに分けて開発が可能
になった!
他の言語なら当たり前の機能がやっと……!
6
TYPESCRIPT はES2015 + 型lethoge:string="ほげ";
//hoge=1;#=>型が stringでないのでエラー!
//オリジナルの型を定義できる
typeLogLevel="debug"|"info"|"warn"|"error"|"fatal";
functionlog(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のインストール
npminstall-DEjquery
10
ツールはグローバルに
インストールしない
今まではgulp やtypescript 等の関連ツールをグローバル
にインストールして使ってた。
これだと各人が入れたバージョンを管理できない><
ビルドした結果が違うと開発に齟齬を来す。
npminstall-gtypescript
#/usr/local/bin/typescriptに入る
11
各種ツールはNPM 経由で実行
ツールのインストール先はプロジェクトローカル。
gulp やbrowserify 等のツールも全部npm 経由で実行す
る。
package.jsonにタスクを書いて、npmrunで実行。
こうすると、必ずプロジェクトにローカルなバージョン
に固定されるので開発者も戸惑わない。
npminstall-DEgulp
#node_modules/.bin/gulpに入る
npmstart #gulp起動
npmrunbuild #TSをコンパイル &browserify
npmrunclean #ビルド済みのファイルを削除
npmruntslint #TSの文法チェック
npmruntypedoc #ドキュメント作成
...
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
BROWSERIFY
browserifymyapp.js>bundle.js
BEFORE
<scriptsrc="http://example.com/jquery.min.js"></script>
<scriptsrc="http://example.com/underscore.min.js"></script>
<scriptsrc="http://example.com/backbone.min.js"></script>
<scriptsrc="http://example.com/bootstrap.min.js"></script>
<scriptsrc="http://example.com/myapp.js"></script>
AFTER
<scriptsrc="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<{}>=>{
constlevel="fatal";
return$.post("/log",{level,message});
};
//他にも Logger.infoとか Logger.debugとか……
でもこれだと、どこでログを吐いたのか分からない。
(´・ω・`)
27
STACKTRACE-JS
https://github.com/stacktracejs/stacktrace.js
//logger.ts
Logger.fatal=(message:string):Promise<{}>=>{
constlevel="fatal";
returnStackTrace
.get()
.then((stackframes:StackTrace.StackFrame[])=>
Promise.resolve(
$.post("/log",{level,message,stackframes})
)
);
};
//hogehoge.ts
exportclasshoge{
fuga(){
Logger.fatal("ERROR!!!");
}
}
28
スタックトレースが取れるスゴイやつ。
Perl とかRuby のcallerみたいなの。
なんでこんな基本的なものがJS には標準でないの
(怒)
Promiseを返すことから分かるように、非同期に動作す
る。
ソースマップなどを加味して分かりやすいログを吐いて
くれるけど、結構重い。
複数のスタックトレースを同時に生成しようとすると
うまく吐けない。
29
まとめJS 界隈は常に勉強して(≒空気を読んで)行かないとす
ぐにおいて行かれる。
Rails のような頼れる存在はいないので自分で道を切り開
く必要がある。
30
メリット
スゴイ勉強になる(意識高い感)
何もないからこそ、自分の思い通りに作れる万能感。
デメリット
使ってるプロダクトがすぐオワコン化する。
書いたソースがすぐ暗黒化する。
一年後の自分ですらメンテできない。
ドキュメント大事!!!
31
終わり超便利!reveal.js
初めに戻る

TypeScript による今風の web アプリ開発