LoginSignup
2
0

More than 3 years have passed since last update.

JavaScriptで書いているWebPackのプロジェクトをTypeScriptに移行・書き換えした

Last updated at Posted at 2019-11-25

背景

学習がてら開発しているクライアントサイドのみの小さなSPAをJavaScriptで書いていたが、変数に入っているのが何のオブジェクトなのかがわからなくなって混乱してきたので重い腰を上げてTypeScriptに移行することに。

環境

Vue.jsを使ったJavaScript(ES6)のコードをWebPackで固めてクライアントサイドで実行している。
エディタはVSCode

typescriptとts-loaderモジュールのインストール

WebPackや各種モジュールを使うのにすでにnpmやNode.jsやWebPackはインストール済みなので、TypeScriptとそれをWebPackにロードするためのローダーのモジュールをnpmでインストールする。

$ npm i typescript ts-loader

webpack.config.jsの書き換え

既存のwebpack.config.jsファイルのmodule.rulesに.tsファイルのロードと解決に関する設定を追加したところ以下のようになった。

webpack.config.js
module.exports = {
    mode: 'development',
    module: {
        rules: [
            {
                test: /\.css$/,
                use: [
                    "style-loader",
                    "css-loader"
                ]
            },
            { // .tsファイルをロードする設定を追加
                test: /\.ts$/,
                use: 'ts-loader'
            }
        ]
    },
    resolve: {
        alias: {
            'vue$' : 'vue/dist/vue.esm.js'
        },
        // 拡張子.tsのファイルをjsに変換
        // (この設定はファイル名の解決に使われるらしい。詳細を後述)
        extensions: ['.ts','.js']
    },
    entry: './src/index.js',
    output: {
        path: `${__dirname}/public`,
        filename: 'main.js'
    },
    devServer: {
        contentBase: './public'
    }
}

ts設定ファイルの追加

以下のようなtsconfig.jsonを追加しました。詳細は後述。

tsconfig.json

{
    "compilerOptions": {
        "target": "esnext",
        "module": "commonjs",
        // "noImplicitAny": true, // 今まで書いたJSのコードで定義した変数がとりあえずそのまま使えるように
        "esModuleInterop": true,
    },
}

拡張子とソースコードの変更

JavaScriptで書かれたコードはそのままTypeScriptのコードとして通用すると言うことなので、以下のようなprogram.jsをprogram.tsにリネーム。

idnumberのような仮引数に対して"Parameter 'id' implicitly has an 'any' type.ts(7006)
"と怒られた。tsconfig.jsonのnoImplicitAny : trueをコメントアウトすることで解消。

program.js
 export default class Program {
    constructor(id, number, title, startTime, lengthMinute, unlockOffsetMinutes) {
        this.id = id;
        this.number = number;
        this.title = title;
        this.startTime = startTime;
        this.lengthMinute = lengthMinute;
        this.unlockOffsetMinutes = unlockOffsetMinutes;
        this.isSelected = false;
    }
    /* 色々な処理が書かれているけど省略 */
}

すると、Property 'id' does not exist on type 'Program'.ts(2339)と怒られた。TypeScriptのクラス定義ではコンストラクタ外でプロパティの定義が必要らしい。VSCodeのQuick FixでDeclare propertyすることで解消。

program.ts
 export default class Program {
     id: any;
     number: any;
     title: any;
     startTime: any;
     lengthMinute: any;
     unlockOffsetMinutes: any;
     isSelected: boolean;
    constructor(id, number,title, startTime, lengthMinute, unlockOffsetMinutes) {
        this.id = id;
        this.number = number;
        this.title = title;
        this.startTime = startTime;
        this.lengthMinute = lengthMinute;
        this.unlockOffsetMinutes = unlockOffsetMinutes;
        this.isSelected = false;
    }
    /* 色々な処理が書かれているけど省略 */
}

遭遇したエラー

Module not found: Error: Can't resolve './program' in '/Users/rlcl-226/git/gachi-taite-designer-web/src'

webpackが出したっぽいエラー.
./program と言うファイルを探した結果見つからなかったと言っているように見える。webpack.jsのresolve.extensionsの設定をすることで解消。
WebPackがprogram.jsを探しに来た時に、TypeScriptコンパイラがprogram.tsをコンパイルしたものを渡してあげるという設定だろうか?

終わりに

とりあえずTypeScriptへの移行の最初のファイルはこれで完了した。
これとは別のソースファイルをTypeScriptに移行しようとした時、moment-duration-formatでエラーが出て直したりしたが、それは次の記事で解説する。

↓次の記事
https://qiita.com/a-yonenaga/items/9f8d1a0fcf898e127b26

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