こんにちは! @53able です。
今回は、VueCLI プロジェクトにおいてモジュールのオンデマンド自動インポートの仕組みを導入したお話をしていきたいと思います。
概要
TypeScript コード上で一部の import
文が省略できるようになります。
開発環境
プロダクションコードは src
ディレクトリ配下にあり、src/*.d.ts
の型定義が適用されているようになっております。
プロジェクトルート ├ src │ └ auto-imports.d.ts ├ .eslintrc-auto-import.json ├ .eslintrc.js ├ jest.setup.js └ vue.config.js
依存モジュールのバージョンは以下の通りです。
- VueCLI v5.0.8
- Vue v2.7.10
- VueUse v9.2.0
- Jest v27.5.1
- ESLint v8.23.0
- unplugin-auto-import v0.11.2
- TypeScript v4.8.2
- NodeJS v16.14.2
- PNPM v7.9.3
課題
SFC の <script lang="ts">
ブロックや、 .ts
ファイルに同じような import
文を長々しく書くことが煩雑でした。
VSCode などの先進的なエディタを用いれば import 文の自動挿入が可能ですが、やはり省略できるようであればそれに越したことはありません。
また、コードの簡潔化が実現できればコード差分をより小さくし、コードレビューの負担を少しでも軽減できるのではないかと思いました。
解決策
unplugin-auto-import を用いて import
文を省略できることが分かったので導入します。
あらかじめ import
文が省略可能なモジュールを設定し、コード上でモジュールが利用されている場合に自動インポートが行われます。
インストール
$ pnpm add -D unplugin-auto-import
設定
unplugin-auto-import の README に、VueCLIプロジェクト向けの設定サンプルが記載されています。
// vue.config.js module.exports = { configureWebpack: { plugins: [ require('unplugin-auto-import/webpack')({ /* options */ }), ], }, }
/* options */
の部分に設定を追加していきます。
options 設定
今回設定した options
は以下の通りです。
{ /* options */ include: [ /\.[tj]sx?$/, // .ts, .tsx, .js, .jsx /\.vue$/, /\.vue\?vue/, // .vue ], imports: [ "vue", "@vueuse/core", { // 個別のモジュール }, ], dts: "src/auto-imports.d.ts", dirs: ["src"], vueTemplate: true, eslintrc: { enabled: true, // Default `false` filepath: "./.eslintrc-auto-import.json", // Default `./.eslintrc-auto-import.json` globalsPropValue: true, // Default `true`, (true | false | 'readonly' | 'readable' | 'writable' | 'writeable') }, }
import
文省略対象のファイルパターン指定
.vue
, .ts
, .tsx
, .js
, .jsx
を対象となるように正規表現でファイル名のパターンを指定します。
include: [ /\.[tj]sx?$/, // .ts, .tsx, .js, .jsx /\.vue$/, /\.vue\?vue/, // .vue ],
import
文省略対応モジュール指定
unplugin-auto-import が定義しているプリセットか、自作のモジュールも指定可能です。
プリセット
本プロジェクトは、Vue2.7と @vueuse/core に依存しているので、プリセットから vue と @vueuse/core を採用しました。
これらのプリセットを設定すると、import { } from "vue";
, imort { } from "@vueuse/core";
を多く省略できるようになります。
imports: [ "vue", "@vueuse/core", { // 個別のモジュール }, ],
⚠️: プリセットには、モジュール名がパスカルケースの型定義は含まれていないです。それらは、 import
文を省略することは出来ません。また、 imort { get } from "@vueuse/core";
など普遍的なモジュール名の省略は避けているようです。
個別モジュール
個別モジュールの指定に関しては、以下のように指定します。
import { モジュール名 } from "パス";
を省略指定する場合には、以下の通りになります。
{ "パス": ["モジュール名"], },
モジュール名の指定は配列形式になっているので複数モジュールが指定可能です。
TypeScript でのコード補完を有効にするための dts 出力
import
文省略モジュールに関してコード補完が効くようにするため型定義ファイル auto-imports.d.ts
を出力します。
auto-imports.d.ts
は、 vue-cli-service serve 実行時に出力されます。
dts: "src/auto-imports.d.ts",
自動インポート対応ディレクトリ指定
dirs: ["src"],
Vue テンプレートでの自動インポートフラグ
SFC の <script>
内で自動インポートを有効にするフラグです
vueTemplate: true,
ESLint ルール設定ファイル出力
import
文を省略したことにより、ESLint の no-undef
エラーが検出されるようになってしまいます。
import
文省略モジュールに関してはグローバルスコープで定義済みと解釈されるように ESLint ルール .eslintrc-auto-import.json
を出力します。
.eslintrc-auto-import.json
は、 vue-cli-service serve 実行時に出力されます。
eslintrc: { enabled: true, // Default `false` filepath: "./.eslintrc-auto-import.json", // Default `./.eslintrc-auto-import.json` globalsPropValue: true, // Default `true`, (true | false | 'readonly' | 'readable' | 'writable' | 'writeable') },
ESLint
.eslintrc.js
に出力された .eslintrc-auto-import.json
で定義されている ESLint ルールを組み込みます。
module.exports = { extends: [".eslintrc-auto-import"] }
自動出力される auto-imports.d.ts
は、ESLint の範囲から除外します。
module.exports = { ignorePatterns: [ "src/auto-imports.d.ts" ] }
Jest
本プロジェクトは、ユニットテストに Jest を採用しています。
unplugin-auto-import はwebpack プラグインなので、 Jest 実行時に import
文を省略したモジュールの参照が解決できません。
import
文省略の設定をしたモジュールをグローバルスコープで定義するため、jest.setup.js
でモジュールをインポートします。
// プリセット import * as Vue from "vue"; for (const key of Object.keys(Vue)) { global[key] = Vue[key]; } import * as vueuseCore from "@vueuse/core"; for (const key of Object.keys(vueuseCore)) { global[key] = vueuseCore[key]; } // 個別モジュール import { モジュール名 } from "パス"; global.モジュール名 = モジュール名;
まとめ
unplugin-auto-import を使って import
文を省略できるようになり、コードが簡潔になりました。
本エントリーでは、unplugin-auto-import の README を見つつ、よりキャッチアップしやすい様に具体的な説明をさせていただきました。
impor
文省略を導入した場合に、ESLint を導入済みのプロジェクトでは no-undef
の指摘がたくさん出てしまうのと、コード補完が不完全になることを避ける方法が用意されていることがポイントになります。
それらが実現させるために unplugin-auto-import には、auto-imports.d.ts
と .eslintrc-auto-import.json
を出力させるオプションが備わっています。
また、Jest に関しては import
文省略コードの個別対応が必要なので、今後はコードの自動生成で対応できるようにしたいと考えています。
現時点では、指定したモジュールに関しては import
文の省略が完全に対応できているので、DX (開発体験)が向上したのではないでしょうか。