deno_stdとは?
deno_stdとは、Denoのコアチームによって開発・メンテナンスされているDenoの標準ライブラリです。
Goの標準パッケージに影響を受けており、パスの操作やテストなどに関する様々な機能を提供しています。
この章では、deno_std
の中から比較的使用頻度の高いと思われる以下のモジュールについて解説します。
std/path
このモジュールはファイルパスを操作するための機能を提供します。
Node.jsにおけるpathパッケージに相当します。
mod.ts
とposix.ts
について
ファイルパスのスタイルはOSごとに異なります。
例えば、Windowsではパスの区切り文字として\
を使用しますが、Unix系だと/
です。
このような違いを考慮して、mod.tsは、使用しているOSに応じて振る舞いを提供します。
Winodows環境においてもUnix環境と同様の振る舞いを期待する場合は、mod.ts
の代わりにposix.tsをimportするか、posix
名前空間で提供されている関数を利用するとよいでしょう。
import { posix } from "https://deno.land/std/path/mod.ts";
posix.join("dist", "index.html"); // => "dist/index.html"
join
与えられたパスを連結します。
import { join } from "https://deno.land/std/path/mod.ts";
join("dist", "index.html"); // => "dist/index.html"
extname
ファイルの拡張子を返却します。
import { extname } from "https://deno.land/std/path/mod.ts";
extname("public/index.html"); // => ".html"
basename
与えられたパスのファイル名を返却します。
import { basename } from "https://deno.land/std/path/mod.ts";
basename("src/protocol/mod.ts"); // => "mod.ts"
dirname
与えられたパスのディレクトリ名を返却します。
import { dirname } from "https://deno.land/std/path/mod.ts";
dirname("src/protocol/mod.ts"); // => "src/protocol"
isAbsolute
与えられたパスが絶対パス形式であればtrue
、そうでなければfalse
を返却します。
import { isAbsolute } from "https://deno.land/std/path/mod.ts";
isAbsolute("/path/to/file.txt"); // => true
isAbsolute("file.txt"); // => false
parse
与えられたパスを解析し、オブジェクトの形式で返却します。
import { parse } from "https://deno.land/std/path/mod.ts";
parse("/path/to/file.txt"); // => { root: "/", dir: "/path/to", base: "file.txt", ext: ".txt", name: "file" }
resolve
与えられたパスを絶対パス形式に変換します。
import { resolve } from "https://deno.land/std/path/mod.ts";
resolve("public/index.html"); // => "/home/uki00a/work/public/index.html"
std/fs
このモジュールはファイルシステムに関する機能を提供します。
Node.jsにおけるfsパッケージに相当します。
使い方
fs/mod.tsで全ての関数をまとめてimportできます。
import { ensureDir, exists } from "https://deno.land/std/fs/mod.ts";
また、個別の機能ごとにimportすることもできます。
import { exists } from "https://deno.land/std/fs/exists.ts";
import { ensureDir } from "https://deno.land/std/fs/ensure_dir.ts";
exists
指定されたファイルが存在すればtrue
、そうでなければfalse
に解決されます。
import { exists } from "https://deno.land/std/fs/exists.ts";
await exists("./sample.txt"); // => `true` or `false`
ensureDir
mkdir -p
コマンドに相当します。
import { ensureDir } from "https://deno.land/std/fs/ensure_dir.ts";
await ensureDir("./path/to/dir");
emptyDir
指定されたディレクトリを空にします。
もし指定されたディレクトリが存在しなければ、作成されます。
import { emptyDir } from "https://deno.land/std/fs/empty_dir.ts";
await emptyDir("./path/to/dir");
move
ファイルの移動を行います。
例えば、次のコードは./sample.txt
を./subdir
ディレクトリへ移動します。
import { move } from "https://deno.land/std/fs/move.ts";
await move("./sample.txt", "./subdir/sample.txt");
移動元と移動先が同じディレクトリであれば、ファイルがリネームされます。 例えば、以下のコードは./src.txt
を./dest.txt
へリネームします。
import { move } from "https://deno.land/std/fs/move.ts";
await move("./src.txt", "./dest.txt");
move
は宛先のファイルがすでに存在する場合は、例外を投げます。 宛先のファイルを上書きしたいときは、overwrite: true
を指定します。
import { move } from "https://deno.land/std/fs/move.ts";
await move("./src.txt", "./dest.txt", { overwrite: true });
walk
指定されたディレクトリの内容を再帰的に走査します。
import { walk } from "https://deno.land/std/fs/walk.ts";
for await (const entry of walk("./books")) {
console.log(entry.name);
}
expandGlob
指定したglobパターンにマッチするファイルを走査します。
import { expandGlob } from "https://deno.land/std/fs/expand_glob.ts";
for await (const entry of expandGlob("./books/**/*.md")) {
console.log(entry.name);
}
std/io
IOに関わる機能を提供するモジュールです。
std/io/util
Deno.Reader
やDeno.Writer
に関するユーティリティを提供します。
readAll
EOFを受信するまで、指定されたDeno.Reader
オブジェクトから全ての内容を読み取ります。
import { readAll } from "https://deno.land/std/io/util.ts";
const decoder = new TextDecoder();
const deno = Deno.run({
cmd: [Deno.execPath(), "--version"],
stdout: "piped",
});
const output = await readAll(deno.stdout);
deno.stdout.close();
deno.close();
console.log(decoder.decode(output));
/*
* deno 1.9.2 (release, x86_64-unknown-linux-gnu)
* v8 9.1.269.5
* typescript 4.2.2
*/
writeAll
指定された全てのデータをDeno.Writer
オブジェクトへ書き込みます。
import { writeAll } from "https://deno.land/std/io/util.ts";
const encoder = new TextEncoder();
await writeAll(Deno.stdout, encoder.encode("Hello, Deno!"));
iter
Deno.Reader
をAsyncIterableIterator
に変換します。
import { iter } from "https://deno.land/std/io/util.ts";
import { StringReader } from "https://deno.land/std/io/readers.ts";
const decoder = new TextDecoder();
const r = new StringReader("Hello, Deno!");
const it = iter(r, { bufSize: 1 });
const results = [];
for await (const x of it) {
results.push(decoder.decode(x));
}
console.log(results);
/* => ["H", "e", "l", "l", "o", ",", " ", "D", "e", "n", "o", "!"] */
std/io/buffer
Buffer
クラスを提供します。
Buffer
可変長のバッファを提供します。(Node.jsのBufferクラスとは異なるものです)
Deno.Reader
とDeno.Writer
の両方を実装しています。
GoのBuffer型がベースになっています。
import { readAllSync, writeAllSync } from "https://deno.land/std/io/util.ts";
import { Buffer } from "https://deno.land/std/io/buffer.ts";
const decoder = new TextDecoder();
const encoder = new TextEncoder();
const buffer = new Buffer();
writeAllSync(buffer, encoder.encode("Hello, "));
writeAllSync(buffer, encoder.encode("World!"));
decoder.decode(readAllSync(buffer)); // => "Hello, World!"
std/io/bufio.ts
Deno.Reader
やDeno.Writer
にバッファリングを実装するため、BufReader
やBufWriter
などが提供されています。
BufReader
Deno.Reader
をラップし、バッファリング機能を提供します。
import { BufReader } from "https://deno.land/std/io/bufio.ts";
const decoder = new TextDecoder();
const buf = BufReader.create(Deno.stdin);
const result = await buf.readLine();
if (result !== null) {
console.log(decoder.decode(result.line));
}
BufWriter
Deno.Writer
をラップし、バッファリング機能を提供します。
import { BufWriter } from "https://deno.land/std/io/bufio.ts";
const encoder = new TextEncoder();
const file = await Deno.open("sample.txt", { write: true, create: true });
try {
const buf = BufWriter.create(file);
await buf.write(encoder.encode("Hello, Deno!\n"));
await buf.write(encoder.encode("Hello, World!\n"));
await buf.flush();
} finally {
file.close();
}
console.log(await Deno.readTextFile("sample.txt"));
/*
* Hello, Deno!
* Hello, World!
*
*/
std/io/readers
Deno.Reader
を実装したオブジェクトを提供します。
StringReader
Deno.Reader
に依存したコードのユニットテストを書く際に便利です。
import { readAll } from "https://deno.land/std/io/util.ts";
import { StringReader } from "https://deno.land/std/io/readers.ts";
const r = new StringReader("Hello, Deno!");
const decoder = new TextDecoder();
decoder.decode(await readAll(r)); // => "Hello, Deno!"
std/io/writers
Deno.Writer
を実装したオブジェクトを提供します。
StringWriter
toString
メソッドを呼ぶと、書き込まれた文字列を取得できます。
Deno.Writer
に依存したコードのユニットテストを書く際に便利です。
import { writeAll } from "https://deno.land/std/io/util.ts";
import { StringWriter } from "https://deno.land/std/io/writers.ts";
const encoder = new TextEncoder();
const w = new StringWriter();
await writeAll(w, encoder.encode("Hello, Deno!"));
w.toString(); // => "Hello, Deno!"
std/testing
このモジュールでは、テストを記述する際に必要となる機能が提供されています。
std/testing/asserts
このモジュールは、主にテストで使用するための様々なアサーション関数を提供します。
assert(expr, msg = "")
expr
がfalse
に評価された場合、例外を投げます。
import { assert } from "https://deno.land/std/testing/asserts.ts";
assert(true); // => OK
assert(false); // => NG
assertEquals(actual, expected, msg = "")
actual
とexpected
の深い比較を行い、それらが一致しなければ例外を投げます。
import { assertEquals } from "https://deno.land/std/testing/asserts.ts";
assertEquals(1, 1); // => OK
assertEquals([1, { foo: "bar" }], [1, { foo: "bar" }]); // => OK
assertEquals(1, 2); // => NG
assertEquals({ bar: "foo" }, { foo: "bar" }); // => NG
assertNotEquals(actual, expected, msg = "")
actual
とexpected
の深い比較を行い、それらが一致したら例外を投げます。
import { assertNotEquals } from "https://deno.land/std/testing/asserts.ts";
assertNotEquals(1, 2); // => OK
assertNotEquals({ bar: "foo" }, { foo: "bar" }); // => OK
assertNotEquals(1, 1); // => NG
assertNotEquals([1, { foo: "bar" }], [1, { foo: "bar" }]); // => NG
assertStrictEquals(actual, expected, msg = "")
actual === expected
がfalse
に評価された場合、例外を投げます。
import { assertStrictEquals } from "https://deno.land/std/testing/asserts.ts";
const obj = { foo: "bar" };
assertStrictEquals(1, 1); // => OK
assertStrictEquals(obj, obj); // => OK
assertStrictEquals([1, { foo: "bar" }], [1, { foo: "bar" }]); // => NG
assertStrictEquals(1, 2); // => NG
assertStrictEquals({ bar: "foo" }, { foo: "bar" }); // => NG
assertNotStrictEquals(actual, expected, msg = "")
actual !== expected
がfalse
に評価された場合、例外を投げます。
import { assertNotStrictEquals } from "https://deno.land/std/testing/asserts.ts";
const obj = { foo: "bar" };
assertNotStrictEquals([1, { foo: "bar" }], [1, { foo: "bar" }]); // => OK
assertNotStrictEquals(1, 2); // => OK
assertNotStrictEquals({ bar: "foo" }, { foo: "bar" }); // => OK
assertNotStrictEquals(1, 1); // => NG
assertNotStrictEquals(obj, obj); // => NG
assertExists(actual, msg = "")
actual
がnull
またはundefined
であれば、例外を投げます。
import { assertExists } from "https://deno.land/std/testing/asserts.ts";
assertExists(0); // => OK
assertExists(""); // => OK
assertExists(false); // => OK
assertExists(null); // => NG
assertExists(undefined); // => NG
assertStringIncludes(actual, expected, msg = "")
actual
がexpected
を部分文字列として含まない場合、例外を投げます。
import { assertStringIncludes } from "https://deno.land/std/testing/asserts.ts";
assertStringIncludes("foobar", "bar"); // => OK
assertStringIncludes("foobar", "baz"); // => NG
assertArrayIncludes(actual, expected, msg = "")
actual
がexpected
の全ての要素を含まない場合、例外を投げます。
import { assertArrayIncludes } from "https://deno.land/std/testing/asserts.ts";
assertArrayIncludes([1, 2, 3], [1, 2]); // => OK
assertArrayIncludes([1, 2, 3], [3, 4]); // => NG
assertMatch(actual, expected, msg = "")
actual
がexpected
で指定された正規表現にマッチしなければ、例外を投げます。
import { assertMatch } from "https://deno.land/std/testing/asserts.ts";
assertMatch("foobar", /bar$/); // => OK
assertMatch("foobar", /baz$/); // => NG
assertNotMatch(actual, expected, msg = "")
actual
がexpected
で指定された正規表現にマッチする場合、例外を投げます。
import { assertNotMatch } from "https://deno.land/std/testing/asserts.ts";
assertNotMatch("foobar", /baz$/); // => OK
assertNotMatch("foobar", /bar$/); // => NG
assertObjectMatch(actual, expected, msg = "")
expected
がactual
のサブセットでなければ、例外を投げます。
import { assertObjectMatch } from "https://deno.land/std/testing/asserts.ts";
assertObjectMatch({ foo: "bar" }, { foo: "bar" }); // => OK
assertObjectMatch(
{ a: 1, foo: "bar" },
{ foo: "bar" },
); // => OK
assertObjectMatch({ obj: { a: 1, b: 2 } }, { obj: { b: 2 } }); // => OK
assertObjectMatch({ a: 1 }, { b: 2 }); // => NG
assertObjectMatch({ obj: { a: 1, b: 2 } }, { obj: { b: 2, c: 3 } }); // => NG
assertThrows(fn, errorClass = undefined, msgIncludes = "", msg = "")
fn
がerrorClass
で指定された例外を投げなければ、例外を投げます。
import {
assertEquals,
AssertionError,
assertThrows,
} from "https://deno.land/std/testing/asserts.ts";
assertThrows(() => assertEquals(1, 2)); // => OK
assertThrows(() => assertEquals(1, 2), AssertionError); // => OK
assertThrows(() => assertEquals(1, 2), AssertionError, "Values are not equal"); // => OK
assertThrows(() => assertEquals(1, 2), TypeError); // => NG
assertThrows(() => assertEquals(1, 2), AssertionError, "hoge"); // => NG
assertRejects(fn, errorClass = undefined, msgIncludes = "", msg = "")
fn
がerrorClass
で指定された例外でreject
されたPromise
を返却しなければ、例外を投げます。
import {
assertEquals,
AssertionError,
assertRejects,
} from "https://deno.land/std/testing/asserts.ts";
await assertRejects(async () => assertEquals(1, 2)); // => OK
await assertRejects(async () => assertEquals(1, 2), AssertionError); // => OK
await assertRejects(
async () => assertEquals(1, 2),
AssertionError,
"Values are not equal",
); // => OK
await assertRejects(async () => assertEquals(1, 2), TypeError); // => NG
await assertRejects(async () => assertEquals(1, 2), AssertionError, "hoge"); // => NG
std/testing/bench
ベンチマークを計測するための機能を提供します。
使い方
bench
でベンチマーク関数を定義し、runBenchmarks
によってそれらを実行します。例えば、以下のような内容のbench.ts
というファイルがあったとします。
import {
bench,
runBenchmarks,
} from "https://deno.land/std/testing/bench.ts";
import { connect } from "https://deno.land/x/redis@v0.22.0/mod.ts";
const redis = await connect({ hostname: "localhost" });
bench({
name: "ping",
runs: 10_000, // 10,000回実行し、平均実行時間を計測
async func(b) {
b.start();
await redis.ping("PING");
b.stop();
},
});
await runBenchmarks();
このファイルを実行すると、ベンチマークが実行され、以下のように計測結果が表示されます。
$ deno run --allow-net bench.ts
running 1 benchmark ...
benchmark ping ...
10000 runs avg: 0.069ms
benchmark result: DONE. 1 measured; 0 filtered
deno_stdの使い方を調べる
この章で紹介した以外にも、deno_stdには様々なモジュールや機能が提供されています。
deno_stdの各モジュールの使い方は、以下の方法で調べられます。
各モジュールのREADME.mdを参照する
deno_stdの各モジュールには、README.mdファイルが提供されています。
例えば、std/fs
モジュールのREADME.mdは以下のURLから閲覧できます。
doc.deno.landからAPIドキュメントを閲覧する
doc.deno.landというWebサイトが存在します。
ここでは、deno_stdに限らず、Web上で公開されている様々なモジュールのAPIドキュメントを閲覧することができます。
例えば、以下のURLをブラウザで開くと、deno_std v0.95.0のpath/mod.ts
のAPIドキュメントを閲覧できます。
ポイント
- Denoにはdeno_stdという標準ライブラリが存在します。
- deno_stdの使い方を知りたいときは、README.mdやdoc.deno.landから調べられます。
-
理由については依存モジュールのバージョンを明示しようを参照ください。 ↩︎