Denoばた会議 Monthly 第22回

Deno v1.36

--deny-*オプションがサポート

Denoに特定の操作を明示的に拒否させることができます。

# ファイルへの書き込み以外の操作を許可します。
$ deno run --allow-all --deny-write main.js

# README.md以外の任意のファイルの読み込みを許可します。
$ deno run --allow-read --deny-read=README.md main.js

deno.json(c)vendorオプションがサポート (unstable)

// deno.jsonc
{
  "imports": {
    "redis": "https://deno.land/x/redis@v0.29.0/mod.ts",
    "dax": "https://deno.land/x/dax@0.24.0/mod.ts"
  },
  "vendor": true
}

vendor: trueを指定すると、サードパーティのDenoモジュールがvendorディレクトリに、npmパッケージがnode_modulesに自動で保存されます。

deno test: JUnit/dotレポーターがサポート

# dotレポーターを有効化します
$ deno test --allow-read --allow-env --reporter=dot

# JUnitレポーターを有効化します
$ deno test --allow-read --allow-env --reporter=junit

# dotレポーターで標準出力に結果を表示しつつ、report.xmlにJUnit形式のレポートを出力します
$ deno test --allow-read --allow-env --reporter=dot --junit-path=report.xml

deno bench - Deno.BenchContext型が実装

Deno.bench("someHeavyComputation", async (t) => {
  await setup(); // ここの実行については計測対象から除外されます

  t.start(); // 計測開始
  await someHeavyComputation();
  t.end(); // 計測終了

  await cleanup(); // ここの実行についても計測対象から除外されます
});

node:testが実装

import assert from "node:assert";
import { test } from "node:test";

function sum(...numbers: Array<number>): number {
  return numbers.reduce((a, b) => a + b, 0);
}

test("sum", () => {
  assert.strictEqual(sum(), 0);
  assert.strictEqual(sum(987), 987);
  assert.strictEqual(sum(1, 2, 3), 6);
});

Fresh v1.4

Islandコンポーネントの事前ビルド

# 1. ビルドを実行
$ deno task build

# 2. _freshが作成されます
$ cat _fresh/snapshot.json

# 3. Freshを起動
$ deno run -A main.ts
Using snapshot found at /path/to/fresh-project/_fresh

fresh.config.ts

プラグインなど、Freshに関する設定をまとめます。

// `fresh.config.ts`
import { defineConfig } from "$fresh/server.ts";

import twindv1 from "$fresh/plugins/twindv1.ts";
import twindConfig from "./twind.config.ts";

export default defineConfig({
  plugins: [twindv1(twindConfig)]
});

fresh.config.ts

main.ts/dev.tsからfresh.config.tsを読み込むように修正します。

// main.ts
import { start } from "$fresh/server.ts";
import manifest from "./fresh.gen.ts";
import config from "./fresh.config.ts";
 
await start(manifest, config);
// dev.ts
import dev from "$fresh/dev.ts";
import config from "./fresh.config.ts";
 
await dev(import.meta.url, "./main.ts", config);

レイアウト

routes内の任意の階層に_layout.tsxを配置できます。

// routes/admin/_layout.tsx
import type { LayoutProps } from "$fresh/server.ts";

export default function Layout({ Component }: LayoutProps) {
  return (
    <section>
      <h2>Admin</h2>
      <main>
        <Component />
      </main>
    </section>
  );
}

define*ヘルパー

defineConfig/defineLayout/defineApp/defineRouteの4つのAPIが追加されました。

import { defineRoute } from "$fresh/server.ts";

export default defineRoute(async (req, ctx) => {
  const content = await readContent(ctx.params.id);

  return (
    <div>{content}</div>
  );
});

Route Groups

routes
├── (_islands)
│   └── Counter.tsx
├── (dashboard)
│   ├── (_components)
│   │   └── Chart.tsx
│   ├── _layout.tsx
│   └── account.tsx
├── _app.tsx
├── _layout.tsx
└── index.tsx

その他の話題

Deno Fest

Deno Festというイベントが開催されるようです。