TypeScriptの設定ファイルを雰囲気でコピらないための記事
TL;DR
-
module
はどのモジュールパターンで出力するかを指定する- Node.jsでの利用想定なら
commonjs
- ブラウザ側での利用なら
umd
- Node.jsでの利用想定なら
-
target
はどの動作環境向けにトランスパイルするかを指定する- 利用環境が想定できないなら
es3
やes5
- 下位互換性のあるコードへの変換をBabelで行うなら
esnext
- 利用環境が想定できないなら
module とは
JavaScriptにはいくつかのモジュールパターン(CommonJSやAMD、ECMAScriptなど)がある。TypeScriptをJavaScriptに変換する際、どのモジュールパターンにするかをmodule
に指定する必要がある。
module
には'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015', 'esnext'
などを指定できる。デフォルトはtarget === "es3" or "es5" ? "commonjs" : "es6"
、つまりtargetがes3かes5ならcommonjsとなる。
サンプルコード
今回は実際にアウトプットされるコードを見ながら解説する。
用いるTypeScriptのサンプルコードは以下。
export default (name: string) => {
console.log(`Hello ${name}`)
}
module: commonjs
commonjsはサーバー側(Node.js)で用いられるモジュールパターン。
このモジュールはrequire('name')
形式で読み込める。
自分のコードがNode.jsからしか利用されない、という想定の場合はcommonjsにする。
yarn run tsc index.ts --module commonjs
"use strict";
exports.__esModule = true;
exports["default"] = (function (name) {
console.log("Hello " + name);
});
余談だが、後述するアウトプットの中にもexports.__esModule = true;
のような記述が頻出する。これはモジュールがES Modules(import
, export
)形式に対応していることを伝えるためである。読み込み側はTypeScriptのesModuleInterop
をtrueにすれば、上のようなcommonjs形式のライブラリもimport
で読み込める。
詳しくは「TypeScriptの--esModuleInterop
は一体何をやっているのか - stone's throw」が参考になる。
module: amd
amdはブラウザ側で利用でき、さらに非同期で読み込めるモジュールパターン。
amdについてはAMD & RequireJS - Qiitaが参考になる。
yarn run tsc index.ts --module amd
define(["require", "exports"], function (require, exports) {
"use strict";
exports.__esModule = true;
exports["default"] = (function (name) {
console.log("Hello " + name);
});
});
module: umd
umdは、commonjsとamdの両方に対応したモジュールパターン。コードサイズはamdとそれほど変わらないため、基本的にブラウザ向けに配布する場合もumdにする。(例として、Vue.jsはscriptをumdで配布している。)
yarn run tsc index.ts --module umd
(function (factory) {
if (typeof module === "object" && typeof module.exports === "object") {
var v = factory(require, exports);
if (v !== undefined) module.exports = v;
}
else if (typeof define === "function" && define.amd) {
define(["require", "exports"], factory);
}
})(function (require, exports) {
"use strict";
exports.__esModule = true;
exports["default"] = (function (name) {
console.log("Hello " + name);
});
});
module: es6
yarn run tsc index.ts --module es6
ライブラリがES Modules形式でしか利用されない場合、es6
もしくはesnext
を指定する。
しかし前述したcommonjsのライブラリもesModuleInterop
によってES Modules形式で読み込むことができる。そのため無理にこのes6
などに設定してcommonjsを切り捨てる必要は無い。
export default (function (name) {
console.log("Hello " + name);
});
Target
target
はどの動作環境に向けてトランスパイルするかを指定する。
target
には、'es3', 'es5', 'es6', 'es2015', 'es2016', 'es2017', 'es2018', 'es2019', 'es2020', 'esnext'
などを指定できる。(デフォルトはes3
)
target: es3
サンプルコードにあるHello ${name}
は、ES6から使えるテンプレートリテラルである。ES3やES5では使えないため、ここでは"Hello " + name
に変換されている。
yarn run tsc index.ts --target es3
"use strict";
exports.__esModule = true;
exports.default = (function (name) {
console.log("Hello " + name);
});
target: es6
es6
ではサンプルコードと同じ結果になる。
しかしES6はまだブラウザでは動作しないため、前述したes3
やes5
で出力しなければいけない。
このような下位互換性のあるコードに変換する役割はTypeScriptでも担えるが、Babelを用いて行うケースも多い。そういった場合はTypeScriptはes6
またはesnext
として出力し、Babel側で任意の環境に向けたコードにトランスパイルするのが一般的。
yarn run tsc index.ts --target es6
export default (name) => {
console.log(`Hello ${name}`);
};