deno入門2018
以下古い情報keroxp.icon2019/3/20
hr.icon
denoが盛り上がり始めたのを感じたのでまとめるkeroxp.icon2018/12/28 インストール方法
公式に書いてあるとおり、
code:bash
で入る
${HOME}/.denoに色々と入れていくスタイル
PATH=${HOME}/.deno/bin:$PATHでパスを通しておく
これでdenoコマンドが使えるようになる
基本
denoコマンドがパッケージ解決、コンパイル、実行全部やる
基本的にはtsだが、CommonJSと異なるのが、パッケージ解決にURLしか使えない(と謳っている)ところ code:ts
import { log } from "./util.ts";
この場合testはネットから落としてきてlogは同階層のファイル
.tsを省略できず、/がindex.tsを表さない
個人的にはpackage.jsonは柔軟性が高くて結局便利だったと思うんですけどねkeroxp.icon
Ry(Ryan Dahl)が中央集権リポジトリを邪悪と断じたところで、ネットにパッケージを上げる以上そういうことは必要になると思うけど 現在だってnodeのモジュールはnpm以外からも入れることできるし(yarnpkg.com)
開発
Goと同じで単一ファイル(本当に単一ファイル)から開発を始められる 設定ファイルとかはいらない。
が、tsconfig.jsonは作っておいたほうがエディタの恩恵を得られる
code:tsconfig.json
{
"compilerOptions": {
"target": "es2018",
"baseUrl": ".",
"paths": {
"../../.deno/deps/https/*"
],
"../../.deno/deps/http/*"
]
}
}
}
deno --types > deno.d.tsでdenoの型定義を出力できる
denoがURLから落としてくるモジュールは、~/.deno/depsに置かれていく
なので↑みたいなtsconfigを書くとエディタが探してきてくれる
denoで一度コンパイルする必要はある
denoパッケージ
denoはURLしかモジュールとして読み込めないが、denoだけは特別に読み込める
code:ts
import {Conn} from "deno"
その他パッケージ
deno_std
もともとexampleだったらしいが最近stdに昇格した
実際は準標準という扱いっぽい
で入るライブラリがいくつか入っている
testing/testing.tsとかnet/http.tsとかをよく使う
denoのコアにhttpは入らないっぽいので、このhttpモジュールを使わなくてもよい
それともこれがコアに昇格することあるのだろうか?
一応Ry本人が書いているようだけど
httpを使いたいときはこう
code:ts
テストの書き方
コアにtestingモジュールがある
Goと同じで同階層に_test.tsファイルを作って開発していくスタイル スタイルであってルールではない。テストファイルは単体でdenoれる
code:some_test.ts
test(async function testSomething() {
assert(1 === (2-1))
})
実行すると結果が出る
code:log
deno test.ts
Compiling /Users/keroxp/Development/deno-ws/test.ts
running 1 tests
test testSomething
... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
HTTPサーバのたて方
deno_stdのnet/http.tsを使う
code:server.ts
(async function main() {
for await (const req of serve("0.0.0.0:8080")) {
if (req.url === "/") {
const contentType = req.headers.get("content-type");
await req.respond({
status: 200,
headers: new Headers({
"Content-Type": contentType
}),
body: new TextEncoder().encode("Hello!")
})
}
}
})();
code:bash
$ deno server.ts --allow-net
1. nodeのhttpのserver.on("request", (req, res) => {})から、ES2018のAsync Iterator構文に変わっている
ここでserveはPromiseを返すジェネレータである
これがいいのかどうかはちょっとわからない
一つのコンテクストで複数のAsync Iteratorを反復するためには無名async関数を実行して開きっぱなしPromiseを作る必要がある??
2. resがない
req: ServerRequestオブジェクトでresponse返す
それ以外はNode.jsのreqと似ている感じ
3. 非同期処理はasyncのみ
コールバック、イベント駆動の処理はない
4. メソッドチェーンみたいなのもあんまりない
やることはメソッド一発でやれ的な意思を感じる
5. *やdefaultエクスポートをほとんど使っていない
export const/function を多用している
CommonJSからTSModuleへという意思を感じる
なんとrequire使えないので!
6. ESのIterable機能を使いまくろうとしている
req.headersもオブジェクトではなく、Headersクラスのインスタンス
Headersは一応ESの仕様だが、Iterableにするために変なmixin実装をしている
{}じゃないのでreq.headers["content-type"]みたいなのは使えない
これはちょっとどうなのかと思った。JSじゃないことを強めている気持ちを感じる
headersがSystem.Iteratorを実装しているのでこういう書き方ができる
code:ts
}
7. プロセスの権限が絞られている
--allow-netをつけて実行しないとネット関連の機能を使わせてくれない
fsへのアクセスもsandbox化されているらしい。デフォルトだとReadOnly