🦕

Denoを開発するときにめっちゃ効率上げるコマンドを作った

2021/11/25に公開

以前、こちらの記事を公開しました。

https://zenn.dev/kawarimidoll/articles/0ff5d28fa584d6

Neovimでターミナルを開き、編集中のファイルに応じてdeno rundeno testを実行するというコマンドです。

開発用に、自動で--allow-allおよび--unstableをつけているので、実行時に必要なオプションを考える必要がありません。しかも--watchもしているのでコードを修正に反応して再起動します。
個人的に、かなり重宝しています。

https://twitter.com/KawarimiDoll/status/1456033511131926533

今回、こちらのコマンドをDenoスクリプトで作り直したので紹介します。

dex

A dexterous deno executor略してdexです。

https://github.com/kawarimidoll/deno-dex

https://ejje.weblio.jp/content/dexterous

機能

  • deno runおよびdeno testを簡単に自動実行できます。
    • 渡されたファイル名から自動でテストファイルかどうかを判断し、deno runまたはdeno testを実行します。
    • 自動で--allow-all --unstable --no-check --watchをつけて実行します。
  • 便利なオプションがあります。
    • --clearオプションを付けることで、リロードのたびにコンソールをクリアできます。
    • --watchオプションにファイルパスを渡すことで、実行対象ファイル以外の変更も監視することができます。
    • その他のオプションはdeno runまたはdeno testに透過的に渡されます。
  • 設定ファイルを自動で読み込みます。
    • カレントディレクトリにimport_map.jsondeno.jsoncなど所定の名前のファイルがある場合、自動的に実行オプションに渡します。
    • --import-mapおよび--configオプションの引数として指定されたファイル(自動指定されたものも含む)は自動的に変更監視対象となります。

導入

deno installで導入します。

deno install --allow-read --allow-write --allow-run --reload --force --name dex https://pax.deno.dev/kawarimidoll/deno-dex/main.ts

各権限は以下の理由で要求しています。

  • read: ファイル変更およびカレントディレクトリの監視
  • write: 中間実行ファイルの生成
  • run: denoコマンドの実行および中断

最新の変更を取り込めるよう、インストール時には--reload --forceをつけることを推奨します。

基本の使い方

引数として渡したファイルをdeno runで実行します。

dex hello.ts
# -> deno run --allow-all --unstable --no-check --watch hello.ts

テストファイルを渡すと、自動で判定してdeno testを実行します。

dex hello_test.ts
# -> deno test --allow-all --unstable --no-check --watch hello_test.ts

オプション

これだけではdeno run/test --allow-all --unstable --no-check --watchのエイリアスに過ぎませんが、--clear--watchオプションを使用することができます。
なお、その他のオプション(--version--helpを除く)は透過的にdeno run/testに渡されるので、--compat--quietなどのオプションも使用可能です。

この際の引数の処理に関してはこちらの記事で解説しています。

https://zenn.dev/kawarimidoll/articles/182d2ff9444375

自動でコンソールをクリアする

--clearオプションをつけることで、リロードのたびに画面をクリアできます。

以前紹介したNeovim用コマンドでもそうだったのですが、こちらの記事にインスパイアされました。

https://zenn.dev/yutaro_elk/articles/ce343b13506364

こちらの記事では編集対象のファイル内にconsole.clear()を置く方法が紹介されています。

dexでは以下のようなファイルを$DENO_DIR以下に生成し、それを実行しています。
ユーザーが明示的にconsole.clear()を書く必要はありません。

$DENO_DIR/dex/script.ts
console.clear();
import("path/to/file");

最初はこれをbase64化してdeno runに渡して実行できるかと思いしましたが、パス解決がうまくいかなかったため、$DENO_DIR以下に生成することにしました。

https://zenn.dev/kawarimidoll/articles/3f06083cb03b25

実行対象以外のファイルを監視する

deno run --watchでは実行対象のファイルおよびそのファイルがimportしているファイルの更新のみが監視対象となりますが、dexでは--watchオプションに追加したファイルはすべて監視対象になります。

たとえば、以下のようにsample.txtを表示するスクリプトがあるとき、

show_text.ts
console.log(await Deno.readTextFile("./sample.txt"))
sample.txt
This is sample text!

--watchオプションにsample.txtを指定すると、このファイルが更新されたタイミングでも自動リロードが走ります。

dex --watch=./sample.txt show_text.ts

,で区切って渡すことで複数ファイルの指定も可能です。

設定ファイル自動読み込み・監視

Denoの実行時に指定できる設定ファイルとして、 import mapsconfiguration fileがあります。

dex実行時、カレントディレクトリにimport_map.jsonがある場合、自動的に--import-mapオプションに渡します。
同様に、カレントディレクトリにdeno.jsonc deno.json tsconfig.jsonのいずれかがある場合、自動的に--configオプションに渡します(前のものほど優先)。
さらに、--import-mapおよび--configオプションの引数として指定されたファイル(自動指定されたものも含む)は自動的に変更監視対象となります。
つまり、実行中にdeno.jsoncに変更を加えた場合、自動的にリロードが走ります。

注意点

簡単実行がコンセプトなので、すべての権限を許可(--allow-all)・不安定動作許可(--unstable)・タイプチェックなし(--no-check)の完全ノーガード設定にしています。
開発環境での確認用であれば問題ないと考えていますが、外部のコードに対し使用する際は厳重に注意してください。

また、コード内でDeno.exit()が呼ばれると、即終了となるためリロードはできません。
これは通常のdeno run --watchの挙動と同様です。

おわりに

dexを使うと、権限全許可・設定ファイル自動監視機能により、細かい設定を考えなくてもとりあえず実行できるようになります。
以前作成したコマンドはNeovim専用でしたが、これでエディタに関わらず自動実行の恩恵を受けられます。
動作確認しながらの開発が非常に楽になると思うので、ぜひ使ってみてください。
https://github.com/kawarimidoll/deno-dex

ご感想、バグ報告、Star、何でも大歓迎です。どうぞよろしくお願いします。

Vim/Neovim連携

エディタに関わらず…とは書きましたが、筆者はNeovimユーザーなので、今回のdexをNeovim内で使えるようにしています。
以下の定義を設定ファイルに追記してご利用ください。Vimでも動作するはずです。

.vimrc or init.vim
command! -nargs=* -bang Dex silent only! | botright 12 split |
    \ execute 'terminal' (has('nvim') ? '' : '++curwin') 'dex'
    \   (<bang>0 ? '--clear ' : '') <q-args> ' ' expand('%:p') |
    \ stopinsert | execute 'normal! G' | set bufhidden=wipe |
    \ execute 'autocmd BufEnter <buffer> if winnr("$") == 1 | quit! | endif' |
    \ wincmd k

  • :Dexで現在のファイルに対しdexを実行します。
  • :Dex --quietのような感じでオプションを渡すことが可能です。
  • :Dex --clearのショートハンドとして、:Dex!が使えます。

Vim scriptでのウィンドウの扱いに関しては以前の記事で説明しているので、気になる方はご覧ください。

https://zenn.dev/kawarimidoll/articles/0ff5d28fa584d6

参考

--watchオプションの対象ファイルは自前で更新監視を行っています。この実装には、以下の記事を参考にしました。

https://dev.to/otanriverdi/let-s-explore-deno-by-building-a-live-reloader-j47

Discussion