MQTTクライアントをコマンドラインで簡単に実行する（npx と MQTT.js）

## はじめに
こちらのツイートをきっかけに、ふと思いついて試した内容のメモです。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">npxで実行できるMQTTクライアントってないのかなぁ <a href="https://twitter.com/hashtag/iotlt?src=hash&amp;ref_src=twsrc%5Etfw">#iotlt</a></p>&mdash; 菅原のびすけ (@n0bisuke) <a href="https://twitter.com/n0bisuke/status/1308754318124748808?ref_src=twsrc%5Etfw">September 23, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

【追記】 @n0bisuke さんも記事を書かれていたので、リンクを掲載します。
　●グローバルインストールせずにMQTTをCLIで試す - Qiita
　　https://qiita.com/n0bisuke/items/13d1442f3cb67664ef60

@n0bisuke さんの記事では、自分の記事では触れていない [PubNub](https://www.pubnub.com/) の場合の事例も書かれてますので、是非ご覧ください。

## MQTTクライアントをコマンドラインで簡単に動かす
IoT系のプロトタイプを作るときに、最近はよく MQTT を使っていました。
そして、以下のような様々な環境で MQTT のクライアントを動かしていました。

- Node.js
- HTML+JavaScript で作られた Webサイト
- Node-RED
- UIFlow （M5Stack向けのビジュアルプログラミング環境）
- Mac や Windows の上で動く GUIフロントエンドとなるアプリ
- ターミナル上などコマンドを使った形

上記の Node.js や Webサイト（HTML+JavaScript）で実装するときは、パッケージ・ライブラリに [MQTT.js](https://github.com/mqttjs/MQTT.js) をよく使っていました。また、Mac のターミナル上のコマンドラインツールで動作させる時も MQTT.js を使いました。

![mqttjs_Command_Line_Tools.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/ad5f3df0-6e96-dbf1-b322-ecc690cc6076.jpeg)

この記事の冒頭のツイートを見た時に、この MQTT.js のコマンドラインツールを思い出し、ふと「MQTT.js のコマンドラインツールが使えてしまうのではないか？」と思って試しました。ローカルに [mosquitto](https://mosquitto.org/) で MQTTブローカーをサクッと実行できる環境はあったので、 `npx mqtt sub -t 'test' -h 'localhost'` とか `npx mqtt pub -t 'test' -h 'localhost' -m 'from MQTT.js'` とかを実行してみて、Pub/Sub の両方とも動作するのを確認し、この記事の冒頭のツイートに以下のコメントをしました。

<blockquote class="twitter-tweet" data-conversation="none"><p lang="ja" dir="ltr">Sub のほうなら、MQTT.js で「npx mqtt sub -t &#39;トピック&#39; -h &#39;ホスト名&#39;」みたいなの感じでどうでしょう？<br>（意図と異なるかもですが）<br><br>Pubのほう、「npx mqtt pub -t &#39;トピック&#39; -h &#39;ホスト名&#39; -m &#39;from MQTT.js&#39;」とかやったら、メッセージを送るたびにインストールがされて微妙でしたがｗ</p>&mdash; you (@youtoy) <a href="https://twitter.com/youtoy/status/1308775232446971908?ref_src=twsrc%5Etfw">September 23, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## 【追記】 MQTT.js のコマンドラインツールを npx で実行した時の挙動の補足
### MQTT.js がインストールされていない環境で実行
サブスクライブのほうは、 `npx mqtt sub -t '【トピック】' -h '【ホスト名】'` とすると、MQTTブローカーへの接続を維持した状態になり、メッセージを受信し続けてくれてます。

パブリッシュのほうは、 `npx mqtt pub -t '【トピック】' -h '【ホスト名】' -m '【メッセージ】'` を実行すると、1回パブリッシュした後に処理が終了します。その処理終了の際にパッケージのファイル一式が削除されるので、その後コマンドを実行するごとにインストールが行われるという挙動になります。

### MQTT.js をローカルインストールしたフォルダ上で実行
npx は、パッケージがインストールされていない環境だと、処理の実行に必要なパッケージをコマンド実行時に一時的にインストールして、処理が終わるとインストールしたファイルを破棄します。
もし、処理の実行に必要なパッケージがローカルインストールされている場合、そのローカルのパッケージを利用して処理を実行します（インストールされたフォルダ内でコマンドを実行する必要あり）。

そのため、自分でローカルインストールしたファイル一式を手動削除する必要が出てきますが、この方法ならパブリッシュするごとにインストールするような挙動は避けられます。インストールしていない状態での実行、という手軽さが失われてしまいますが・・・。

冒頭のツイートのコメントでのやりとりでも、少し触れてました。
<blockquote class="twitter-tweet" data-conversation="none"><p lang="ja" dir="ltr">ローカルインストールのものを<br>　$ ./node_modules/.bin/パッケージ名<br>でなく<br>　$ npx パッケージ名<br>とシンプルに呼び出せる、という使い方のほう（自分がよく使うのは、こちらだったり）。</p>&mdash; you (@youtoy) <a href="https://twitter.com/youtoy/status/1308778893071937538?ref_src=twsrc%5Etfw">September 23, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## 【追記】 npx について
npx を初めて使ってみようと思ったきかっけは、おそらくこちらの記事を見た時でした。

●npm 5.2.0の新機能！ 「npx」でローカルパッケージを手軽に実行しよう - Qiita
　https://qiita.com/tonkotsuboy_com/items/8227f5993769c3df533d

<blockquote class="twitter-tweet" data-conversation="none"><p lang="ja" dir="ltr">なるほど！<br><br>自分は、この記事だったかで、初めてnpxについて知った時に「インストールしていないパッケージを一度だけ実行できる機能」と合わせて「ローカルのnpmパッケージを使用するのが簡単になる」の両方を同時に見ていて、という感じでした。<br>　<a href="https://t.co/k8mUsdL5fZ">https://t.co/k8mUsdL5fZ</a></p>&mdash; you (@youtoy) <a href="https://twitter.com/youtoy/status/1308780656030150658?ref_src=twsrc%5Etfw">September 23, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

npx の利用について、自分は「何か特定のパッケージのコマンドライン実行を、ずっと使わないかもしれないけれど、とりあえずは試してみたい」というときなどに、以下のような使い方をしてたりします。

1） 適当にパッケージのお試しをするフォルダを作る
2） 上記1）で作ったフォルダで `npm install 【パッケージ名】` でパッケージをローカルインストール
3） `npx 【パッケージ名】' でローカルインストールしたパッケージを実行
4） お試しが終わったら、上記1）で作ったフォルダを丸ごと削除

ローカルインストールした場合、コマンドを実行したフォルダ直下に node_modules フォルダが作られて、その下にファイルが置かれるような構成になるので、コマンドを実行したフォルダを削除するだけでサクッとお試し用に追加されたファイル一式を丸ごと削除できます。

## おわりに
他にも、Node.js のパッケージでコマンドラインツールが使えるようなものがあったと思うので、MQTT.js 以外でも便利に使えそうなものがないか試してみようと思います。

### 【追記】 wscat（WebSocket関連）で試してみて、記事を書きました。

●WebSocket のサーバー・クライアントをコマンドラインで簡単に実行する（npx と wscat） - Qiita
　https://qiita.com/youtoy/items/72bbd5f6b0893756da36