JavaScript
TypeScript
vue.js
VSCode

VSCode / Vue.jsでコンポーネントの自動Importプラグイン(拡張機能)をつくってみたよ

はじめに

VSCodeでvueで開発しているとき、コンポーネントのimportを毎回記述するのが煩わしかったので、import挿入してくれるプラグインを作ってみました。
1.png
先に言い訳します。
えいやっ!の精神で作ったので変数名とかいろいろツッコミどころ満載です。

こちらのソートプラグインと合わせて使うと良い感じです。

感想

英語のドキュメントしかないし、最終的にvscodeのd.tsから想像しろ的なところがあって辛かった。

雛形テンプレート

vscode-generator-codeを使用して雛形を作成します。使い方はQiitaにも記事があるのでそちらを見ると良いかと。この段階では「お、簡単じゃん!っていう印象。」

package.json

プラグインの設定はpackage.jsonに書いていきます。要点だけ。

contributes.configuration
ユーザー設定を定義。今回はルートディレクトリを設定できるようにしたので、vuejsAutoImport.rootDirectoryをstring型で定義してます。

contributes.commands
当プラグインのコマンドを登録します。ctrl+shift+pから機能を使用できるようになります。

contributes.menus.editor/context
コンテキストメニューにコマンドを追加します。
contributes.commandsで設定したタイトルでコンテキストメニューに追加されます。

contributes.keybindings
ショートカットキーにコマンドを割り当てます。
同じくcontributes.commandsで設定したタイトルでコンテキストメニューに追加されます。
ちなみにwindowsとmacでそれぞれ設定できるみたいですが、mac持ってないのでテストしてないです。(ちゃんとうごくかなー

コマンド登録

extension.tsのactivateメソッドがvscode起動時に実行されます。
なので、この中で、vuejsAutoImportコマンドを登録します。

export function activate(context: vscode.ExtensionContext) {
  context.subscriptions.push(
    vscode.commands.registerCommand('extension.vuejsAutoImport', async () => {...

Import文を挿入

流れ
1. 現在選択されているテキストを取得します。
2. そのテキストでファイル名をgrepします。
3. import文とcomponents:{}に追加します。

1. 現在選択されているテキストを取得します。

vscode.TextDocument.getWordRangeAtPosition()で現在のポジションから選択しているテキストを取得できます。第2引数で正規表現を指定できます。<>内のテキストが欲しいので以下の感じに。
/<.+?-?.+?(>| )/

2. そのテキストでファイル名をgrepします。

grepはglobbyを、ファイル名の記法がいろいろあるのでファイル名の変換にはvocaを使用してます。
※ファイル名変換
<sample-component> → sample-component → SampleComponent → 'SampleComponent' + '.vue'で検索!
ファイル名はどんなケースで書かれてるか解らないので、とりあえずありそうなケースを舐めてます。

const pathList: string[] = await grepAsync([
  path.join(rootPath, `**/${voca.camelCase(text)}.vue`),
  path.join(rootPath, `**/${voca.kebabCase(text)}.vue`),
  path.join(rootPath, `**/${voca.capitalize(text)}.vue`)
])

3. import文とcomponents:{}に追加します。

<script>の直下に取得したパスを追加します。
ちなみに、同じ名前のファイルが複数ある場合は選択できるようにしています。
3.png
制御は以下のようにしてます。

if (pathList.length === 1) {
  importCore(pathList[0])
} else if (pathList.length > 1) {
  vscode.window.showQuickPick(pathList).then(selectedPath => {
    importCore(selectedPath!)
  })
}

挿入するimport文はこんな感じかと。

import ${ファイル名} from '${パス}' ${改行コード}

components:{} への追加は以下の正規表現をしようしています。
/components( )*:( )*{[\s\S]*?(?=})/

この正規表現にヒットした文字の最後が{ か , のときはファイル名をそのまま挿入。
それ以外のときは, + ファイル名を挿入しています。

Marketplaceに公開

こちらも検索すれば良い記事がたくさん出てきます。
ちなみに管理画面はこんな感じ。
2.png

最後に

いつか気分が乗ったらimportとcomponents:{}への追加時にソートしてくれるようにしたいです。
あと、私が見つけられなかっただけで、そのプラグインすでにあるよって場合は教えてくれたら嬉しいです。

:relaxed: おまけ :relaxed:

このコンポネントのpropなんだろうって毎回確認しに定義に飛ぶのが手間だったので、
タグにマウスオーバーで<script>内をツールチップに表示するプラグインも作りました。
vue-peekのツールチップ版みたいな感じです。