Denoばた会議 Monthly 第21回

Deno v1.35

Astroが動作するように

Node.jsの互換性が改善され、Astroが動作するようになりました。

Deno.serveが安定化

const ac = new AbortController();
setTimeout(() => ac.abort(), 10000);

const server = Deno.serve({
  signal: ac.signal,
}, (req) => new Response("Hello Deno!"));
await server.finished;

Deno KVでキューが実装

const kv = await Deno.openKv(":memory:");
// メッセージを追加します。
const res = await kv.enqueue({ id: 1, payload: "foo" });
assert(res.ok);

let message;
const listenPromise = kv.listenQueue((_message) => { // キューを購読します
  message = _message;
});

kv.close();
await listenPromise; // closeするとresolveされます

console.info(message); // Output: { id: 1, payload: "foo" }

ReadableStream.fromが実装

const readableStream = ReadableStream.from(gen());
for await (const i of readableStream) {
  console.info(i);
}

async function* gen() {
  for (let i = 0; i < 5; i++) {
    await sleep(i * 1000);
    yield i;
  }
}

function sleep(ms) {
  return new Promise((ok) => setTimeout(ok, ms));
}

deno lintにfresh向けのルールが追加

deno.json"fresh"タグを指定することで有効化できます。

{
   "lint": {
     "rules": {
       "tags": ["fresh", "recommended"]
     }
   }
}

fresh v1.2

Islandコンポーネントでprops.childrenがサポート

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

import Collapse from "../islands/Collapse.tsx";

export default function Index(props: PageProps) {
  return (  
    <Collapse>
      <Collapse>
        <Content />
      </Collapse>
    </Collapse>
  );
}

Islandコンポーネントでnpmパッケージがサポート

// islands/Example.tsx
import truncate from "npm:lodash.truncate@4.4.2";

interface Props {
  text: string;
}

export default function Example({ text }: Props) {
  return <span>{ truncate(text) }</span>;
}

プラグインシステムでrenderAsyncフックがサポート

SSRの実行前後に非同期処理を仕込めるようになりました。

これにより、UnoCSSの公式サポートが入る可能性があるかもしれません。

fresh v1.3

非同期のRouteコンポーネント

// routes/users/[id].tsx
export default async function User(
  req: Request,
  ctx: RouteContext,
) {
  const user = await findUserByID(ctx.params.id);
  return <UserDetail user={user} />;
}

プラグインからのMiddleware/Routeの注入

import type { Plugin } from "$fresh/server.ts";
import { loggingMiddleware } from "./logging_middleware.ts";
import { SamplePage } from "./SamplePage.tsx";

export default function samplePlugin(options: { path: string }): Plugin {
  return {
    name: "samplePlugin",
    middlewares: [{
      middleware: { handler: loggingMiddleware },
      path: "/",
    }],
    routes: [{
      path: options.path,
      component: SamplePage,
    }],
  };
}

その他の話題

Deno Deployで静的に解析可能なdynamic importがサポート

// OK
const { deferred } = await import("https://deno.land/std@0.193.0/async/deferred.ts");

// 以下の形式はまだサポートされていません。
let mod = "async/retry.ts";
const { retry } = await import(`https://deno.land/std@0.193.0/${mod}`);