deno入門2018
以下古い情報

2019/3/20
denoが盛り上がり始めたのを感じたのでまとめる

2018/12/28
インストール方法
公式に書いてあるとおり、
bash$ curl -L https://deno.land/x/install/install.py | python
で入る
${HOME}/.deno
に色々と入れていくスタイル
PATH=${HOME}/.deno/bin:$PATH
でパスを通しておく
これで deno
コマンドが使えるようになる
基本
deno
コマンドがパッケージ解決、コンパイル、実行全部やる
基本的にはtsだが、
CommonJSと異なるのが、パッケージ解決にURLしか使えない(と謳っている)ところ
tsimport { test } from "https://unpkg.com/deno_testing@0.0.5/testing.ts";
import { log } from "./util.ts";
この場合 test
はネットから落としてきて log
は同階層のファイル
.ts
を省略できず、 /
が index.ts
を表さない
個人的には
package.json
は柔軟性が高くて結局便利だったと思うんですけどね

Ry(
Ryan Dahl)が中央集権リポジトリを邪悪と断じたところで、ネットにパッケージを上げる以上そういうことは必要になると思うけど
現在だってnodeのモジュールはnpm以外からも入れることできるし(yarnpkg.com)
開発
Goと同じで単一ファイル(本当に単一ファイル)から開発を始められる
設定ファイルとかはいらない。
が、 tsconfig.json
は作っておいたほうがエディタの恩恵を得られる
tsconfig.json{
"compilerOptions": {
"target": "es2018",
"baseUrl": ".",
"paths": {
"deno": ["./deno.d.ts"],
"https://*": [
"../../.deno/deps/https/*"
],
"http://*": [
"../../.deno/deps/http/*"
]
}
}
}
deno --types > deno.d.ts
でdenoの型定義を出力できる
denoがURLから落としてくるモジュールは、 ~/.deno/deps
に置かれていく
なので↑みたいなtsconfigを書くとエディタが探してきてくれる
denoで一度コンパイルする必要はある
denoパッケージ
denoはURLしかモジュールとして読み込めないが、denoだけは特別に読み込める
tsimport {Conn} from "deno"
その他パッケージ
deno_std
もともとexampleだったらしいが最近stdに昇格した
実際は準標準という扱いっぽい
で入るライブラリがいくつか入っている
testing/testing.ts
とか net/http.ts
とかをよく使う
denoのコアにhttpは入らないっぽいので、このhttpモジュールを使わなくてもよい
それともこれがコアに昇格することあるのだろうか?
一応Ry本人が書いているようだけど
httpを使いたいときはこう
tsimport {serve} from "https://deno.land/x/net/http.ts"
テストの書き方
コアに testing
モジュールがある
Goと同じで同階層に
_test.ts
ファイルを作って開発していくスタイル
スタイルであってルールではない。テストファイルは単体でdenoれる
some_test.tsimport {test, assert} from "https://deno.land/x/testing/testing.ts"
test(async function testSomething() {
assert(1 === (2-1))
})
実行すると結果が出る
logdeno 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を使う
server.tsimport {serve} from "https://deno.land/x/net/http.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!")
})
}
}
})();
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を実装しているのでこういう書き方ができる
tsfor (const [key, val] of req.headeres) {
}
7. プロセスの権限が絞られている
--allow-net
をつけて実行しないとネット関連の機能を使わせてくれない
fsへのアクセスもsandbox化されているらしい。デフォルトだとReadOnly