viteのlib modeを使ってnpmパッケージを公開する
先日 react-use-polling を公開したのですが、その際に使用した vite の lib mode が便利だったので記録。
はじめに
今回 library として作成した react-use-polling
は、 React の custom hooks です。
本記事は custom hooks を公開する場合の lib mode の使用に関して記述しています。
言語は TypeScript を使用しているため、本記事では TypeScript での環境として記述していきます。
公開したライブラリのリポジトリは、 hey3/react-use-polling です。
lib mode とは
vite.config.ts
に build.lib
を設定すると、ライブラリとしてビルドするというものです。
昨今、web の開発環境構築はイージーなものになりました。
vite
を使うと、 vite.config
にプラグインを設定するのみで構築できるほど簡単になりました。また、エコシステムも充実しており、テストを書くにも vitest
を使うことでそれぞれの設定を vite.config
に一貫して記述することができます。
この環境を利用しながらライブラリ開発を行う際に、 lib mode も同様に vite.config
に設定を記述するだけのため、とても便利です。
各種設定
では、実際にライブラリを開発する際に意識して設定する項目を記述していきます。
vite.config.ts
import { resolve } from 'path'
import reactPlugin from '@vitejs/plugin-react-swc'
import { defineConfig } from 'vite'
export default defineConfig({
plugins: [reactPlugin()],
build: {
emptyOutDir: false,
lib: {
entry: resolve(__dirname, 'src/index.ts'),
name: 'MyLib',
fileName: 'index',
},
sourcemap: true,
rollupOptions: {
external: ['react'],
output: {
globals: {
react: 'React',
},
},
},
},
})
重要なのは build.lib
です。
build.lib.entry
に指定したファイルがエントリーポイントとなります。
build.lib.formats
には出力形式を指定することができ、 entry
が単体の場合は ['es', 'umd']
で、配列として複数指定された場合は ['es', 'cjs']
となります。
emptyOutDir
を指定することで、出力ディレクトリをビルド毎にクリーンにすることができます。
修正の際に過去のビルド結果が残る場合があるので、都度クリーンにしておくほうが安全です。
今回公開したライブラリは React で使われる前提のため、 React 自体は利用者がインストールしているはずです。そのため、バンドルサイズを軽減するためにライブラリ自体には React をバンドルしないようにしたいです。
そこで使用するのが rollupOptions.external
となります。
rollupOptions.external
に指定したものはバンドルに含まれなくなります。
UMD での利用を考慮する場合、 rollupOptions.output.globals
も設定しておくと親切です。
tsconfig.json
{
"compilerOptions": {
// ...
"declaration": true,
"declarationDir": "./dist/types",
"declarationMap": true,
"emitDeclarationOnly": true,
"noEmitOnError": true
},
"include": ["./src/**/*.ts"],
"exclude": ["./**/dist"]
}
vite は型情報を出力しません。
そのため、型定義ファイル( *.d.ts
)は tsc を使って出力しています。
vite-plugin-dts
などのプラグインを使うことも可能ですが、個人的には公式のものを使いつつ処理は分けておいた方が好みです。
package.json
{
"name": "my-lib",
"main": "./dist/index.umd.js",
"module": "./dist/index.mjs",
"types": "./dist/types/index.d.ts",
"files": ["dist"],
"exports": {
".": {
"types": "./dist/types/index.d.ts",
"import": "./dist/index.mjs",
"require": "./dist/index.umd.js"
}
},
"sideEffects": false,
"scripts": {
"prebuild": "rimraf dist",
"build": "tsc && vite build",
"prepare": "npm run build"
},
"peerDependencies": {
"react": ">= 16.8.0"
}
}
package.json
にはビルドの出力に合わせて設定を記述します。
vite のデフォルトの出力先は dist
であるため、 files
に 'dist'
を指定します。
その他型定義ファイルの指定や、エントリーポイントを指定します。この辺りは vite の使用に限りません。
vite.config.ts
にて、 React をバンドルに含めないようにしているため、 peerDependencies
に React を指定しておくと親切です。
prepare
を指定しておくことで、 npm publish
時にビルドを行います。
出力結果の確認は、 npm pack
コマンドで確認できるため、 publish 前に確認すると良さそうです。
まとめ
今回、 vite の lib mode を使ったライブラリ開発をしてみて「これは便利だな」と思ったので、メモとして淡々と設定周りを記述しました。
vite を使うことで、開発やテスト、ビルド周りの設定が簡単になったのでめちゃくちゃ良いですね。