[Vue.js] オリジナルコンポーネントをnpmに公開する方法

## 環境

この記事を書くのに使った環境は以下の通りです。

```c
$ npm -version
6.9.0

$ vue --version
3.8.3
```

## Vue CLI のインストール

Vue CLIをグローバルインストールします。

```c
$ npm install -g vue-cli

~~中略~~
+ @vue/cli@3.8.3
added 877 packages from 554 contributors in 213.92s
```

この記事で紹介しているnpmへの公開方法は、Vue CLI 3以上のバージョンが必要なので、イントールされたバージョンを確認してください。もし2.x系のVue CLIがインストールされている場合、一度アンインストールしてからインストールしてください。

## 公開するコンポーネントのVueプロジェクトを作成

Vueのプロジェクトを作成するフォルダに移動します。

```
$ cd path/to/dir
```

次に、プロジェクトを作成します。コマンド入力後、質問形式で設定を聞かれるので答えます。

```
$ vue create <component-name>

Vue CLI v3.8.3
? Please pick a preset: default (babel, eslint)
? Pick the package manager to use when installing dependencies: NPM
```

プロジェクトの作成が完了したら、とりあえず動かしてみましょう。

```
$ cd <component-name>
$ npm install
$ npm run serve
```

ブラウザで`http://localhost:8080`にアクセスします。

