UnityのPackageManagerに自分のパッケージを入れるまで

# 概要

最近、自作のEditor拡張等を入れてAssetフォルダに増えるのが厳しい感じがしたので、Unityの機能であるPackageManagerに登録することにしました。その備忘録になります。
PCに直接npmやらVerdaccio入れるのはつらい気持ちがあるので、Dockerなるものを使います。

# 材料
※私の環境はWindows10 Homeのため
* [Docker Toolbox](https://github.com/docker/toolbox/releases) - v19.03.1

# 手順
### 1. 下準備
上記のDocker Toolboxはあらかじめインストールしておきます。
参考 - [Windows環境にDocker Toolboxをインストールする](https://qiita.com/KIYS/items/8ac37f6757a6b7f84569)

### 2. docker-compose.ymlを作る
docker composeってなんぞや？
> Compose とは、複数のコンテナを使う Docker アプリケーションを、定義・実行するツールです。Compose はアプリケーションのサービスの設定に、Compose ファイルを使います。そして、コマンドを１つ実行するだけで、設定した全てのサービスを作成・起動します。 - [Docker ドキュメント日本語化プロジェクト](http://docs.docker.jp/compose/overview.html)より

その複数のコンテナを使う Docker アプリケーションを、定義するためのファイルがdocker-compose.ymlとのことです。
まずは今回のプロジェクト用のフォルダを作成し、その中にdocker-compose.ymlファイルを配置します。
フォルダ構成はこんな感じ。(Cドライブのどこかに置くこと)

```
- LocalNpmPackageServer
  ├ verdaccio
  │ ├ config
  │ │ └ config.yml
  │ ├ plugins
  │ └ storage
  └ docker-compose.yml
```
中身は下記

```yml:docker-compose.yml
version: '3.1'

services:
  verdaccio:
    image: verdaccio/verdaccio
    container_name: "verdaccio"
    networks:
      - node-network
    environment:
      - VERDACCIO_PORT=4873
    ports:
      - "4873:4873"
    volumes:
      - "./verdaccio/storage:/verdaccio/storage"
      - "./verdaccio/config:/verdaccio/conf"
      - "./verdaccio/plugins:/verdaccio/plugins"  
networks:
  node-network:
    driver: bridge
```

今回はUnityのPackageManagerのレジストリサーバーとして、Verdaccioの構成を定義しています。

### 3. config.yamlを作る
Verdaccioのコンフィグファイルを作成します。docker-compose.ymlのvolumesに定義されている ./verdaccio/configに配置します。
中身は下記。

```yml:config.yml

storage: ../storage
auth:
  htpasswd:
    file: ./htpasswd
uplinks:
  npmjs:
    url: https://registry.npmjs.org/
packages:
  '**':
    access: $all
    publish: $authenticated
    proxy: npmjs
logs:
  - {type: stdout, format: pretty, level: http}
```
ここで定義されているstoregeの位置はdocker-compose.ymlのvolumesに定義した./verdaccio/storageの位置です。

### 4.起動する
Docker Toolboxを入れたタイミングでDocker Quickstart Terminalが追加されているはずなので、起動します。
くじらのAAの黒い画面が出てきたら、`docker is configured to use the default machine with IP なんとか`と、IPアドレスが出ているので覚えておきましょう。
そしてdocker-compose.ymlを置いたプロジェクトフォルダへ移動します。

```powershell:コマンド
cd "プロジェクトフォルダのパス"
```

移動したらDockerを起動するためのコマンドを入れます。

```powershell:コマンド
# デーモン状態で起動する場合はこっち(このターミナルを閉じても動いてる)
docker-compose up -d

# 普通に動かす場合はこっち
docker-compose up
```
` http://先ほど出ていたIPアドレス:4873`をブラウザに入れて、Verdaccioの画面が表示されたらこれで環境は作成完了です。

### 5. パッケージを作成する
参考 - [UNITYPACKAGEMANAGERのレジストリサーバーを立てる話](https://developers.10antz.co.jp/archives/361)

Unityでの作業になります。

* パッケージ構成について

個人的にはこのようなフォルダ構成にしています。

```
- OriginalPackage
  │ ├ Runtime
  │ │ └ OriginalPackage.Runtime.asmdef
  │ ├ Editor
  │ │ └ OriginalPackage.Editor.asmdef
  └ package.json
```
この時に注意するのはEditorのAssembly DefinitionのPlatformsの設定で、Any Platformのチェックを外し、Editorのみにしておきます。
また、後ほどPackageManagerからインストールする際に既に存在しているとインストールできないため、同じプロジェクトに入れる場合は最初の作成が終わったら登録する前に別の(プロジェクト外の)場所に移しておきましょう。

* package.jsonについて

中身は下記

```json:package.json
{
  "name": "jp.co.mypackage.originalpackage",
  "displayName": "Original Package",
  "version": "1.0.0",
  "unity": "2018.1",
  "description": "My original package.",
  "keywords": [
  	"editor"
  ],
  "category": "",
  "relatedPackages": {},
  "dependencies": {},
  "repository": {},
  "author": {
    "name": "My Name",
    "url": ""
  },
  "license": {
    "type": "MIT",
    "url": "https://monry.mit-license.org"
  }
}
```
このうち、上から5項目(name・displayName・version・unity・description)は必須です。
上記の必須でない項目の一部はVerdaccioで表示されたりします。

### 6.パッケージを登録する
またDocker Quickstart Terminalに戻ります。

まずユーザー登録をします。

```powershell:コマンド
npm adduser --registry  http://4で出てたIP:4873
```
ユーザー名、パスワード、メアドを登録します。
で、ログイン。

```powershell:コマンド
npm login --registry  http://4で出てたIP:4873
```

で、登録。

```powershell:コマンド
cd "OriginalPackageのフォルダパス"
npm publish --registry  http://4で出てた:4873
```

これで登録完了です。
ちなみに上記のコマンドたちは、立ち上げたVerdaccioのページに書いてあるのでコピペすると良いです。

この状態でVerdaccioのページを読み込み直すとパッケージが登録されているのが確認できると思います。

### 7.UnityのPackageManagerからインストールする
最後です。Unityのプロジェクトフォルダ/Package/manifest.jsonを開きます。
そこに下記のようにscopedRegistriesを追加します。(dependencies以下は元からあるはずです)

```json:manifest.json
{
  "scopedRegistries": [
    {
      "name": "my-package-name",
      "url": "http://4で出てたIP:4873/",
      "scopes": [
        "jp.co.mypackage"
      ]
    }
  ],
  "dependencies": {
    "com.unity.collab-proxy": "1.2.16",
    "com.unity.ide.rider": "1.1.4",
    "com.unity.ide.vscode": "1.1.4",
    "com.unity.test-framework": "1.1.11",
    "com.unity.textmeshpro": "2.0.1",
    "com.unity.timeline": "1.2.12"
  }
}
```

これでUnityに戻りPackageManagerを見ると出ていると思います。