TypeScriptコンパイラーとは何ができるの?

compiler OptionsやBasic Optionsをわかりやすく解説

アプリケーションを制作する過程を効率的に出来ると言ったら、どのようなことを思い浮かべますか。コードヒントや、エラーを検知してくれるものが合ったら事故防止になると思いますか。TypeScriptのコンパイラーは実行する前の異常を検知するものです。近年のJavaScriptフレームワークの規模は大きくなり、フロントエンドの役割も変化してきました。影響の範囲を特定するために、そのコントロール出来るコーディングを心がけることも求められています。このコードはどんな値になるように記述されているか、チームにとってどんなコードが期待されているか、その一つの答えとなりつつあるTypeScriptの役割を理解し、深めていきましょう。

はじめに

今回はTypeScriptのコンパイラーの機能について解説していきます。TypeScriptはJavaScriptに予め型を定義しておいて、引数や戻り値の値をコントロールすることが主な役わりです。TypeScriptファイルの拡張子は.tsとなり、コンパイルすることで.jsファイルを出力します。TypeScriptをコンパイルするにはnpmパッケージが必要で、予めインストールして下さい。

前提

開発環境

macOS Catalina

MacBook Pro (15inch, 2019)

npm version 6.14.4

nodebrew use v12.0.0(node)

tsc -v 3.8.3

おさらいしよう

.tsファイルをコンパイルするにはtscコマンドでしたね。index.tsをコンパイルの対象にする場合、ターミナルでtsc index.tsと叩きます。すると、コンパイルされ、index.jsが作成されます。今回はtscコマンドをより細かく設定出来るtsconfig.jsonファイルの基本的な設定を解説していきます。その前にtsconfig.jsonなしでホットリロードのような更新を可能にするモードがあります。以下のwatchモードも覚えておくと良いでしょう。

watchモードを使って保存したら自動でコンパイルする

自動コンパイルするにはwatchモードを使います。短縮は -w、解除はcontrol + cです。

tsc index.ts --watch

tsconfig.jsonで全てのファイルを一気にコンパイルする

ここからtsconfig.jsonファイルの機能について解説していきます。まずは作成しましょう。次のコマンドです。

tsc --init

tscコマンドのみで全てのtsファイルをコンパイルすることができます。

tsc

watchモードも追加できます。ホットリロードモードのように変更をキャッチして更新してくれます。

tsc -w

compilerOptions

トップレベルプロパティ。多くの設定項目を持っています。ビルドに関する設定を主にします。

targetに指定したバージョンでコンパイルする

defaultではes3でコンパイルされます。指定することで実行環境に適切な出力になります。

 "target": "es2017"

libで型の定義を指定する

ビルドに含めるライブラリファイルのリストになります。例えば、es2015,es2017などです。指定されていない場合はdefaultになります。targetを指定していれば明示的に指定しなくてもいいです。TypeScriptの持つ型を認識することができます。

"lib": ["es2017"],

module

生成されるモジュールコードを指定します。commonjsやamd,es2015など指定可能です。

"module": "commonjs",

allowJsはJavaScriptファイルを含める

JavaScriptファイルをビルド出来る様にします。

"allowJs": false,

checkJsはallowJsをtrueにして使う

allowJsと同じboolean。.jsファイルのエラーを報告します。

"allowJs": false,

declaration, declarationMapは型定義ファイル

自作ライブラリを適用させたい時に指定します。.d.tsファイルを生成します。

"declaration": false,
"declarationMap": false

jsxはReact.jsのJSXをサポートするかを指定する

preserve, react-native, reactが指定できます。初期値はpreserveとなります。

"jsx": "react"

sourceMapは.mapファイルを作成する

ブラウザでJavaScriptファイルをTypeScriptで表すことが出来るようになります。debugしたい時も利用することができます。対応するファイルの.mapを作成します。

"sourceMap": false

outDir, rootDir, removeComments, noEmit, downLevelIterationの使い方

コンパイルしたファイルをまとめるディレクトリを指定する

コンパイルされたjsファイルを吐き出すディレクトリを指定します。以下の場合、同階層のdistフォルダーに集まります。

"outDir": "./dist"

以下の画像の場合はどうなるでしょう。tempファイルに.tsファイルが3つありますが、excludeに指定されているものもあります。コンパイルすると

このような結果になります。distフィルダが作成されて、component.ts以外のファイルが吐き出されていますね。ですが、tempフォルダがありません。どの階層からコンパイルしても、distフォルダにまとめられてしまうと言うことですね。

では一度distフォルダを削除します。

rm -rf dist

次のようなパターンはどうでしょう。

上記ではルートにdata.tsがあり、tempフォルダには今まで通り3つのファイルが格納されています。このパターンでコンパイルすると、

階層が守られてコンパイルされました。tempフォルダ内のファイル以外にコンパイルするtsファイルがない場合,tempフォルダを残す意味はないですし、今回のようにルートにdata.tsのようなファイルがある場合は階層を守る方が最適解と判断しているようですね。ですがtempフォルダも残したい場合は次の設定を行います。

 rootDirではフォルダの調整が出来る

