Oinari Tech Blog

プログラミングとか、日々の技術的アウトプットをするためのブログ

ts-nodeを使ってtsconfigのpathsをちゃんと読み込ませる

どうも、フロントエンドエンジニアのおいなりです。

今回はタイトルにある通り、ts-nodeを使って「tsconfig.json」のpathsをちゃんと読み込ませるために必要な指定について書いています。

というのも、最近自分で作っている『First Vue』のバックエンド側をTypeScriptに変えようとしたときにこの問題が発生しました。

ただ、これがベストな方法なのか不明なので、わかる方ツイッターからでもご指摘ください!

Node.js + TypeScriptでエイリアスを指定する

まず前提として、TypeScriptで独自のエイリアスを指定するためには、「tsconfig.json」に下記のような記述をしなければいけません。

tsc --initのコマンドで「tsconfig.json」を生成した場合には、コメントとしてすでに記述されているので、それを有効にしましょう。

{
  "compilerOptions": {
    /* Base directory to resolve non-absolute module names. */
    "baseUrl": "./",
    /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
    "paths": {
      "@Config": ["./config"],
      "@Server/*": ["./server/*"],
    },
  }
}

pathsを有効にするためには、"baseUrl": "./",の指定も必要です。

そうすると、下記のようにパスの指定が可能になります。

import config from '@Config';
import encrypt from '@Server/utils/hash';

ただ、ここで"@Config": ["./config"]"@Server/*": ["./server/*"]の指定の仕方が若干違うのですが、これは/つなぎで下層にあるファイルを指定できるかどうかの違いです。

ts-nodeを使うとエイリアスがエラーになる

開発時はコンパイルをせず、ts-nodeのようなものを使うこともあります。

ただ、なぜかts-nodeを使うと下記のような、エイリアスの「パスが解決ができません」というエラーが表示されます。

Cannot find module '@Server/../..'

解決法としてはts-nodeを使うと、tsconfig-pathsというnpmパッケージが必要みたいです。
tsconfig-paths

なので、下記でインストールしましょう。

npm i -D tsconfig-paths

インストールが完了したら、下記のコマンドで対象ファイルの実行をすればちゃんとエイリアスを読み込めるようになります。
./server/index.tsは実行したいファイルを指定します。

ts-node -r tsconfig-paths/register ./server/index.ts

ESLintやwebpackを使っている場合

ここまででts-nodeを使ったパスは一旦解決なんですが、補足としてESLintやwebpackを使っている場合の指定の方法を書きます。

webpackのエイリアス対応

「tsconfig.json」でpathsで解決できたかと思いきや、webpackを使っている場合には「webpack.config.js」にもエイリアスの指定を書かなければいけません。

「tsconfig.json」のときとはちょっと変わって、下記のように指定します。

module.exports = {
  resolve: {
    alias: {
      "@Config": "./config",
      "@Server": "./server",
    }
  }
}

ESLintのエイリアス対応

ESLintを使っていると、先ほどの設定がちゃんとできていてもエイリアスののパス解決がESLintでエラーになってします。
なので、下記のコマンドで必要なnpmパッケージをインストールしましょう。

npm i -D eslint-import-resolver-alias

インストールしたら、ESLintの設定ファイルに下記のように追記しましょう。例として、「.eslintrc」のファイル形式です。

// .eslintrc
"plugins": { ... },
"extends": [ ... ],
"settings": {
  "import/resolver": {
    "alias": {
      "map": [
        ["@Config", "./config"],
        ["@Server", "./server"]
      ],
      "extensions": [".ts", ".js", ".json"]
    }
  }
},

まとめ

いやー。エイリアスの指定だけでこんなに書かないといけないのは大変ですね。

Node.jsとTypeScriptの開発でts-nodeを使う場合には、tsconfig-pathsをインストールしてコマンドにオプションとして指定します。

また、ESLintやwebpackを使っているときには、さらにそれらの設定ファイルにエイリアスの指定をします。

ちょっと面倒ではありますが、TypeScriptでの開発は恩恵のほうが多いと思うので、理解したいですね。

以上ですー!!