カテゴリー
[Deno事始め] Denoでコマンドラインから動く対話型アプリケーションを作成する
※ 当ページには【広告/PR】を含む場合があります。
2020/10/30
node.jsの開発者であるRyan Dahl氏がnode.jsでの反省点を踏まえた形で開発が進められているため、改良版型Nodeと言っても過言では無く今後も注目が集まりそうです。
さて今回はDenoの標準ライブラリを利用して、コマンドラインから対話型アプリを作ってみようと思います。
準備編
インストール方法は
各種の主要なOSのインストールの仕方が載っています。
この記事の中ではLinux系の方法でインストールを試します。
とはいってもcurlでインストール用のスクリプトを実行しているだけです。
$ curl -fsSL https://deno.land/x/install/install.sh | sh
$ deno --version
deno 1.4.6
v8 8.7.220.3
typescript 4.0.3
導入はとっても簡単です。
以下でdenoのhello world的なことも行えます。
$ deno run https://deno.land/std/examples/welcome.ts
Download https://deno.land/std/examples/welcome.ts
Warning Implicitly using latest version (0.75.0) for https://deno.land/std/examples/welcome.ts
Download https://deno.land/std@0.75.0/examples/welcome.ts
Check https://deno.land/std@0.75.0/examples/welcome.ts
Welcome to Deno 🦕
denoの特徴として、一度リモートレジストリから取り込んだリソースは環境変数
DENO_DIR
$ deno run https://deno.land/std/examples/welcome.ts
Welcome to Deno 🦕
コードの実装
それではdenoでコマンドライン上で動く簡単な対話型アプリケーションを作成してみます。
もっとも単純な対話型のプログラムとして、stdinから何か文字をインプットして、エンターキー後にその入力を出力させるだけのプログラムは以下のようになります。
これを
main.ts
import { readLines } from "https://deno.land/std/io/mod.ts";
async function main() {
for await (const line of readLines(Deno.stdin)) {
console.log(">", line);
if (/quit/.test(line)) {
console.log("Bye!");
return true;
}
}
}
console.log("Type 'quit' when you want to close the app.");
console.log("Reading line from stdin:");
await main();
ではこれを実行してみます。
$ deno run main.ts
Type 'quit' when you want to close the app.
Reading line from stdin:
hoge #👈hogeを入力
> hoge
fuga #👈fugaを入力
> fuga
piyo #👈piyoを入力
> piyo
quit #👈quitを入力
> quit
Bye!
上のように、
deno run <ソースコード>
また
quit
これは
for await
return
denoのプログラミングでは、
for await ~ of
この構文を使うとasync/awaitの並列化の設計思想と違っていて、並列処理の恩恵があまり無くなってしまうのでESLintで警告扱いになっていますが、denoでは割と開放的に利用されいます。
また同期処理のループでは
Promise.all()
Lint原理主義的な開発を行いたい場合にはそちらコーディングを検討されてもよいと思います。
質問内容をjsonで抽出する
対話型で良くある質問事項をjson形式で取りまとめるプログラムを作ります。
denoのスタンダードライブラリから独自に実装しても良いのですが、まずは
まだまだnpmと違い公開されているパッケージも少ないものの、現時点でコマンドラインから入力した内容をjson形式で出力してくれそうなのは、
ここでは
deno-prompt
main.ts
import Prompt from "https://deno.land/x/prompt/mod.ts";
import PromptError from "https://deno.land/x/prompt/src/errors/PromptError.ts";
const answers = await Prompt.prompts([
{ type: "text", name: "name", message: "Please input your name" },
{
type: "text",
name: "sex",
message: "Please input your sex(male or female)",
validate(result: string) {
if (!["male", "female"].includes(result)) {
throw new PromptError("input must be [male] or [female]");
}
},
},
{ type: "number", name: "birthYear", min: 1900 },
{ type: "number", name: "age", min: 1, max: 100 },
{ type: "confirm", name: "agree", defaultValue: true },
]);
console.log(answers);
これを実行してみます。
$ deno run main.ts
? Please input your name: Hoge Piyo
? Please input your sex(male or female): male
? BirthYear (>=1900): 1999
? Age (1-100): 21
? Agree (Y/n): true
{ name: "Hoge Piyo", sex: "male", birthYear: 1999, age: 21, agree: true }
質問内容からjsonが狙い通り抽出出来ているようです。
まとめ
denoを使ったjs/tsプログラミングは、node.jsの時代から比べると様々なプロセスが簡素化されています。
あまりに簡素化されているためnode.jsからdenoに移行を検討している方にとっては、
package.json
node_modules
ただ、まだまだライブラリやユーティリティの厚みが本家node.jsよりも薄いので、複雑な機能を実現しようとすると物足りなさを感じます。
暫くはnode.jsが取って代わられることも無い気がします。
今後、波が来るときに備え今のうちにdenoを勉強しておくと良い気がします。
参考サイト
記事を書いた人
ナンデモ系エンジニア
主にAngularでフロントエンド開発することが多いです。 開発環境はLinuxメインで進めているので、シェルコマンドも多用しております。 コツコツとプログラミングするのが好きな人間です。
カテゴリー