【kintone/プラグイン】plugin-uploaderでハマった話【dev活】

# 前置き

### 勉強会いってきた。

先日、サイボウズさん主催のdevCampプラグイン基礎編に行ってきました。
とても為になるお話が聞けたり、他のエンジニアさん達と意見交換できたり、とても素敵な時間を過ごさせていただきました！！😁
特に、APIトークンを使用した安全なREST APIの使い方については、ちょうど実務で困っていた箇所だったのでめちゃめちゃ助かりました……！！

### モチベのあるうちに触っとこう。

と思い、復習ついでに、勉強会内ではさらっと流されたplugin-packerにも触れていくことにしました。
そこで、[お手本](https://cybozu.dev/ja/kintone/sdk/development-environment/create-plugin/)を見ながら進ていたですが、うまくいかないところが多々あったので備忘録として残します。


# 【本題】plugin-uploaderでハマった
前提：[お手本](https://cybozu.dev/ja/kintone/sdk/development-environment/create-plugin/)のcreate-pluginのStep2まで素直に従って、補足に記載の`npm start`でパッケージングする。

### plugin-uploadeのインストール
[plugin-uploadeのお手本](https://cybozu.dev/ja/kintone/sdk/development-environment/plugin-uploader/)通りインストールする。
`npm install -g @kintone/plugin-uploader`


### plugin-uploadeの実行
次にkintoneにアップロードしようと思い、
`kintone-plugin-uploader --base-url https://examle.cybozu.com --username ログイン名 plugin.zip`
を実行すると……

![スクリーンショット 2024-09-21 021332.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/956154/4e444dbf-c866-345a-3c31-82724ca7e86f.png)
見たことあるエラー
PowerShell のスクリプトファイル実行させないぞってやつが出てきました。


「単純にps1がダメならcmdに書き換えようかなぁ……」とファイルを探すと、
![スクリーンショット 2024-09-21 022830.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/956154/5784b4ce-7ecb-5df5-cd7a-068fa4fdff3a.png)
cmdファイルあるじゃん

### plugin-uploade.cmdの実行
デフォルトでps1ファイルが優先されるなら、cmdを指定したら通るのでは？
と考え、以下を実行
`kintone-plugin-uploader.cmd --base-url https://examle.cybozu.com --username ログイン名 plugin.zip`

![スクリーンショット 2024-09-21 023724.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/956154/5959e0a5-cb87-8410-39ff-033e0fd879d4.png)
通った！！やった！！


### と思ったらログインエラー

![スクリーンショット 2024-09-21 024511.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/956154/6ad2a879-3fe2-6d5c-60b1-331d0ee05ccc.png)
なんやて。
ユーザー名はコピペしたから間違いないし、そもそもパスワード聞かれてないのになんで？？
ここで数時間悩む。

### そうだ、パスワードも一緒に書いちゃえ
`kintone-plugin-uploader.cmd --base-url https://examle.cybozu.com --username ログイン名 --password パスワード plugin.zip`
![スクリーンショット 2024-09-21 025132 - コピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/956154/03bfa8b7-caf2-4e8d-f3b3-36aa75a9c040.png)
あ、通った。ラッキー。
（あの数時間はなんだったんだ……）
[追記：npmのサイトにちゃんと使い方書いてた😢](###2024/10/04)

### 喜びも束の間
なんか凄そうなエラーが出た。
![スクリーンショット 2024-09-21 025132.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/956154/f1f99f99-c685-bce6-ff29-a1a60482b30f.png)
こんな時こそ冷静になってエラーメッセージを検索しよう！

### プラグインzipファイルのパスが違った
`npm start`でパッケージングすると、plugin.zipはdistフォルダの中に生成されます。

![スクリーンショット 2024-09-21 030245.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/956154/32bd6397-4628-7e29-edd2-9d432cf00fd1.png)
なので、plugin.zipを指定するパスを正しくすれば通るはず……

### plugin.zipのパスを修正
以下を実行
`kintone-plugin-uploader.cmd --base-url https://examle.cybozu.com --username ログイン名 --password パスワード dist\plugin.zip`

![スクリーンショット 2024-09-21 030731.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/956154/672531e4-f7e9-d3e9-dcf3-534d4623a28f.png)
キターーーーーーーーー！！！！脳汁ブシャーーーー！！！！

### kintoneからも確認する
kintoneシステム管理>プラグインから確認します。
ちゃんと入ってますね。
![スクリーンショット 2024-09-21 031324.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/956154/212a7234-4d97-01bc-978e-7e8f3f3f0579.png)


# 【おまけ】"npm run upload" was failed
### 事件はまだ終わってない
本編は円満に解決したと思ったのにfailedとはどういう事だ？？
![スクリーンショット 2024-09-21 032716.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/956154/69628fc3-daa0-9cc9-270a-61842bbb9883.png)

### そもそも`npm start`ってなんだろう？
[虎の巻さん](https://npm.command-ref.com/cmd-npm-start.html)曰く、

>npm startは、package.jsonのstartに定義されたコマンドを実行するコマンドです。

とのことです。

### package.jsonを調べてみよう

```sample_plugin_project\package.json
{
  "name": "watchYoutubeOnKintone",
  "version": "0.1.0",
  "scripts": {
    "start": "node scripts/npm-start.js", 
    "develop": "npm run build -- --watch",
    "build": "kintone-plugin-packer --ppk private.ppk --out dist/plugin.zip src",
    "lint": "eslint src",
    "upload": "kintone-plugin-uploader dist/plugin.zip --watch --waiting-dialog-ms 3000"
  },
  "devDependencies": {
    "@cybozu/eslint-config": "^23.0.0",
    "@kintone/plugin-packer": "^8.1.3",
    "@kintone/plugin-uploader": "^9.1.2",
    "eslint": "^8.57.0",
    "npm-run-all": "^4.1.5"
  }
}
```
おそらく、我々は5行目のstartを呼び出している。（きっと、たぶん）
`npm start`は`node scripts/npm-start.js`を実行させているっぽい。

### npm-start.jsの中身を見る。
いかにも一番初めに実行されるぜって名前のファイルだ。
```sample_plugin_project\scripts\npm-start.js
"use strict";
const runAll = require("npm-run-all");

runAll(["develop", "upload"], {
  parallel: true,
  stdout: process.stdout,
  stdin: process.stdin
}).catch(({results}) => {
  results
    .filter(({code}) => code)
    .forEach(({name}) => {
      console.log(`"npm run ${name}" was failed`); //ここが呼び出されている
    })
  ;
});

```

このコードは、package.jsonに定義されたdevelopとuploadを平行実行させる処理だと推測できる（多分、おそらく）
という事は、"npm run upload" was failedは、

### uploadコマンドが通っていない。
つまり、sample_plugin_project\package.jsonファイルの9行目
`"kintone-plugin-uploader dist/plugin.zip --watch --waiting-dialog-ms 3000"`
が犯人！！！！

### 手動でアップロードした時のコマンドを参考に修正する
```sample_plugin_project\package.json
{
  "name": "watchYoutubeOnKintone",
  "version": "0.1.0",
  "scripts": {
    "start": "node scripts/npm-start.js", 
    "develop": "npm run build -- --watch",
    "build": "kintone-plugin-packer --ppk private.ppk --out dist/plugin.zip src",
    "lint": "eslint src",
    "upload": "kintone-plugin-uploader --base-url https://examle.cybozu.com --username ログイン名 --password パスワード dist/plugin.zip --watch --waiting-dialog-ms 3000"
  },
  "devDependencies": {
    "@cybozu/eslint-config": "^23.0.0",
    "@kintone/plugin-packer": "^8.1.3",
    "@kintone/plugin-uploader": "^9.1.2",
    "eslint": "^8.57.0",
    "npm-run-all": "^4.1.5"
  }
}
```

### 動作確認
#### 1.コマンドプロンプトに`npm start`を入力する
![スクリーンショット 2024-09-21 045632 - コピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/956154/f5ac8d56-8041-82d8-1380-a4932e615e2b.png)
ちゃんと動いてる……！！


#### 2.カスタマイズファイル本体にコメントを追記し、保存する。
```例）sample_plugin_project\src\js\desktop.js
//省略

    if (spaceEl === null) {
      throw new Error('The header element is unavailable on this page.');
    }
    console.log('hello cyboz');  //コメントを追記

    const fragment = document.createDocumentFragment();
    const headingEl = document.createElement('h3');


//省略
```
![スクリーンショット 2024-09-21 045632.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/956154/c9310a55-e74d-ca13-a4ff-7251a6dd5fe8.png)
動いた！！！！

#### 3.kintone環境で確認
サンプルプラグインの設定を入力、保存する。
![スクリーンショット 2024-09-21 050537.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/956154/1996a236-4b4d-241b-22be-28847852bfea.png)

アプリを開き、コメントが表示されていることを確認する
![スクリーンショット 2024-09-21 050520.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/956154/0e28371f-2a6c-c5f9-bdaf-e4545d45dee0.png)

#### 4.監視の停止
Ctrl+cで監視を終了することができる
パッチジョブを終了するか聞かれたら`y`と入力
![スクリーンショット 2024-09-21 162210.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/956154/75cdc823-a40c-7d3e-177c-563525c70a93.png)

### まとめ
sample_plugin_project\package.jsonファイルの9行目を
`"upload": "kintone-plugin-uploader --base-url https://examle.cybozu.com --username ログイン名 --password パスワード dist/plugin.zip --watch"`
に変えたら、保存するごとに変更を検知してプラグインをアップロードできる！！楽！！


:::note warn
※注意

今回はsample_plugin_project\package.jsonに直接パスワード書いちゃってるので、取り扱いには十分にご注意ください。
:::

# 最後に
kintoneってすごいなぁというのを改めて感じました……
これを機に、気が向いたらまた投稿しようかなと思います。
ご質問やご指摘等ございましたらお気軽にコメントください。

閲覧ありがとうございました！

# 追記
### 2024/10/04
npmのサイトにちゃんと使い方書いてた😢

https://www.npmjs.com/package/@kintone/plugin-uploader

# 参考資料
https://cybozu.dev/ja/kintone/sdk/development-environment/create-plugin/

https://cybozu.dev/ja/kintone/sdk/development-environment/plugin-uploader/

https://qiita.com/sugurutakahashi12345/items/2a17a3cdfbc4a7e5e4eb

https://npm.command-ref.com/cmd-npm-start.html

https://reon777.com/2023/07/04/kintonetimeoutupload/#google_vignette