![Vueテンプレートプロジェクとを起動した画面](https://lh3.googleusercontent.com/nCT_oibJaF_IsAQYI2riW8UPpFebVg_XDdQHWfEuQfFSEoIjTuMCE1NVIWAxLHBqMxE1kLqU-Ode)

## フォルダ構成

この記事では、最終的に以下のようなフォルダ構成になるように、コンポーネントおよび必要ファイルを作成していきます。

```c
├── src
│   ├── components
│   │   └── MyComponent.vue  //(1)公開するコンポーネント
│   ├── library-main.js      //(2)使われる時に自動でvue.useする為のwrapper
├── package.json             //(3) プロジェクトの情報
~~中略~~
```

`vue create`でプロジェクトを作成すると、上で書いた必要なファイル以外にも、色々とファイルが作成されますが、消す必要はなく、ほっておいても大丈夫です。

## インストールラッパーを作成する

コンポーネント使用時に自動的に`Vue.use()`を行うインストールラッパーを作成します。以下はVueの公式サイトに掲載されているサンプルコードです。基本的にそのまま使えますが、<span class="maru">(1)(2)</span>の部分だけは、公開するコンポーネント名に置き換えてください。


```js:library-main.js
// コンポーネントのインポート
import component from './components/MyComponent.vue'; //(1)Vueのファイル名に変更

// Vue.use() によって実行される install 関数を定義
export function install(Vue) {
	if (install.installed) return;
	install.installed = true;
	Vue.component('MyComponent', component); //(2)コンポーネント名を変更
}

// Vue.use() のためのモジュール定義を作成
// Create module definition for Vue.use()
const plugin = {
	install,
};

// vue が見つかった場合に自動インストールする (ブラウザで <script> タグを用いた場合等)
let GlobalVue = null;
if (typeof window !== 'undefined') {
	GlobalVue = window.Vue;
} else if (typeof global !== 'undefined') {
	GlobalVue = global.Vue;
}
if (GlobalVue) {
	GlobalVue.use(plugin);
}

// (npm/webpack 等で) モジュールとして利用させるためコンポーネントを export する
export default component;
```

## 公開するコンポーネントを実装する

npmに公開するコンポーネントを実装します。公開するからと言って変わった点はなく、普通にコンポーネントを実装していきます。

```html:MyComponent.vue
<template>
  ~~コンポーネントのテンプレート~~
</template>
<script>
export default {
  ~~コンポーネントの実装~~
}
</script>
<style scoped>
  ~~コンポーネントのスタイル~~
</sytle>
```

## package.jsonを編集


```js
{
  "name": "my-component",  //(1)npmに公開するコンポーネント名
  "version": "0.1.0", 
  "private": false,        //(2)npmに公開する為、falseに変更
  "main": "dist/my-component.common.js",          //(3)エントリポイント
  "unpkg": "./dist/my-component.umd.min.js",      //(4)unpkg公開用
  "jsdelivr": "./dist/my-component.umd.min.js",   //(5)jsdelivr公開用
  "typings": "dist/types/index.d.ts",  
  "license": "MIT",        //(6)ライセンス
  "author": "<作成者>",     //(7)作成者
  "files": [ "dist" ],     //(8)npmに公開するフォルダやファイル
  "keywords": ["Vue", "Vue.js", "xxxx", "xxxx"],  //(9)パッケージマネージャー用のキーワード
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint",
    "build-bundle": "vue-cli-service build --target lib --name my-component ./src/library-main.js"　
    //(10)npmに公開するライブラリ生成用のコマンド
  },
  "dependencies": {
    "core-js": "^2.6.5",
    "vue": "^2.6.10"
  },
  ~~中略~~
}
```

## npmのサインアップ

npmのアカウントを持っていない場合は、以下のURLからアカウントを登録して、サインアップします。

[https://www.npmjs.com/signup](https://www.npmjs.com/signup)

![npmのサインアップ画面](https://lh3.googleusercontent.com/NELdb-OXXZLBOryBaCcQHxMxW7Da7d1HQa_0yU9AnqHgI2zqxgExys34MNiBen1z0_X7BymPSOd_=w300)

## npmにログイン

以下のコマンドを入力して、npmにログインします。コマンドを入力すると、ユーザ名/パスワード/メールアドレスを聞かれますので、サインアップ時に登録した内容を打ち込みます。

```
$ npm login
```

### ビルドをする

package.jsonに追加したライブラリ生成用のコマンドを入力して、ビルドを行います。

```
$ npm run build-bundle
```

##   npm publishで公開する

以下のコマンドで、npmにコンポーネントを公開します。

```
$ npm publish
```

[https://www.npmjs.com/](https://www.npmjs.com/)にアクセスにして、自分が公開したコンポーネントが検索できるか確認してみましょう。


## README.md を書こう

テンプレートで作成された`README.md`をnpmに公開すると、下のように寂しい感じになっているので、セットアップ方法やAPIなどの説明を書くようにしましょう。

![テンプレートで作成されたnpmファイル](https://lh3.googleusercontent.com/tuxkOdKtP7PbhW5nwyQktPI3NsEgDtQ5lSnBW7oNJtMTMOVnnYBGVYvTLGD8s_fE-ZKxhEn5yW2X)


## 変更した内容を公開する

バグ修正・新機能追加・README.mdの修正など、作成したコンポーネントを変更した場合、`npm publish`で再度公開します。npmでは**同じバージョンでpublishするとエラーになる**ので、バージョンを上げてから`npm publish`をする必要があります。

バージョンを上げる方法には、以下の2つのやり方があります。

### [1] npm versionコマンドを使う

npmには、package.jsonのバージョンを上げるコマンドが容易されています。

```
npm version [option]
```

`[option]`には以下を指定します。指定するオプションによって、バージョンの上がり方が違います。

option  | 実行後のバージョン
:-- | :--
major | **2**.0.0
minor | 1.**1**.0 
patch | 1.0.**1**
premajor | **2**.0.0<b>-0</b>
preminor | 1.**1**.0<b>-0</b>
prepatch | 1.0.**1-0**
prerelease | 1.0.**1-0**

### [2] package.jsonを直接編集する

上のコマンドでバージョンを上げるのは必須ではない為、package.jsonのversionを手動で書き換えてもOKです。

```js:package.json
{
  "version": "0.1.1", 
}
```

## npmに公開したコンポーネントの使い方

npmに公開すれば、あとは普通にnpmのコマンドで、コンポーネントがインストールできます。

### コンポーネントのインストール

```c
npm i my-component --save
```

### コンポーネントを使う

importにコンポーネントとCSSを入れてあげると、作成したコンポーネントが使えます。

```html
<template>
  <my-component/>
</template>
<script>
import MyComponent from 'my-component'
import 'my-component/dist/my-component.css'

export default {
  components: {
    MyComponent
  }
}
</script>
```


## さいごに

Vue.jsでオリジナルコンポーネントをnpmに公開する方法と、公開した後に、実際にコンポーネントを使う手順を紹介してきました。VUE-CLI3を簡単に公開できて楽です。