ReactNative + TypeScript で PathAliasing


import TestScreen from '../screens/TestScreen'
import TestComponent from '../../components/TestComponent'
import TestLibrary from '../../../lib/TestLibrary'

みたいなのはやりたくないので、 ../ を別の文字(列)に置き換えたい。

環境

ReactNative 0.57
TypeScript 3.1.6
(expo v31)

目標

../../ という部分を AppRoot という文字列に置き換える。以下のように書けるようにしたい。

import TestScreen from 'AppRoot/screens/TestScreen'
import TestComponent from 'AppRoot/components/TestComponent'
import TestLibrary from 'AppRoot/lib/TestLibrary'

AppRoot は文字通り、アプリのルートディレクトリ。慣習的には @ をつかうことが多いしこっちのが簡潔だけど、これが使えない理由は後述。

やり方

tsconfig.jsonの設定

TypeScriptのコンパイルが通るように以下の設定をtsconfig.jsonに追加

{
  "compilerOptions": {
    "baseUrl": "./",
    "paths": {
      "AppRoot/*": ["./*"]
    }
  }
}

tslint.jsonの設定

さらにtslint.jsonも以下のように設定。この設定が無いとno-implicit-dependenciesルールに引っかかってlinterに怒られてしまう。

"no-implicit-dependencies": [true, ["AppRoot"]]

babel-plugin-module-resolver をインストール

yarn add -D babel-plugin-module-resolver

上記のTypeScript関連の設定だけではダメだったので、babelでもimportを解決してくれるパッケージが必要だったので、babel-plugin-module-resolverをインストール。
自分の場合はexpo環境下だったので、expo init コマンドで作成したときにデフォルトでbabel.config.jsが存在していた。今回はそのbabelの設定ファイルに以下のような設定を追加した。

plugins: [
  [
    "module-resolver",
    {
      root: ["./"],
      alias: {
        AppRoot: "./",
      },
    },
  ],
],

これでビルドすればもう ../ 地獄に悩まされずに済む。

@が使えない理由

https://github.com/palantir/tslint/issues/3364#issuecomment-425058574
このissueにあるように、2018/11現在バグによって @ という記号が使えないらしい。 @Componentというような文字列をaliasにしてもダメだった。もうちょっと待ったら治るかも?