Denoを開発するときにめっちゃ効率上げるコマンドを作った
以前、こちらの記事を公開しました。
Neovimでターミナルを開き、編集中のファイルに応じてdeno runかdeno testを実行するというコマンドです。
開発用に、自動で--allow-allおよび--unstableをつけているので、実行時に必要なオプションを考える必要がありません。しかも--watchもしているのでコードを修正に反応して再起動します。
個人的に、かなり重宝しています。
今回、こちらのコマンドをDenoスクリプトで作り直したので紹介します。
dex
A dexterous deno executor略してdexです。
機能
-
deno runおよびdeno testを簡単に自動実行できます。- 渡されたファイル名から自動でテストファイルかどうかを判断し、
deno runまたはdeno testを実行します。 - 自動で
--allow-all --unstable --no-check --watchをつけて実行します。
- 渡されたファイル名から自動でテストファイルかどうかを判断し、
- 便利なオプションがあります。
-
--clearオプションを付けることで、リロードのたびにコンソールをクリアできます。 -
--watchオプションにファイルパスを渡すことで、実行対象ファイル以外の変更も監視することができます。 - その他のオプションは
deno runまたはdeno testに透過的に渡されます。
-
- 設定ファイルを自動で読み込みます。
- カレントディレクトリに
import_map.jsonやdeno.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などのオプションも使用可能です。
この際の引数の処理に関してはこちらの記事で解説しています。
自動でコンソールをクリアする
--clearオプションをつけることで、リロードのたびに画面をクリアできます。
以前紹介したNeovim用コマンドでもそうだったのですが、こちらの記事にインスパイアされました。
こちらの記事では編集対象のファイル内にconsole.clear()を置く方法が紹介されています。
dexでは以下のようなファイルを$DENO_DIR以下に生成し、それを実行しています。
ユーザーが明示的にconsole.clear()を書く必要はありません。
console.clear();
import("path/to/file");
最初はこれをbase64化してdeno runに渡して実行できるかと思いしましたが、パス解決がうまくいかなかったため、$DENO_DIR以下に生成することにしました。
実行対象以外のファイルを監視する
deno run --watchでは実行対象のファイルおよびそのファイルがimportしているファイルの更新のみが監視対象となりますが、dexでは--watchオプションに追加したファイルはすべて監視対象になります。
たとえば、以下のようにsample.txtを表示するスクリプトがあるとき、
console.log(await Deno.readTextFile("./sample.txt"))
This is sample text!
--watchオプションにsample.txtを指定すると、このファイルが更新されたタイミングでも自動リロードが走ります。
dex --watch=./sample.txt show_text.ts
,で区切って渡すことで複数ファイルの指定も可能です。
設定ファイル自動読み込み・監視
Denoの実行時に指定できる設定ファイルとして、 import mapsとconfiguration 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専用でしたが、これでエディタに関わらず自動実行の恩恵を受けられます。
動作確認しながらの開発が非常に楽になると思うので、ぜひ使ってみてください。
ご感想、バグ報告、Star、何でも大歓迎です。どうぞよろしくお願いします。
Vim/Neovim連携
エディタに関わらず…とは書きましたが、筆者はNeovimユーザーなので、今回のdexをNeovim内で使えるようにしています。
以下の定義を設定ファイルに追記してご利用ください。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でのウィンドウの扱いに関しては以前の記事で説明しているので、気になる方はご覧ください。
参考
--watchオプションの対象ファイルは自前で更新監視を行っています。この実装には、以下の記事を参考にしました。
Discussion