クロスプラットフォームで動作するデスクトップ通知コマンド「@neos21/simple-notify」を作った

デスクトップ通知を CLI から行える npm パッケージ、なんて何百番煎じだよ、とは思うが、OS 判定に関するコードを作って残しておきたかったので、ちょっと作ってみた。

npm でグローバルインストールすると、$ simple-notify 'メッセージ' という感じでコマンド実行できる。

という感じで、内部では OS を判別して実行するコマンドを別けている。

PowerShell でトースト通知を送るコマンドを組み立てるのが大変だった。過去記事で BurntToast というモジュールを紹介したが、コレが内部で使っているような Windows API を使っている。

タイトルやアイコンなどを XML 形式で書いて実行したりとか、色んな呼び出し方があるのだが、ワンライナーで呼び出せているコードがどこにもなく、今回自分で頑張って組み立てた。

OS 判定について、特に WSL 環境の見極めをできるようにしておきたいなと思ったのだが、os.release() を見れば microsoft の文字が出てくるので WSL かどうか区別が付く、というやり方が多いようだった。Bash だと $ uname -amicrosoft の文字列が登場するので見極められる。Sindre Sorhus 氏が is-wsl というパッケージを作っていて、まぁ大体同じだった。

npm (Node.js) の良いところは、コンパイルが要らない点だと思っていて、Windows のコマンドプロンプトでも PowerShell でも GitBash でも、MacOS でも Linux でも、Node.js が直接 JS コードを動かしてくれるので、リリース時にクロスコンパイルとかのことを考えずにコマンドが提供できるのが便利だと思っている。

最近は Go や Rust が人気で、Zig はクロスコンパイルが得意だとか言われているけど、それでもクロスプラットフォーム対応はまだ引っかかりやすいところがあり、「Windows でも Mac でも同じ JS ファイルがそのまま実行可能ファイルとしてコマンド化できる」というのは Node.js の強みだと思う。シェルスクリプト (.sh.bash) もコマンドプロンプトや PowerShell では実行できないから、コマプロや PowerShell からの呼び出しでも動く方法としては Node.js でラッパースクリプトを書いてやるのが一番手っ取り早いだろう。

今回はデスクトップ通知をクロスプラットフォームで実現してみたが、他にも

のそれぞれをラップするパッケージなんかを作ったら面白いかなーと思っている。wsl-open という WSL 向けのコマンドは既にあるが、コレの中身はシェルスクリプトだし (npm パッケージとして公開されているが JS ファイルは一切ない)、WSL から xdg-openstart コマンドを実行してもよしなにやってくれるので、簡単に動けば良いなら今回と似たようなコードで実現できそうだ。

というワケで、クロスプラットフォーム対応コマンドを作るには Node.js スクリプトでラップするのが良いんじゃね?というお話でした。