ES2015とwebpackで何も考えずにコードを書いていたら、以下のような相対パス指定のimportをちらほら見かけるようになった。
import Lib from '../../lib/Lib';
ぱっと見で辛いし、Jestでmoduleをmockしたいときにも辛いので、もろもろの設定をしてimportを綺麗にした。基本的には、各種ツールにnode_moduleのdirectory指定オプションがあるので、それを利用する。
import Lib from '../../lib/Lib'
と書いてたやつが
import Lib from 'lib/Lib'
と書けるようになる。
余談だけど、JestのAutomockingはバージョン15からはデフォルトでdisabledになったらしい。なので、デフォルト設定でmoduleをmockするならjest.mock('module_path')を書かないといけない。
https://facebook.github.io/jest/blog/2016/09/01/jest-15.html#disabled-automocking
各ツールのバージョンはこんな感じ。
- webpack: 2.4.1
- Jest: 19.0.2
- flow: 0.44.2
ファイル構成
.
└── src
├── lib
│ └── Lib.js
└── main
└── foo
├── bar.js
└── bar.test.js
Lib.js
// @flow
export default class Lib {
log() {
console.log('log lib.');
}
};
bar.js
// @flow
import Lib from '../../lib/Lib';
export default function bar() {
const lib: Lib = new Lib();
lib.log();
}
bar();
bar.test.js
import bar from './bar';
import Lib from '../../lib/Lib';
jest.mock('../../lib/Lib');
test('jest', () => {
bar();
expect(Lib.prototype.log).toBeCalled();
});
各種ツールの設定
以下の設定をすることでimport pathをいい感じにできる。
srcディレクトリをmodule directoryとして認識させることで、import Lib from 'lib/Lib'
とかけるようになる。(元はimport Lib from '../../lib/Lib'
)
webpack
// webpack.confing.js
resolve: {
modules: [
path.resolve(__dirname, 'src'),
'node_modules'
]
}
Jest
// package.json
"jest": {
"moduleDirectories": [
"src",
"node_modules"
]
}
Flow
# .flowconfig
[options]
module.system.node.resolve_dirname=src
module.system.node.resolve_dirname=node_modules
最終的なコード
Lib.js
変更なしなので省略。
bar.js
importのpathだけ変更。
// @flow
import Lib from 'lib/Lib';
export default function bar() {
const lib: Lib = new Lib();
lib.log();
}
bar();
bar.test.js
importのpathとjest.mockのpathを変更。
import bar from './bar';
import Lib from 'lib/Lib';
jest.mock('lib/Lib');
test('jest', () => {
bar();
expect(Lib.prototype.log).toBeCalled();
});
動かせるサンプルコード
調査に使ったコードはこちらのリポジトリにあるのでご興味あれば。
https://github.com/mwatanabe/cleanup-messy-imports-poc
おまけ:IntelliJ IDEA
あまりいないかもしれないけど、IntelliJでJSを書いている人は、IntelliJのProject Structureの設定から、Source Folderとしてsrcディレクトリを指定すると、importの補完がいい感じになる。
こんな感じ。