ES Modulesのimportで絶対パスを使いつつ、eslintでインポート先モジュールも検証させる
Firefox 60からES Modulesにネイティブで対応するようになったことから、筆者は現在、(人に言われて)自作アドオンのES Modules化を進めています1。
ES Modules化の最大のモチベーションは、eslintでのより厳密な検証が可能になるという点です。ES Modulesの仕様に則って書かれたモジュール群は、モジュール外で定義された変数や関数の事を考慮しなくてもよくなるため、変数名や関数名のtypoによって発生する「未定義の変数を参照している」「未定義の関数を呼ぼうとしている」といった状況まで静的に検出できるようになります2。
ただ、eslintでeslint-plugin-importを使ってインポート先のモジュールまで含めて検証するためには、from
に書かれたパスを辿れる必要があります。なので普通にやろうとすると相対パスを使ってこんな風に書く事になります。
import * as Constants from '../../common/constants.js';
import * as ApiTabsListener from '../../common/api-tabs-listener.js';
import * as MetricsData from '../../common/metrics-data.js';
import * as ApiTabs from '../../common/api-tabs.js';
import * as Tabs from '../../common/tabs.js';
import * as TabsContainer from '../../common/tabs-container.js';
import * as TabsUpdate from '../../common/tabs-update.js';
階層が深くなると../
を何個も書かなければなりませんし、ファイルを置く階層を変える時もファイル間の位置関係を考慮してパスを直さなければなりません。これは地味に大変です。
ところで、Firefoxの拡張機能では構成ファイルのパスを示すにあたって、拡張機能のプロジェクトルートからの位置を/
から始まる絶対パスとして記述できます。なのでimport
文でも是非そうしたい所なのですが、そうするとeslintでの検証ができなくなります。/
から始まる絶対パスでimport
させつつeslintでの検証も行う方法は無いものか……はい、あります。そこで登場するのがeslint-import-resolver-babel-moduleです。
eslint-import-resolver-babel-moduleを使うには、まずpackage.json
に依存関係を追加し、それらをnpm install
でインストールします。
},
"dependencies": {
"eslint": "^5.0.1",
- "eslint-plugin-import": "^2.13.0"
+ "eslint-plugin-import": "^2.13.0",
+ "babel-core": "^6.0.0",
+ "babel-plugin-module-resolver": "^3.0.0",
+ "eslint-import-resolver-babel-module": "^4.0.0"
}
}
eslint-import-resolver-babel-module
だけでなくbabel-core
とbabel-plugin-module-resolver
もわざわざdependencies
に追加しているのは、筆者環境では以下のように警告されたためです。
npm WARN [email protected] requires a peer of babel-core@^6.0.0 but none is installed. You must install peer dependencies yourself.
npm WARN [email protected] requires a peer of babel-plugin-module-resolver@^3.0.0-beta but none is installed. You must install peer dependencies yourself.
次に、.eslintrc.jsのmodule.exports
に必要な設定を追加します。
module.exports = {
'root': true,
'parserOptions': {
'ecmaVersion': 2018,
},
'env': {
'browser': true,
'es6': true,
'webextensions': true,
},
+ 'settings': {
+ 'import/resolver': {
+ 'babel-module': {
+ 'root': ['./'],
+ }
+ }
+ },
eslint-import-resolver-babel-moduleの使い方の情報を検索すると'babel-module': {}
とだけ書いておく例が結構出てきた3のですが、筆者環境では'root': ['./']
という指定で明示的にプロジェクトルートを絶対パスのルートに紐付ける必要がありました。
最後に、各モジュールのimport
文のfrom
に書かれた相対パスを絶対パスに直しておきます。コマンド操作でやるなら以下の要領です。
git grep "from '../" |
cut -d : -f 1 |
uniq |
xargs sed -i -r -e "s;from '(../)+;from '/;g"
(これはUbuntu 16.04LTSでの例なので、GNU sedのオプション形式になっています。macOSの場合はBSD sedなので、-r
ではなく-E
と指定しなくてはなりません。)
これで、相対パスでimport
していた箇所が以下のような/
から始まる絶対パス表記に置き換わります。
import * as Constants from '/common/constants.js';
import * as ApiTabsListener from '/common/api-tabs-listener.js';
import * as MetricsData from '/common/metrics-data.js';
import * as ApiTabs from '/common/api-tabs.js';
import * as Tabs from '/common/tabs.js';
import * as TabsContainer from '/common/tabs-container.js';
import * as TabsUpdate from '/common/tabs-update.js';
以上の手順で、筆者環境では無事に絶対パスでimport
されたモジュールまで含めた検証が行われるようになりました。
-
Mozilla Add-onsのファイルアップロード時の検証器がES Modulesに対応していないためリリース版には反映できていないのですが、現在の所、ツリー型タブとマルチプルタブハンドラは作業を概ね終えています。 ↩
-
具体的にどのようなルールを使えているかは、2018年7月31日現在「ツリー型タブ」で使用している.esrintrc.jsの内容も併せてご覧下さい。 ↩
-
実際、自分はimportを絶対パスで書くに書かれていた内容をヒントにして作業しました。 ↩
Author And Source
この問題について(ES Modulesのimportで絶対パスを使いつつ、eslintでインポート先モジュールも検証させる), 我々は、より多くの情報をここで見つけました https://qiita.com/piroor/items/f1f95fbb1ee98f7e23a2著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .