Babel + TypeScript
Babel@7からTypeScriptサポートが入ったので、TypeScriptでコードを書いてbabelを用いてトランスパイルをしている人も多いと思います。
するとそのうち増えてきたimport文が大変になってくると思います。
import foo from '../../foo'
import bar from '../../bar'
というような相対パスでのimportが増えてくると絶対パスでimportしたくなってきます。
まずはbabel
tleunen/babel-plugin-module-resolver: Custom module resolver plugin for Babel
を使いましょう。
...
[
'module-resolver',
{
alias: {
foo: './foo',
bar: './bar'
},
extensions: ['.js', '.ts', '.tsx']
}
]
...
上記のような記述をbabelのconfigにpluginとして追加しましょう。
aliasの部分が絶対パスとして解決されるようになる名前です。お好きなように書き換えて下さい。
これでbabel側から絶対パスを解決できるようになりました。
つぎにTypeScript
なにもやることはありません。
tsconfig.json
のpathsにaliasを書く必要もありません。
追記(2019/4/30)
Next.jsベースのプロジェクトで使っていたときは何も書かなくてもうまくいっていたのですが、普通にwebpackでゼロからやったらTypeScript側でエラーになってました。ビルドはbabel側が解決できるので成功するが型チェックはエラーで落ちる状態になりました。
{
"baseUrl": ".",
"paths": {
"foo*": ["src/foo*"]
}
}
やはり上のような記述は必要なようです。
Next.jsではディレクトリルートに配置しているディレクトリをaliasしてたのでbaseUrl
から解決されてたからエラーにならなかったのかな...?
この記事を書いたときに使っていたプロジェクトはtsconfig.jsonでpathsは書いてないけどbaseUrlは書いてあったためbaseUrlからのパスはTypeScript側でも認識されてたみたいです。
Module Resolution · TypeScript
ESLintもほしい
benmosher/eslint-plugin-import: ESLint plugin with rules that help validate proper imports.
を使っているlint環境が前提となります。
tleunen/eslint-import-resolver-babel-module: Custom eslint resolve for babel-plugin-module-resolver
を導入しましょう。
{
"settings": {
"import/parsers": {
"@typescript-eslint/parser": [".ts", ".tsx"]
},
"import/resolver": {
"babel-module": {}
}
}
}
上記の内容を追加しましょう!
eslint-plugin-import
からts
やtsx
をparseできるようにしてあげます。
さらにresolverとしてeslint-import-resolver-babel-module
を使うように指定します。
これでbabelのconfigのaliasの中身をみてくれるようになります。
babel.config.js
のextensions
はeslint-import-resolver-babel-module
がこれを指定していないと.ts
や.tsx
を対象にしてくれずエラーになるため必要でした。
まとめ
かなり簡単に実現できるようになったのではないでしょうか。
babelに寄せたことでwebpackまわりに触ることも不要ですし、TypeScriptも完全に言語として利用するだけなのでシンプルに設定できてよいのではと思っています。
もしもっと良い環境があればご教示下さい!
あとがき
むかし、babel-plugin-module-resolverでimportを快適にする(eslint-plugin-import + flow + path-autocomplete) というようなものを書きましたが、最近はTypeScriptでしょ!ということで書き直しました。
エディタの連携はVSCodeなら特になにもしなくても補完にでてくると思います!もしだめだったら上のリンクを参考にpath-autocomplete
を使うと良いかもしれません。