Deno 色々
Links
Playground
公式
- マニュアル
- API ドキュメント(よく読め)
- Deno by Example(by Example 系)
有志
わかりやすい。ちょっと内容古い。deprecated なやつがちらほら。
標準ライブラリ
依存の管理
deps.ts
or import maps
テスト
CI
古いから注意。標準ライブラリとかよく使われてるモジュールの GitHub Actions の YAML を参考にすれば OK。そんなにむずくない。
パーミッション
-
-A
、--allow-all
は本番環境で使わないように
deno run -A main.ts
- 必要な権限のみオプションで指定する。何の権限が必要になっているかを明示的にする。
deno run --allow-read --allow-write --allow-env main.ts
サブプロセス
Deno におけるテスト
テストの並列実行について
ChatGPT
エラーメッセージ
error: Started test step while another test step with sanitizers was running:
このエラーメッセージは、Denoのテストランナーが同時に複数のテストステップを実行しようとした際に発生しています。Denoのテストフレームワークでは、テスト間でのリソースのクリーンアップ("sanitizers"と呼ばれる)を保証するために、一度に一つのテストステップのみが実行されるように設計されています。このエラーは、特にDeno.test
で{ sanitizeResources: false, sanitizeOps: false }
のようなオプションを使用せずに、非同期操作やリソースの開放を伴うテストが適切にハンドリングされていない場合に起こりがちです。
エラーメッセージが示しているのは、tail の基本的な動作: 指定された行数をファイルから正確に取得する
というテストが複数同時に実行されており、それらのテストが互いに干渉している状態をDenoが検出したということです。これは、テストが非同期操作を行っていて、それらの操作が完了する前に次のテストが開始された場合に起こります。
解決策
-
非同期テストの正しい管理: 非同期操作を含むテストでは、操作が完了するのを待つために
await
を適切に使用してください。また、リソース(ファイルハンドル、ネットワークコネクションなど)を開放する処理をfinally
ブロック内で行い、テストが終了する前に必ずクリーンアップするようにしてください。 -
テストの隔離: 同時に実行されるテスト間で干渉が発生しないように、テストを適切に隔離します。テストが互いに独立していることを確認し、共有される状態やリソースがないようにしてください。
-
テストオプションの利用:
Deno.test
にはsanitizeResources
やsanitizeOps
などのオプションがあり、これらをfalse
に設定することでリソースやオペレーションの自動クリーンアップを無効にすることができます。ただし、これらのオプションを使用する場合は、手動でリソースのクリーンアップを確実に行う責任が生じます。
Deno.test({
name: "あなたのテスト名",
fn: async () => {
// あなたのテストロジック
},
sanitizeResources: false,
sanitizeOps: false
});
このエラーメッセージが出る原因と解決策を理解し、テストの設計を見直すことで、テストの正確性と信頼性を高めることができます。
ロギング
JSON 形式のロギング
import * as log from "https://deno.land/std@0.224.0/log/mod.ts";
log.setup({
handlers: {
default: new log.ConsoleHandler("DEBUG", {
formatter: log.formatters.jsonFormatter,
useColors: false,
}),
},
});
log.formatters.jsonFormatter
の中身を見ると意外と大したことしてない。細かなコンテキスト、例えば Go の zap の caller
フィールドみたいなのはどうやって取得するんだろう。
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
// This module is browser compatible.
import type { LogRecord } from "./logger.ts";
export function jsonFormatter(logRecord: LogRecord): string {
return JSON.stringify({
level: logRecord.levelName,
datetime: logRecord.datetime.getTime(),
message: logRecord.msg,
args: flattenArgs(logRecord.args),
});
}
function flattenArgs(args: unknown[]): unknown {
if (args.length === 1) {
return args[0];
} else if (args.length > 1) {
return args;
}
}
export const formatters: {
jsonFormatter(logRecord: LogRecord): string;
} = {
jsonFormatter,
};
UUID
UUID の生成は crypto
const myUUID = crypto.randomUUID();
console.log("Random UUID:", myUUID);
import * as uuid from "jsr:@std/uuid";
console.log(uuid.validate("not a UUID")); // false
console.log(uuid.validate("6ec0bd7f-11c0-43da-975e-2a8ad9ebae0b")); // true