この記事は ionic + TypeScriptで今風な開発フローを実現 の第1回にあたります!他の記事は↓です。
- ionic + TypeScript で今風な開発フローを実現【導入編】
- ionic + TypeScript で今風な開発フローを実現【型定義ファイル活用編】
- ionic + TypeScript で今風な開発フローを実現【module, concat編】
- ionic + TypeScript で今風な開発フローを実現【sourcemap編】
- ionic + TypeScript で今風な開発フローを実現【TypeScript編】
JavascripterからTypescripterとそろそろ言ってもいいかなって最近ちょっと思えるくらいTypeScriptを使っているKENです。色々なメディアを見ていてもどんどん脚光を浴びているTypeScript。.NETを割とがっつりやっていてよかったなぁ、と思っています。
さて、TypeScriptをしばらく触っていると生の、しかもES5以下のJavaScriptでがっつりSPAを書こうとは思えなくなってきます。一人だったらいいですけど、チームで1kステップを余裕で超えるソースの山を凡ミス無しでメンテしていける自信が無くなってきます。特に、イケてないメソッド名とかクラス名作ったときに、後からリファクタできる容易さは本当に神がかり的です。VSCodeとかならF2をポチッとな。JetBrains系ならShift+F6をポチッとなで変えれるようになりますからね。と、長い前置きはここまでとして、最近がっつり触っている ionic 。これも流れ的にTypeScriptで書きたくなってきます。この記事では ionic start <プロジェクト名>
で作ったプロジェクトをTypeScriptに移行する方法を載せたいと思います。 TypeScript -> JavaScript に簡単に transpile するのには webpack の力を借りたいと思います。
ionic
をインストールしているものとして話を進めます。ちなみに執筆時点での ionic info
は↓です。
1 2 3 4 5 6 7 8 9 10 11 |
Cordova CLI: 6.0.0 Gulp version: CLI version 3.9.0 Gulp local: Ionic CLI Version: 1.7.14 Ionic App Lib Version: 0.7.0 ios-deploy version: 1.8.5 ios-sim version: 5.0.6 OS: Mac OS X El Capitan Node Version: v0.12.5 Xcode version: Xcode 7.2.1 Build version 7C1002 |
普通の ionic
のアーキテクチャは↓のようなイメージですが
今回 TypeScript
を入れることで↓のようなイメージに変身する予定です!
プロジェクト作成
まずはプロジェクトを作りましょう!
1 2 3 |
# プロジェクト名は自由です ionic start ionic-typescript |
↓こんなこと聞かれますけど、今回は必要ないので n
で!
1 2 3 |
Create an ionic.io account to send Push Notifications and use the Ionic View app? (Y/n):n |
作ったプロジェクトのフォルダに移動しましょう。
1 2 |
cd ionic-typescript |
とりあえずプロジェクトが開始できるかお試し。
1 2 3 |
# ブラウザでionicアプリを起動します ionic serve |
ブラウザが起動して↓のような画面が出てきたらOKです!
フォルダ構成の変更
作りたてのプロジェクトのフォルダ構成は↓のような状態だと思います。
TypeScriptを使うと TypeScript -> JavaScript という transpile のフローが必要になるので、標準のJSの置き場所である www/js
とは別の場所でTS(TypeScriptファイル)を管理していきます。今回は src/app
配下にTSファイルを置くことにします。さらに transpile するときには今割りとホットな webpack を使います。 いままで と これから のイメージの違いは↓のようになります。
さて、まずはファイルの引っ越しをしましょう!これをすると当然ですけど一時的にプロジェクトは壊れて動かなくなります!以下、コマンドを載せますけどGUIでやっても全然OK。
1 2 3 4 5 6 7 8 9 10 11 12 |
# 引っ越し先のフォルダを準備 mkdir -p src/app # 既存のJSファイルを引っ越し mv www/js/* src/app/. # ↓になっているはず src/app ├── app.js ├── controllers.js └── services.js |
Javascript -> TypeScript変換
拡張子変換
引っ越しが完了したところで、JSファイルをTSファイルに変換します!TypeScriptはJavascriptの Superset なので、JavaScriptはTypeScriptなのです!なので、拡張子を変換しただけで一応TypeScriptに変換が完了した、と言ってもOK。
1 2 3 4 |
# ↑のmvの際にやってもよかったんですけど、一応順番に、ということで。 # これはとりあえず.jsを.tsに拡張子変換してくれるおまじないだと思って下さい。 for f in src/app/*.js; do mv $f src/app/`basename $f .js`.ts; done; |
webpackによるtranspile
前準備
拡張子だけ変換したって何もうれしいことは無いので、 webpack を使っていろいろとごにょごにょします。 webpack 自体はかなり様々なことができるんですけど、今回は主に transpile の部分だけお願いをします。
まずは webpack をインストールしましょう。
1 2 3 |
# アプリが直接使うライブラリではないのでdevのインストールとします npm install --save-dev webpack |
webpack で TypeScript -> JavaScript するために awesome-typescript-loader
を使います。 loader
という概念は webpack で超重要なんですけど、とりあえずは「なんか色々と変換してくれる人」って覚えてくれてて良いと思います。 awesome-typescript-loader
をインストールしましょう。
1 2 |
npm install --save-dev awesome-typescript-loader |
さらにtranspileに必要なので TypeScript 自身もインストールしておきます。
1 2 |
npm install --save-dev typescript |
webpack.configの作成
さて、 webpack がお仕事をする為には config ファイルを準備してあげる必要があります。開発をしていく上でこの config ファイルがいくつかあると便利なので、 webpack
というフォルダの中で管理します。 config ファイルは webpack.dev.js
とでも命名しておきましょう。
1 2 3 4 5 6 |
# フォルダ作って mkdir webpack # configファイル作っておく touch webpack/webpack.dev.js |
webpack/webpack.dev.js
ファイルの中身は以下のようにしておきます。好きなエディタで編集して保存してください。 webpack の詳細については触れません(奥が深いので)。この webpack/webpack.dev.js
についてのポイントとしては、 entry:
で指定されているファイルをエントリポイントとして、 awesome-typescript-loader
を介して TypeScript -> JavaScript を実現して、完成したファイルの出力先は output:
で定義されている場所にしますよ、って内容です(ざっくり!)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
var webpack = require('webpack'); module.exports = { entry: { app: './src/app/app.ts', controllers: './src/app/controllers.ts', services: './src/app/services.ts' }, output: { filename: '[name].js', path: './www/js' }, resolve: { extensions: ['', '.ts'] }, plugins: [], module: { loaders: [ { test: /\.ts$/, exclude: /node_modules/, loaders: ['awesome-typescript-loader'] } ] } }; |
tsconfig.jsonの作成
↑の手順で一通り完成!と言いたいところですが、今度はTypeScriptのコンパイラに対して、TypeScriptをどうやってコンパイル(transpile)するのか教えてあげないといけません。このために tsconfig.json
ファイルを作成します。tsconfig.json
に渡せるcompilerOptions
一覧はこちら参照。
1 2 3 |
# とりあえずファイル作成 touch tsconfig.json |
tsconfig.json
の中身は↓のようにします。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
{ "compilerOptions": { "target": "es5", "module": "commonjs" }, "exclude": [ "node_modules", "bower_components", "www/lib", "platforms" ] } |
コンパイル!(transpile)
役者が(だいたい)揃ったところで、とりあえずコンパイルしてみましょう!そのためには npm scripts
を使います。「え?gulpじゃないの?」と思うかもしれませんけど、 ionic
はあらかじめ十分にいろいろとコマンドが用意されているので、 gulp
のレイヤを追加するより、npm scripts
で単純にコマンドを並べてしまったほうがわかりやすいと私は思っています。
では package.json
に↓を追加します!
1 2 3 4 |
"scripts": { "watch": "webpack --config webpack/webpack.dev.js --watch" } |
これは単純に webpack
のコマンドを叩いているだけです! npm scripts
なら node_modules
配下のコマンドをそのまま使える(パスが通っている)ので便利!それでは実際にこれを使いましょう!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
# ↓package.jsonのscripts内のwatchコマンド実行するという意味 npm run watch # ↓こんな感じなものが出力されたはず Hash: 6563c7db425d14f864ed Version: webpack 1.12.14 Time: 2905ms Asset Size Chunks Chunk Names app.js 4.05 kB 0 [emitted] app controllers.js 2.27 kB 1 [emitted] controllers services.js 2.82 kB 2 [emitted] services + 3 hidden modules # ↓こんなのもいっぱい出たはず(今は無視!) ERROR in [default] /hoge/ionic-typescript/src/app/app.ts:8:0 Cannot find name 'angular'. . . . |
なんだか ERROR
も多々表示されていると思いますけど、重要なのは app.js
, controllers.js
, services.js
が .ts
ファイルから変換されて www/js
に出力されたことです! webpack
のコマンド作ったときに --watch
オプションをつけたと思うのですが、これをつけていると、対象となるファイルが保存で変更された場合などに、 webpack
が再度タスクを自動で実行してくれるという便利なやつです。
アプリケーション実行
とりあえずこの状態で ionic serve
を再度叩いてみましょう。壊れていたアプリがまた復活しているのが確認できると思います。
TypeScript -> JavaScript する際に、 www/js
配下にゴミが残っていると後々変なバグを誘発する恐れがあるので、 watch
を実行する前にかならず www/js
の下を全部綺麗にするようにタスクを組んでおきましょう!OSを跨げる便利な npm package
として rimraf
があるので、インストールします。
1 2 |
npm install --save-dev rimraf |
package.json
に新たな scripts
を追加します。↓の内容にしてください。
1 2 3 4 5 6 |
"scripts": { "clean": "rimraf ./www/js/*", "prewatch": "npm run clean", "watch": "webpack --config webpack/webpack.dev.js --watch" }, |
clean
というタスクを追加して、 prewatch
というものを増やして、その中で clean
を呼んでいます。 npm scripts
はそれぞれのタスクの前や後に実行するタスクを指定できます。タスクの前に実行するものは pre<タスク名>
で、タスクの後に実行するものは post<タスク名>
となります。 watch
の前にフォルダの中を綺麗にしておきたいので、 prewatch
に clean
を入れているのです。 これで、今後は npm run watch
を実行する度に、まずは www/js
直下のファイルを全部削除してくれます。
まとめ
いったんはこれで ionic
に TypeScript を導入できたことになります!が、まだまだただ単に導入しただけで、TypeScriptの旨味は出せていない状態です。次の記事ionic + TypeScript で今風な開発フローを実現【型定義ファイル活用編】でさらに強力な開発フローを完成させていきましょう!
残課題
- コンパイルエラーが出ている
- コンパイル後のファイルが複数ある
- ブラウザでデバッグしづらい
- 型をまるで使っていない