deno v0.42.0の変更点まとめ

https://github.com/denoland/deno/releases/tag/v0.42.0

deno v0.42.0がリリースされました。

v1.0.0のリリースに先駆けて、多くの破壊的変更が実施されています。

# 破壊的変更

## `--unstable`フラグが導入された

v0.42.0からいくつかの機能がunstableとして扱われます。

下記機能を利用する際は、`--unstable`フラグを指定する必要があります。

- UDP([#4968](https://github.com/denoland/deno/pull/4968))
- `shutdown`([#4940](https://github.com/denoland/deno/pull/4940))
- `--importmap`オプション([#4934](https://github.com/denoland/deno/pull/4934))
- `Deno.dir()`([#4924](https://github.com/denoland/deno/pull/4924))
- `Deno.kill()`([#4950](https://github.com/denoland/deno/pull/4950))
- `Deno.loadavg()`([#4938](https://github.com/denoland/deno/pull/4938))
- `Deno.osRelease()`([#4938](https://github.com/denoland/deno/pull/4938))
- `Deno.setRaw()`([#4925](https://github.com/denoland/deno/pull/4925))
- `Deno.isatty()`([#4925](https://github.com/denoland/deno/pull/4925))
- `Deno.umask()`([#4935](https://github.com/denoland/deno/pull/4935))
- `Deno.utime()`([#4955](https://github.com/denoland/deno/pull/4955))
- `Deno.compile()`([#4912](https://github.com/denoland/deno/pull/4912))
- `Deno.transpile()`([#4912](https://github.com/denoland/deno/pull/4912))
- `Deno.signal()`([#4926](https://github.com/denoland/deno/pull/4926))
- `Deno.openPlugin()`([#4892](https://github.com/denoland/deno/pull/4892))
- `Deno.link/linkSync`([#4892](https://github.com/denoland/deno/pull/4892))
- `Deno.symlink/symlinkSync`([#4892](https://github.com/denoland/deno/pull/4892))

#### 例

`Deno.umask()`はunstableとして扱われます。

```typescript:mod.ts
console.log(Deno.umask());
```

`--unstable`フラグが指定されていない場合、エラーが発生します。

```shell
$ deno run mod.ts
Unstable API 'Deno.umask'. The --unstable flag must be provided.
```

`--unstable`フラグを指定すると動作します。

```shell
$ deno run --unstable mod.ts
18
```

## `Deno.env`のAPIが大幅に変更された

v0.41.0まではプレーンなオブジェクトを返却する関数として実装されていました。

```typescript:v0.41.0
Deno.env()["HOME"];
```

v0.42.0でMapライクなAPIに変更されました。

```typescript:v0.42.0
// HOME環境変数を取得
Deno.env.get("HOME");

// 環境変数を設定
Deno.env.set("TEST", "true");

// 環境変数の一覧を取得(v0.41.0までのDeno.env()に相当)
Deno.env.toObject();
```

https://github.com/denoland/deno/pull/4942

## `Deno.test`の名前付き関数のみを受け取る形式が削除された

以下のように、名前付き関数を受け取る形式がサポートから外されました。

```typescript
Deno.test(function namedFunction() {
  ...
});
```

今後は、以下のように指定する必要があります。

```typescript
Deno.test("namedFunction", () => {
  ...
});
```

https://github.com/denoland/deno/pull/4951

## `Deno.EOF`が削除された

今まで`Deno.EOF`が返却されていた場面では、`null`が返却されます。

v0.41.0までは、EOFの判定をする際は、以下のように記述する必要がありました。

```typescript
if (x === Deno.EOF) {
  ...
}
```

v0.42.0以降では以下のように変更する必要があります。

```typescript
if (x === null) {
  ...
}
```

https://github.com/denoland/deno/pull/4953

## ` Deno.DirEntry`型が単純化された

`Deno.DirEntry`は`Deno.readDir`から返却されます。

以下はv0.41.0とv0.42.0、それぞれの比較です。

```typescript:v0.41.0
{
 isFile: true,
 isDirectory: false,
 isSymlink: false,
 size: 5,
 modified: 1583048860,
 accessed: 1583048860,
 created: 1583048860,
 dev: 66309,
 ino: 5647783,
 mode: 33188,
 nlink: 1,
 uid: 1000,
 gid: 1000,
 rdev: 0,
 blksize: 4096,
 blocks: 8,
 name: "hello.txt"
}
```

```typescript:v0.42.0
{ name: "hello.txt", isFile: true, isDirectory: false, isSymlink: false }
```

https://github.com/denoland/deno/pull/4941

## `Deno.OpenMode`が削除された

`Deno.open`における以下の形式がサポートから外されました。

```typescript:v0.41.0
const f = await Deno.open("./hello.txt", "w+");
```

v0.42.0以降は、以下の形式で代用できます。

```typescript:v0.42.0
const f = await Deno.open("./hello.txt", {
  read: true,
  write: true,
  truncate: true,
  create: true,
});
```

https://github.com/denoland/deno/pull/4884

## `Deno.copy`の引数の順番が変更された

`src`引数と`dst`引数の順番が入れ替わりました。

```typescript
// v0.41.0(変更前)
await Deno.copy(dst, src);

// v0.42.0(変更後)
await Deno.copy(src, dst);
```

https://github.com/denoland/deno/pull/4885

## (`std/io/ioutil`) `copyN`関数の引数の順番が変更された

`Deno.copy`関数の引数の順序の入れ替えに合わせて、`copyN`関数の引数の順序も変更されました。

```typescript
// v0.41.0(変更前)
await copyN(dest, src, size);

// v0.42.0(変更後)
await copyN(src, dest, size);
```

https://github.com/denoland/deno/pull/4900

## いくつかのAPIがリネームされた

#### `Deno.SeekMode`([#4946](https://github.com/denoland/deno/pull/4946))

- `Deno.SeekMode.SEEK_START` => `Deno.SeekMode.Start`
- `Deno.SeekMode.SEEK_CURRENT` => `Deno.SeekMode.Current`
- `Deno.SeekMode.SEEK_END` => `Deno.SeekMode.End`

#### TLS([#4888](https://github.com/denoland/deno/pull/4888))

- `Deno.connectTLS` => `Deno.connectTls`
- `Deno.listenTLS` => `Deno.listenTls`

#### fs([#4995](https://github.com/denoland/deno/pull/4995), [#4886](https://github.com/denoland/deno/pull/4886))

- `Deno.readdir` => `Deno.readdir`
- `Deno.readdirSync` => `Deno.readdirSync`
- `Deno.readlink` => `Deno.readLink`
- `Deno.readlinkSync` => `Deno.readLinkSync`
- `Deno.realpath` => `Deno.realPath`
- `Deno.realpathSync` => `Deno.realPathSync`
- `Deno.fsEvents()` => `Deno.watchFs()`



#### その他([#4848](https://github.com/denoland/deno/pull/4848))

- `Deno.toAsyncIterator()` => `Deno.iter()`

## `Deno.resources()`の返り値の型が変更された

v0.41.0までは、以下の形式のオブジェクトが返却されていました。

```typescript:v0.41.0
{ [rid: number]: string; }
```

v0.42.0からは、`string`ではなく`any`型に変更されました。

```typescript:v0.42.0
{ [rid: number]: any; }
```

`Deno.resources`は内部的なAPIであり、将来的な変更を想定した修正のようです。

https://github.com/denoland/deno/pull/4893

## `Deno.chdir()`が`--allow-write`フラグを要求するようになった

https://github.com/denoland/deno/pull/4889

## `Deno.listen`に渡す`address`オプションが`path`オプションにリネームされた(Unixソケット)

https://github.com/denoland/deno/pull/4959

## `"udp"`及び`"unixpacket"`プロトコルを使用する際は、`Deno.listen`ではなく`Deno.listenDatagram`関数を使用するように変更された

https://github.com/denoland/deno/pull/4968

## UNIXドメインソケットを使う際は`--allow-write`を要求するよう変更された

https://github.com/denoland/deno/pull/4939

## `Deno.shutdown`がasync関数になった

戻り値の型が`void`から`Promise<void>`に変更されています。

https://github.com/denoland/deno/pull/4940

## `Conn.closeRead`が削除された

https://github.com/denoland/deno/pull/4970

## `Deno.runTests`が削除された

`deno test`コマンドで代用できるためと思われます。

https://github.com/denoland/deno/pull/4922

## `Deno.symbols`が削除された

https://github.com/denoland/deno/pull/4936

## `Deno.ReadCloser/WriteCloser/ReadSeeker/WriteSeeker/ReadWriteCloser/ReadWriteSeeker`が削除された

これらの型に依存していたコードがある際は、以下のように置き換えられます。

```typescript
// Deno.ReadCloser
const rc: Deno.Reader & Deno.Closer = ...;

// Deno.WriteCloser
const wc: Writer & Closer = ...;

// Deno.ReadSeeker
const rs: Reader & Seeker = ...;

// Deno.WriteSeeker
const ws: Writer & Seeker = ...;

// Deno.ReadWriteCloser
const rwc: Reader & Writer & Closer = ...;

// Deno.ReadWriteSeeker
const rws: Reader & Writer & Seeker = ...;
```

https://github.com/denoland/deno/pull/4944

## `Deno.FileInfo`型に対する変更

`Deno.FileInfo`は`Deno.stat()`から返却されるデータ型です。

この`Deno.FileInfo`における以下の3つのプロパティがリネームされ、型が`number`から`Date`に変更されました。

- `modified` => `mtime`
- `accessed` => `atime`
- `created` => `birthtime`

https://github.com/denoland/deno/pull/4932

## `Deno.Buffer#toString`のオーバーライド実装が削除された

https://github.com/denoland/deno/pull/4992

# 新規機能

## (`deno install`) `DENO_INSTALL_ROOT`環境変数がサポートされた

`deno install`のインストール先を変更できます。

例えば、以下を実行すると、カレントディレクトリの`bin`ディレクトリ配下に`file_server`がインストールされます。

```shell
$ DENO_INSTALL_ROOT=. deno install --allow-net --allow-read file_server https://deno.land/std/http/file_server.ts
```

https://github.com/denoland/deno/pull/4787

## (`std/io/bufio`) `BufWriterSync`クラスが追加された

`BufWriter`とは異なり、同期的に動作します。

https://github.com/denoland/deno/pull/4693

## (`std/path`) `fromFileUrl`関数が追加された

file URLを絶対パス形式に変換してくれます。

```typescript
import { fromFileUrl } from "https://deno.land/std@v0.42.0/path/mod.ts"

console.log(fromFileUrl("file:///home/piyo/test.txt")); // "/home/piyo/test.txt"
```

https://github.com/denoland/deno/pull/4993

## (`std/uuid`) uuid v5が実装された

https://github.com/denoland/deno/pull/4916

## (`deno test`) `--quiet`フラグがサポートされた

```typescript:test.ts
Deno.test("test1", () => {});
Deno.test("test2", () => {});
```

`--quiet`フラグを付与せずに`deno test`を実行すると、以下のようにテストの実行結果が表示されます。

`--quiet`フラグを付与した場合、以下のメッセージが一切表示されなくなります。

```shell
$ deno test ./test.ts
running 2 tests
test test1 ... ok (7ms)
test test2 ... ok (2ms)

test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out (10ms)
```

https://github.com/denoland/deno/pull/4894

## `Deno.readTextFile/writeTextFile`が実装された

`readTextFile`は指定したファイルを読み込み、文字列として返却してくれます。

`writeTextFile`は指定したパスに文字列を書き込みます。

```typescript
await Deno.writeTextFile("./hello.txt", "Hello, world!");

console.log(await Deno.readTextFile("./hello.txt")); // "Hello, world!"
```

https://github.com/denoland/deno/pull/4901

## `Deno.copy`が`bufSize`オプションをサポートした

```typescript
function copy(src: Reader, dst: Writer, options?: { bufSize: number }): Promise<number>
```

`options`引数が追加され、`src`から`dst`へコピーする際のバイト数を指定できるようになりました。(デフォルトは32KB)

https://github.com/denoland/deno/pull/4907

## pluginをクローズできるようになった

deno pluginをテストしようとすると、リソースリークチェックによりテストが失敗してしまう問題がありました。

その問題を解決するために、pluginをクローズする機能が追加されました。

https://github.com/denoland/deno/issues/4670
https://github.com/denoland/deno/pull/4785

## `Deno.startTls`が実装された

使用する際は`--unstable`フラグを指定する必要があります。

既存のTCPコネクションを元に、TLSコネクションを確立できます。

```typescript
const conn = await Deno.connect({ port: 80, hostname: "127.0.0.1" });
const tlsConn = await Deno.startTls(conn, { hostname: "127.0.0.1" });
```

https://github.com/denoland/deno/pull/4773

# その他の変更点

## `deno fmt`が複数のファイルを並行で処理するように変更された

https://github.com/denoland/deno/pull/4823

## `URL`に対する変更

- 不正なポートを渡すと、エラーが発生するようになった([#4954](https://github.com/denoland/deno/pull/4954))
- 不正なポートを`URL.port`に設定しようとすると、無視されるようになった([#4954](https://github.com/denoland/deno/pull/4954))

```typescript
const url = new URL("http://127.0.0.1:3000");
url.port = "-30";
console.log(url.port); // 3000
```

- ポートとして`0`として指定できるようになった([#4963](https://github.com/denoland/deno/pull/4963))

## カスタムの`message`プロパティをgetterとして定義している`Error`が`throw`された際に、適切にエラーメッセージがフォーマットされていなかった問題が修正された

以下のように、`message`プロパティをgetterとして定義している`Error`クラスがあったとします。

このようなクラスを`throw`した際に、適切なエラーメッセージが表示されない問題が修正されました。

```typescript
class CustomError extends Error {
  constructor() {
    super();
  }

  get message() {
    return "hoge";
  }
}

throw new CustomError();
```

以下はv0.41.0とv0.42.0におけるそれぞれの表示結果です。

```shell:v0.41.0
error: Uncaught Error
► file:///home/uki00a/work/deno/sample/mod.ts:11:7

11 throw new CustomError();
         ^

    at file:///home/uki00a/work/deno/sample/mod.ts:11:7
```

```shell:v0.42.0
error: Uncaught Error: hoge
throw new CustomError();

    at file:///home/uki00a/work/deno/sample/mod.ts:11:7
```

https://github.com/denoland/deno/pull/4808

## (`deno fmt`) jsxファイルを標準入力経由で渡した際にエラーが発生する問題が修正された

以下のようなjsxファイルがあったとします。

```jsx:test.jsx
function Test() {
  return <div>Hello</div>;
}
```

以下のように、標準入力経由で`deno fmt`にjsxファイルを渡すと、エラーが発生してしまう問題が修正されました。

```shell
# v0.41.0までは動作しなかった
$ cat ./test.jsx | deno fmt -
```

https://github.com/denoland/deno/pull/4971

## (`std/mime/multipart`) `MultipartReader`が`11534332`バイトよりも大きなファイルを切り捨ててしまう問題が修正された

https://github.com/denoland/deno/pull/4865

## (`std/node/fs`) `mkdir`の第2引数にコールバック関数を渡した際に、それが呼び出されない問題が修正された

https://github.com/denoland/deno/pull/4917