ジャコ Lab

プログラミング関連のメモ帳的ブログです

Vite x Vue3 のライブラリビルドで型定義ファイルを作成する

前回の記事で Vite を使って Vue3npm package を作成しました。

しかし、 TypeScript からだと型定義エラーになってしまうことが判明しました。

この記事では TypeScript のプロジェクトからもエラーなく利用できるように型定義ファイルを出力する方法を調べていこうと思います。

前回のおさらい

まずは、プロジェクト構成のおさらい
.
├── hello-vue3-lib  # パッケージとして提供する側のプロジェクト
└── vite-project # 提供されたパッケージを使う側のプロジェクト

また、両プロジェクト共 ViteVue3 のプロジェクトを作っています。

Vite で Vue3 のプロジェクトの作り方の記事はこちら
実行環境のおさらい
$ node -v
v20.14.0

$ yarn -v
1.22.22

「パッケージとして提供する側のプロジェクト」で型定義ファイルを出力するようにする

今回は hello-vue3-lib のプロジェクトをビルドする際に型定義ファイルも一緒に出力するようにします。

github.com

vite-plugin-dts

このプラグインを使えば良さそう!

作業ディレクトリの確認

# 作業ディレクトリの確認
$ pwd
./hello-vue3-lib

プラグインのインストール

$ yarn add -D vite-plugin-dts

vite.config.ts の変更

  import { resolve } from 'path'
  import { defineConfig } from 'vite'
+ import dts from 'vite-plugin-dts'

  import vue from '@vitejs/plugin-vue'

  // https://vitejs.dev/config/
  export default defineConfig({
    build: {
      lib: {
        // 複数のエントリーポイントのディクショナリや配列にもできます
        entry: resolve(__dirname, 'lib/index.ts'),
        name: 'hello-vue3-lib',
        // 適切な拡張子が追加されます
        fileName: 'index',
      },
      rollupOptions: {
        // ライブラリーにバンドルされるべきではない依存関係を
        // 外部化するようにします
        external: ['vue'],
        output: {
          // 外部化された依存関係のために UMD のビルドで使用する
          // グローバル変数を提供します
          globals: {
            vue: 'Vue',
          },
        },
      },
    },
-   plugins: [vue()],
+   plugins: [vue(), dts()],
  })
たったこれだけで良いみたいです。

ビルドをしてみる

$ yarn build
yarn run v1.22.22
$ vue-tsc && vite build
vite v5.2.13 building for production...
✓ 5 modules transformed.

[vite:dts] Start generate declaration files...
dist/style.css  0.07 kB │ gzip: 0.08 kB
dist/index.js   0.59 kB │ gzip: 0.39 kB
[vite:dts] Declaration files built in 4251ms.

dist/style.css      0.07 kB │ gzip: 0.08 kB
dist/index.umd.cjs  0.70 kB │ gzip: 0.47 kB
✓ built in 4.57s
Done in 12.59s.

[vite:dts] Start generate declaration files...
[vite:dts] Declaration files built in 4251ms.

こんなキーワードが出力されるようになりましたね。 なんか作ってそうな気がします!

出力ファイルの確認

$ tree dist/
dist/
├── index.js
├── index.umd.cjs
├── src
│   └── main.d.ts
├── style.css
└── vite.svg
ん。。。lib/ 以下がビルドターゲットなのに src/main.ts の型定義ファイルができている?

残念ながら lib/ 以下をビルドターゲットにしている場合はダメっぽいです。

原因調査と解決

原因

パッと見、勘ですが dts() のオプションである以下のせいな気がしました。

  /**
   * Override `include` glob (relative to root)
   *
   * Defaults to `include` property of tsconfig.json (relative to tsconfig.json located)
   */
  include?: string | string[],
$ cat tsconfig.json
  ..., // 省略
  "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"],
  ... // 省略
tsconfig.json的にはsrc以下がターゲットになっていそう

解決策

ということでvide.config.tsに以下のようなことをしてみました
    ..., // 省略
-    plugins: [vue(), dts()],
+    plugins: [vue(), dts({ include: ['lib/**/*.ts', 'lib/**/*.tsx', 'lib/**/*.vue'] })],
  })

ビルドを再実行

$ yarn build
yarn run v1.22.22
$ vue-tsc && vite build
vite v5.2.13 building for production...
✓ 5 modules transformed.

[vite:dts] Start generate declaration files...
dist/style.css  0.07 kB │ gzip: 0.08 kB
dist/index.js   0.59 kB │ gzip: 0.39 kB
[vite:dts] Declaration files built in 3332ms.

dist/style.css      0.07 kB │ gzip: 0.08 kB
dist/index.umd.cjs  0.70 kB │ gzip: 0.47 kB
✓ built in 3.64s
Done in 11.43s.
出力ログは変わらないけど。。。
$ tree dist/
dist/
├── components
│   └── CountUpButton.vue.d.ts
├── index.d.ts
├── index.js
├── index.umd.cjs
├── style.css
└── vite.svg

1 directory, 6 files

$ cat dist/index.d.ts
import { default as CountUpButton } from './components/CountUpButton.vue';

export { CountUpButton };
ちゃんと出力されるようになったっぽい!!

package.json に型定義の場所を設定する

   ..., // 省略
   "files": [
     "dist"
   ],
+ "types": "./dist/index.d.ts",
   "main": "./dist/index.js",
   ..., // 省略

「提供されたパッケージを使う側のプロジェクト」で動作確認

型定義エラーがなくなった様子
型定義エラーがなくなった様子

型定義エラーが無くなった!

まとめ

vite-plugin-dtstsconfig.jsonincludeプロパティに影響されることがわかった!