📦

Viteのライブラリモードを使ってnpmパッケージを作成&公開してみる

2023/04/16に公開

はじめに

npmパッケージ作成にViteのライブラリモードが便利そうだったので試してみました。

Viteのプロジェクトを生成する

参考: 最初の Vite プロジェクトを生成する

npm create vite@latest

publicディレクトリなどの不要なファイル等は削除します。

開発するファイルを作成

今回は適当に色付きのコンソールログを作成。

src/lib/cclg/index.ts
src/lib/cclg/index.ts
/**
 * @property label log text
 * @property color color of the label
 * @property bgColor background color of the label
 * @property value value of the label
 * @cStyle cStyle style of the label
 * @type type log type
 */
type TCclg = {
  label: string
  color?: string
  bgColor?: string
  value?: string | number | object | null | undefined
  cStyle?: string
  type?: 'log' | 'info' | 'warn' | 'error'
}

const getConsole = (type: 'log' | 'info' | 'warn' | 'error' | undefined = 'log') => {
  switch (type) {
    case 'log':
      return console.log
    case 'info':
      return console.info
    case 'warn':
      return console.warn
    case 'error':
      return console.error
    default:
      return console.log
  }
}

/**
 * custom console
 * @param args {@link TCclg}
 * @returns console medhod
 */
export const cclg = ({ label, color, bgColor, cStyle, value, type }: TCclg) => {
  const _color = color ?? '#000000'
  const style = cStyle ?? `color: ${_color}; background: ${bgColor}; padding: 2px 4px;`

  const console = getConsole(type)

  if (value) return console(`%c${label}`, style, `${value}`)
  return console(`%c${label}`, style)
}

実際に使うとこんな感じになります。

src/main.ts
import { cclg } from './lib/cclg'

cclg({ label: 'any label' })
cclg({ label: 'color', color: '#ff1493' })
cclg({ label: 'color bgColor', color: '#ffffff', bgColor: '#39c093' })
cclg({ label: 'color bgColor value', color: '#ffffff', bgColor: '#39c093', value: '123456789' })
cclg({ label: 'cStyle', cStyle: 'color: #ffffff; background: #ff8c00; padding: 4px 12px;' })
cclg({ label: 'type log', type: 'log' })
cclg({ label: 'type info', type: 'info' })
cclg({ label: 'type warn', type: 'warn' })
cclg({ label: 'type error', type: 'error' })

vite.config.jsを作る

Viteをライブラリモードとして使うためにvite.configを設置します。

vite.config.js
import { resolve } from 'path'
import { defineConfig } from 'vite'

export default defineConfig({
  build: {
    lib: {
      entry: resolve(__dirname, 'src/lib/cclg/index.ts'),
      name: 'index',
      fileName: 'index',
    },
  },
})

ビルドしてみる

npm run build

Viteはデフォルトではesumdフォーマットが生成されるようです。
参考: #build-lib

dist
 ┣ index.js
 ┗ index.umd.cjs

型定義(d.ts)ファイルを出力する

Viteでプロジェクトを作成するとtsconfigでnoEmittrueになっていて、型定義ファイルが生成されません。以下のDiscussionではvite-plugin-dtsというプラグインが紹介されていました。

https://github.com/vitejs/vite/discussions/7509

こちらのプラグインを使ってもいいですが、今回はこれは使わずにやりました。

tsconfig.jsonを修正

Viteでプロジェクト作成した状態のままだとtsconfigで型定義ファイルを生成しない設定になっているので、生成するように設定を変えます。

{
  "compilerOptions": {
    ...
+    "emitDeclarationOnly": true,
+    "declaration": true,
+    "declarationDir": "./types",
-    "noEmit": true,
    ...
  },
  "include": ["src/lib"]
}

参考: TypeScript: Documentation - .jsファイルから.d.tsファイルを生成する

buildスクリプトを修正

初期設定だと以下のようになっています。

package.json
"build": "tsc && vite build",

これだとtscコマンドで型定義ファイルを出力した後にvite buildコマンドでファイルが消されてしまいます。これについては下記のDiscussionで聞いてる人がいました。buildコマンドのemptyOutDirフラグをfalseにするといいよとありました。

https://github.com/vitejs/vite/discussions/4839

ただここではコマンドの順番を逆にすれば問題なさそうだったのでそうしました。
先にvite buildをしてからtscを実行するようにします。

package.json
"build": "vite build && tsc",

これでnpm run buildすると以下のようにd.tsファイルもdistフォルダに残ります。

dist
 ┣ index.d.ts
 ┣ index.js
 ┗ index.umd.cjs

package.jsonを修正

公開に必要そうな項目を修正します。

{
  ...
+  "main": "./dist/index.umd.cjs",
+  "module": "./dist/index.js",
+  "types": "./dist/index.d.ts",
+  "author": "takashi_shiratori",
+  "license": "MIT",
+  "repository": {
+    "type": "git",
+    "url": "https://github.com/t-shiratori/cclg"
+  },
+  "files": [
+    "dist"
+  ],
+  "exports": {
+    ".": {
+      "require": "./dist/index.umd.cjs",
+      "import": "./dist/index.js"
+    }
+  },
  ...
}

参考

NPMにパブリッシュ

npmアカウントがない場合は作成します。
npm | Sign Up

npmにログイン

npm login

npmに公開

npm publish

https://www.npmjs.com/package/cclg

https://github.com/t-shiratori/cclg

Discussion