LoginSignup
6
2

More than 5 years have passed since last update.

TypeScriptプロジェクトをECMAScript標準に合わせていく話

Posted at

この記事はOpt Technologies Advent Calendar 2016の9日目です。

webpack 2.2-rcが出ましたね!

(記事がめっちゃ遅れたのはこの時を待っていたからなんです!。。。嘘ですすみません><)

webpack2のtree shakingはES Modulesで書かれていないと適用されないのではと風の噂で聞いた(真偽は知らない。。。)ので、この機会にcommonjsスタイルを撲滅しようとしてみました。

内容が薄い&あまり参考になるものではない、のはご容赦ください。

現状の問題

僕の現在のプロジェクトでは、いろんな書き方が混在していました。。。

import A = require('A')
const A = require('A')
import A from 'A'

さらには、react-routerの型定義ファイルが良くないのか、僕のTypeScript力が足りないのか、型合わせがうまく行かずに困っていて妙なハックをしていました。(RouterContextProps という型が欲しいのになんか全然取れなかった)

とりあえず開発はできているものの、webpack2対応や、今後ES Modulesの書き方に統一していって変な悩みをなくしていこうということで、ガッとやってしまいました。

ゴール

tsconfigのmodulesをcommonjs -> es6にすること(targetはes5のまま)。
後述の話で出てきますが、noImplicitAnyも消したくなかったので変なハックが入っています。

{
  "compilerOptions": {
    "module": "es6",
    "target": "es5",
    "noImplicitAny": true,
    ...
  }
}

やったこと

これまで、こんなコードが入ってました。

const {Button} = require('react-materialize')

現在、react-materializeの型定義は存在しないので、

import {Button} from 'react-materialize'

などと書くと module 'react-materialize' not foundなどと言われるため、これまで上記のようにかいていました。それをなんとか読み込ませたい。
わかめさんのこちらの記事などではnoImplicitAnyを外せばいける、などと書かれていましたが、それも嫌だったので別の方法で対応しました。

allowImportAsAny.d.ts
//型定義ないやつを読み込めるようにする。
declare module "fetch-mock";
declare module "react-router";
declare module "react-materialize";
declare module "react-select";

このような型定義ファイルを自作して逃れました。なお、react-routerは型定義が壊れているように見える(リンクを失念しましたが、DefinitelyTypedにもissueが上がってる)ので、落ち着くまでは型なしにしました。

webpack2対応もやってみた

ついでにwebpack2.2-rcも試してみました。(お仕事のではまだマージされてない)

普通のwebpack.conf.jsはほぼ変更無く動いたのですが、karmaでのwebpackの設定が一苦労いりました

元のコード
webpack: {
    resolve: {
        extensions: ['', '.ts', '.js', ".tsx"]
    },
    module: {
        loaders: [{
            test: /\.tsx?$/,
            loader: "ts-loader"
        }],
        postLoaders: [{
            test: /\.js/,
            exclude: /(__test__|node_modules|bower_components)/,
            loader: 'istanbul-instrumenter'
        }]
    }
},
直したコード
webpack: {
    resolve: {
        extensions: ['.ts', '.js', ".tsx"]
    },
    module: {
        rules: [
            {
                test: /\.tsx?$/,
                loader: "ts-loader"
            },
            {
                test: /\.js/,
                exclude: /(__test__|node_modules|bower_components)/,
                query: {esModules: true},
                loader: 'istanbul-instrumenter-loader'
            }
        ]
    }
},

僕らのプロジェクトではistanbulでカバレッジを取っているため、そちらの設定が手間取りました。
書いてて気づいたのですが、 postLoadersの書き方変更ちゃんとやってないですね。。。まぁ動いてるから良いのかな。。

その他

ついでに、lodashやobject-assgnに依存していた箇所をcore-jsを使う形に変えました。これもECMAScript標準に合わせて行こうということで。

まとめ

JSはいろんな書き方できてしまいますが、なるべくECMAScript標準に寄せれるように適宜調整していきたいです。

6
2
0

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
6
2