コンパイルされた時に削除されてしまうフォルダをあえて残したい場合や、任意で階層を残したいなど、フォルダを調整するときに使用するのがrootDirです。例えば、

上記のようなtemp/src/に2ファイル、temp/component.tsの1ファイル、ルートに1ファイルのような階層パターンでも、コンパイルすれば以下のように階層が保たれたままdistにコンパイルされます。

では、tempフォルダはいらないとした場合、以下のように設定します。

rootDirに./tempと記述することでdist内に吐き出されたフォルダはsrc以下となりました。しかしこの場合、data.tsの場所が変わったことに気づかれたでしょうか。data.tsを含めたフォルダにするようエラーがでるためdata.tsをtempフォルダ内に移動してコンパイルすることになります。

error TS6059: File '/Users/Documents/workspace/typescript/data.ts' is not under 'rootDir' '/Users/Documents/workspace/typescript/temp'. 'rootDir' is expected to contain all source files.

removeCommentsはコメントを削除する

removeCommentsをtureに設定すると、buildした後の.jsファイル内のコメントが削除されてコンパイルされます。data.tsには合ったはずのコメントが右のコンパイル後では消えています。

noEmitは何も出力しない

noEmitをtrueに設定することでコンパイル後の.jsファイルを出力しない設定をすることができます。

downlevelIteration

こちらの設定では、targetをes3,es5にしている時のみ適用される設定になります。JavaScriptのfor of 文をコンパイルした時にエラーが出る可能性があるため、防止策として使用出来る設定です。

noEmitOnError

trueにするとエラーが検出されるファイルを出力しない設定になります。distフォルダに設定している場合、distそのものも出力されません。不必要なファイルを作らない設定です。

use ‘strict’は厳格モード

use’strict’モードをtrueにすると、以下の7つをtrueにすることと同じことになります。

noImplicitAny

implicitとは暗に示されたと言う意味です。anyになってしまっている記述に対してエラーをだし、型を決めることを要求します。

例えば、関数を作成してみた時に、下記のように型を宣言することでanyを避けることができます。

型を宣言していなければ、下記のようにanyに対してエラーを出します。

では変数はどうでしょうか。

エラーが出ません。anyを許さないのではなかったんでしょうか。なぜでしょう。以下の場合をみてみましょう。Math.floorのnumberはanyではありませんね。numberに数字が代入された後、numberは数字として使われることを予想し、数字として使われるまでエラーを出さないんです。

関数のときは引数のパラメータが変化することは予想していないことから厳格に対応するよう要求します。明示的なanyは許しているんですが…変数との違いに気を付けたいとこですね。

strictNullChecksはnullやundefinedの扱いを厳しくする

defaultでstringはnullやundefinedを含みます。strictNullChecksをtrueにすることでstringにnullやundefinedを入れることができなくなります。

strictFunctionTypes, strictPropertyInitializationはclassで使う

こちらに関しては以後、別の機会に解説していきたいと思います。

strictBindCallApply

JavaScriptのbindやcall, applyの引数に対してstrictモードを設定するものです。

noImplicitThis

JavaScriptのthisに対してエラーを出す設定です。

alwaysStrict

tsc コマンドでコンパイルされた時にuse strictが自動的に挿入される設定になります。

コンパイルするファイルを選ぶ

excludeでコンパイルしたくないファイルを指定する

特定のファイルをコンパイルしない設定にするには、excludeに指定します。ビルドから除外するならここです。ルートディレクトリが対象となります。例えばserver/server.tsを対象にしたい場合は/server/server.tsと記述します。

{
  "compilerOptions": {
},
"exclude": ["server.ts", "node_modules"]
}

ワイルドカードを使えます。.d.ts(任意)がつくファイル全てを省きたい場合になります。どの.d.tsファイルもコンパイルしたくない場合は、**(アスタリスク×2)を使って表現します。**/*.d.tsとなります。このようにコンパイルを避けたいファイルがある場合、node_modulesも指定する必要があります。忘れずに入れるようにしましょう。

"exclude": ["server.ts", "node_modules", "*.d.ts", "**/component.ts"]

includeでコンパイルするファイルを指定する

includeに指定すると明示的にコンパイルしたいファイルとなります。excludeよりも弱い指定です。

 "include": [
    "**/*.spec.ts",
    "**/*.d.ts"
  ]

filesはexcludeを無効化する

ビルドに含むファイルを指定します。excludeに指定されたファイルはコンパイルされないと言いましたが、filesに指定するとコンパイルが実行されます。

 "files": [
    "test.ts",
    "polyfills.ts"
  ],

まとめ

このようにtsconfig.jsonの記述によって、コンパイル時の型を設定できます。tsc –initでtsconfig.jsonの作成から、compilerOptionsのいろいろな設定、トップレベルオプションのincludeや、exclude, filesなどもありました。webpackやnpm scriptなどと同じようにアプリケーションの制作過程の効率化や安全性を担保できるシステムとなっています。今回はtscofig.jsonの解説をしていきました。お疲れ様でした。

最後に

今回に限らず、新たに学んだことを再記述、訂正、追加更新していきます。その時は更新日を追加致しますので確認してみて下さい。

SNSでもご購読できます。

検索