Typescript、VSCodeのMove to new file は便利だぞという話
Move to a new file を使おう
VSCodeのリファクタリング機能はとても便利ですが、とりわけMove to a new file
は使い方を覚えると、コーディング作業の速度をかなり上げることができます。
「1つのファイルに関数を詰め込みすぎない、理想を言うなら1つの関数に1つのファイル。しかし、importの整理や、ファイルの作成の手間を考えると、ちょっと億劫……。」という人も少なく無いと思います。
そんな時は、纏めて書いた後にMove to a new file
で切り出していく手法を覚えておくととても便利です。
例えばこんなシチュエーション
foo.ts
でfoo()
を書いていた。ファイル内で作っていたbar()
は別のファイルに分けたくなった
// foo.ts
import { baz } from './baz';
export function foo() {
return bar();
}
// ここから下を選択し、リファクタリング -> Move to a new file
function bar() {
return baz();
}
こんな時にMove to a new file
を使いましょう。自動的にbar.ts
を生成し、importの整理も自動で行います。コピペで行うと、ファイルの作成と命名、importの整理といった面倒な手作業が多く発生します。
// foo.ts
import { bar } from './bar';
export function foo() {
return bar();
}
// bar.ts
import { baz } from './baz';
export function bar() {
return baz();
}
応用
Move to a new file
で切り出したときのファイル名は、選択範囲の一番上の変数 or 関数の名前になります。範囲内に変数や関数の候補がない場合はnewFile
になります。
その1 好きなファイル名で出力する
ファイル名にしたい変数を一時的に定義した後、Move to a new file
を任意のファイル名(変数や関数名で使える範囲に限る)で出力することができます。index.tsなどにリネームしたい場合に少し楽ができます。
// ここから下を選択し、Move to a new fileすると index.ts が生成される
const index = 0;
function bar() {
return baz();
}
応用その2 ファイルと関数、両方のリネーム
「bar()
を切り出してbar.ts
で作ったけれど……。やっぱりhoge()
にしたかったなぁ」なんてこともあると思います。
ファイル名も合わせてhoge.ts
にリネームしてしまいたいところです。その場合、シンボルの名前変更
で関数の名前をリネームした後、もう一度Move to a new file
をすると良いです。
// bar.ts
import { baz } from './baz';
// barを選択し、シンボルの名前を変更でhogeに変更
// barをimportしている関数も自動でリネームされる
function bar() {
return baz();
}
↓
// bar.ts
import { baz } from './baz';
// ここから下を選択し、Move to a new fileすると
// hoge.tsが生成され、中身がなくなったbar.tsは空ファイルになる
function hoge() {
return baz();
}
この操作により、新たにhoge.ts
が生成され、bar.ts
の中身は空になります。空になったbar.ts
を消してあげると、実質リネームが完了します。
その3 単体テストを書く手間を少し節約
例えばJest等で、foo.ts
に対応するテストをfoo.test.ts
やfoo.spec.ts
として、同じフォルダに格納している場合、テストコードを関数の下にいきなり書くことで、importを書く手間を少し省けます。
// foo.ts
export function foo() {
return 1;
}
// fooの真下にfooのテストコードを書き、Move to a new fileする
describe(foo, () => {
it('1を返す', () => {
expect(foo()).toBe(1);
});
});
describe
以降の行を選択してMove to a new fileすると、同じフォルダにnewFile.ts
が生成されます。
// newFile.ts
import { foo } from './foo.ts'
describe(foo, () => {
it('1を返す', () => {
expect(foo()).toBe(1);
});
});
newFile.ts
をテスト用のファイル名のfoo.test.ts
にリネームしてあげると、必要なimportを備えた単体テストファイルが出来上がります。
更におすすめの設定とか
importやファイル名の管理は、地味に時間を費やす作業のため、可能な限りIDEの支援を活用するのが理想的だと思います。Workspaceの.vscode/setting.json
に、eslintやstylelint、prettierやimport整理を自動で行う設定を追加しておくと、気持ちよく切り出すことができるのでオススメです
{
"editor.codeActionsOnSave": [
"source.organizeImports",
"source.addMissingImports",
"source.removeUnusedImports",
"source.fixAll.eslint",
"source.fixAll.stylelint",
],
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"editor.formatOnPaste": true,
"editor.formatOnType": true,
"typescript.preferences.importModuleSpecifierEnding": "minimal",
"javascript.preferences.importModuleSpecifierEnding": "minimal"
}
Discussion