TypeScriptでコードを書いて、ブラウザで動かすためにWebPackでまとめてるアプリで、Worklet用に別に出力しているソースに不要なコードも含まれてしまってサイズが大きくなってしまっていた。
「Worklet側でもimport
されるコードをソースを手動で分離するか〜」と思ったが、TreeShakingという機能でできるということなのでやってみた。
TypeScriptのコードでTreeShakingを有効にする
WebPackのTree Shakingの説明によればwebpack.config.jsにoptimization: {usedExports: true}
と指定すればいいとのこと。
がやってみるとされなかった。
他にもpackage.jsonに"sideEffects": false
を指定してみたりしたけど変わらず。
ググったところ、TypeScriptから変換している場合にはtsconfig.jsonの"compilerOptions"
内で"module": "es6"
とする必要があるとのこと:
(Typescript + Tree shaking configuration · Issue 995 · webpack/webpack.js.org)
"commonjs"
だったのを"es6"
に変更することでTreeShakingが機能するようになって、生成されるjsのファイルサイズが小さくなった、めでたしめでたし…
- 要するにTypeScriptからJavaScriptにトランスパイルする際に、
"commonjs"
だとimport
がrequire
に変換されてしまい、それだとES6モジュール定義が失われてしまいTreeShakingで判定されない - WebPackのTypeScriptのBasic Setup はちゃんと
"module": "es6"
となっていた
ts-nodeも動くようにする
しかし上記の設定をすると、ツールとしてローカルで動かしていたTypeScriptのコードでエラーが出るようになってしまった:
$ npx ts-node ./tools/getmapperno.ts test.nes |
TypeScriptのコードをts-nodeで動かしていたんだけどその場合も"es6"
モジュールとしてコンパイルされ、それがnode.jsで動かせないっぽい。
ワーニングに示されてる対応をしても動作しなかった。
あれこれ調べたが、結局はts-nodeの説明に書かれていた。
曰く、tsconfig.jsonに追加で"ts-node": {"compilerOptions": {"module": "CommonJS"}}
と指定する:
{ |
(他にはWebPackで使用するtsconfigのファイルを変更(webpack + ts-loader で使う tsconfig.json を動的に切り替える - mizdev)、
またはts-nodeにコマンドラインオプション-P
で指定という方法もあった。)
ts-nodeの場合"CommonJS"
としてコンパイルするとして回避したけど、そうじゃないと動かない理由というのはよくわかってない…JavaScriptのモジュールの仕組みもよく理解してない…。