LoginSignup
104

More than 3 years have passed since last update.

tsconfigのmoduleとtargetには何を設定すればいいか - TypeScript

Last updated at Posted at 2019-11-25

TypeScriptの設定ファイルを雰囲気でコピらないための記事

TL;DR

  • moduleはどのモジュールパターンで出力するかを指定する
    • Node.jsでの利用想定ならcommonjs
    • ブラウザ側での利用ならumd
  • targetはどの動作環境向けにトランスパイルするかを指定する
    • 利用環境が想定できないならes3es5
    • 下位互換性のあるコードへの変換を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のサンプルコードは以下。

index.ts
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

output.js
"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

output.js
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

output.js
(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を切り捨てる必要は無い。

output.js
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

output.js
"use strict";
exports.__esModule = true;
exports.default = (function (name) {
    console.log("Hello " + name);
});

target: es6

es6ではサンプルコードと同じ結果になる。

しかしES6はまだブラウザでは動作しないため、前述したes3es5で出力しなければいけない。

このような下位互換性のあるコードに変換する役割はTypeScriptでも担えるが、Babelを用いて行うケースも多い。そういった場合はTypeScriptはes6またはesnextとして出力し、Babel側で任意の環境に向けたコードにトランスパイルするのが一般的。

yarn run tsc index.ts --target es6

output.js
export default (name) => {
    console.log(`Hello ${name}`);
};

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
104