Deno v1.38

Deno v1.38がリリースされました。 この記事では主な変更点などについて解説します。 deno doc deno doc --lint deno docコマンドで--lintオプションがサポートされました。 $ deno doc --lint mod.ts Missing JS documentation comment. at file:///home/uki00a/ghq/github.com/uki00a/some-project/mod.ts:12:3 このオプションを指定すると、DenoはAPIドキュメントを出力する前に、各APIを検査します。そして以下のようなAPIが検出された場合、APIドキュメントを出力せずにエラーを表示します。 exportされているAPIにJSDocコメントが書かれていない場合 (Missing JS documentation comment.) exportされているAPIの戻り値の型定義が省略されている場合 (Missing return type.) exportされている型のプロパティがexportされていない型を参照している場合 (Type 'foo' references type 'Bar' which is not exported from a root module.) このエラーが発生した場合、そのexportされていない型に@internalを指定することでエラーを抑止できます deno doc --html deno docでAPIドキュメントのHTML形式での出力がサポートされました。 --htmlを指定すると、docsディレクトリにHTMLが出力されます。 $ deno doc --html --name=fresh-testing-library mod.ts Written 261 files to "./docs/" docs/index.htmlを開くことで作成されたAPIドキュメントを閲覧できます。...

November 5, 2023

fresh v1.5

fresh v1.5がリリースされました。 この記事では主な変更点などについて解説します。 Partials SPAライクなクライアントサイドでのページ遷移を実現するためにPartialsという機能が導入されました。 基本的な使い方 以下のコードを例に見てみます。 // routes/docs/[id].tsx import { Partial } from "$fresh/runtime.ts"; export default function Page({ docs, currentDoc }: { docs: Array<Doc>, currentDoc: Doc }) { return ( <> <Sidebar docs={docs} /> <Partial name="docs-main-content"> <MainContent doc={currentDoc} /> </Partial> </> ); } function Sidebar({ docs }: { docs: Array<Doc> }) { return ( <nav f-client-nav> <ul class="flex flex-col gap-2"> {docs....

October 15, 2023

Deno v1.37

Deno v1.37がリリースされました。 この記事では主な変更点などについて解説します。 実験的なパッケージマネージャが実装 (jsr:URL) ⚠️この機能は実験的機能のようなので、今後、大きな変更が入る可能性があります。 ⚠️また、パッケージレジストリがまだ公開されていないため、この機能はまだ利用できない状態のようです。 Deno本体に実験的なパッケージマネージャーが実装されています。 具体的には、以下のようにjsr:形式のURLを記述することで、Denoがパッケージレジストリと連携してsemverの解決などを行いつつ、パッケージのインストールなどを自動で行ってくれるようです。 import { foo } from "jsr:@foo/some_pkg@1/mod.ts"; 例えば、この場合、@foo/some_pkgパッケージに関するsemverの解決を行うために、まずhttps://${DENO_REGISTRY_URL}/@foo/some_pkg/meta.jsonの問い合わせを行い、その内容を元にどのバージョンをインストールすべきか判断されるようです。 従来のhttps:やnpm:形式のパッケージと同様に、npm installなどのコマンドの実行は不要で、スクリプトの実行時にDenoが必要に応じてパッケージをインストールしてくれます。 また、パッケージのインストール元レジストリはDENO_REGISTRY_URL環境変数で変更可能なようです。 ここからは推測になりますが、この機能は、元々、導入される予定であったdeno:URLに相当する機能だと思われます。 Deno本体がレジストリと連携してsemver解決を行うことで、依存関係の重複問題などを解消しようというのがこの機能の狙いだと思われます。 feat(unstable): package manager #20517 Built-in support for semvered specifiers on the deno.land/x registry #17495 deno jupyter Deno本体にJupyter Kernelが実装されました。 以下のコマンドを実行すると、Deno Kernelがインストールされているかどうかを確認できます。 $ deno jupyter --unstable ℹ️ Deno kernel is not yet installed, run `deno jupyter --unstable --install` to set it up もしインストールされていなければ、以下のコマンドでインストールできます。...

September 24, 2023

fresh v1.4

fresh v1.4がリリースされました。 この記事では主な変更点などについて解説します。 事前ビルドのサポート Islandコンポーネントなどの事前ビルドがサポートされました。 deno task buildを実行すると、_freshディレクトリにIslandコンポーネントなどをesbuildによってバンドルした結果が出力されます。(この_freshディレクトリは.gitignoreに含めることが推奨されます。) # 1. ビルドを実行 $ deno task build # 2. _freshディレクトリが作成されます $ cat _fresh/snapshot.json サーバの起動時にfreshは自動で_freshディレクトリを探索し、見つかればそこに格納されたバンドルを利用してくれます。これによりコールドスタート時間の短縮が期待されます。 $ deno run -A main.ts Using snapshot found at /path/to/fresh-project/_fresh この事前ビルド機能はオプトイン方式によるものであり、従来どおり、ビルドステップなしでの開発やデプロイは引き続きサポートされています。ローカルでは従来どおりの方法で開発をし、本番環境にデプロイするときだけ事前ビルドを行うことも可能です。 移行について (fresh.config.ts) ※fresh v1.4以降、新規に作成したプロジェクトにおいてはこの作業は不要です。 この修正の影響により、dev.tsで使用することが想定されているdev()に変更が入っており、移行が必要になる場合がありそうです。 具体的には、まず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)] }); 次に、main.tsをfresh.config.tsからfreshに関する設定を読み込むように変更します。 import { start } from "$fresh/server.ts"; import manifest from "....

August 20, 2023

Deno v1.36

Deno v1.36がリリースされました。 この記事では主な変更点などについて解説します。 --deny-*オプション --deny-*という新しいオプションが導入されました。このオプションにより、Denoに対して特定の操作のみを明示的に拒否させることができます。 例えば、以下の場合、Denoにwrite権限のみを拒否させています。 $ deno run --allow-all --deny-write main.js このように--allow-*オプションと--deny-*オプションは併用することが可能で、その場合、--deny-*オプションの方が優先されます。 また、--deny-*には--allow-*と同様に、リスト形式で対象を指定することもできます。 $ deno run --allow-read --deny-read=README.md main.js 上記の場合、./README.mdへの読み込みのみが拒否され、それ以外のファイルの読み込みは許可されます。 { const content = await Deno.readTextFile("Makefile"); // => OK console.info(content); } { const content = await Deno.readTextFile("README.md"); // => PermissionDenied console.info(content); } deno_modulesディレクトリの導入 ⚠️この機能はまだunstableという扱いのため、今後、機能などに変更が入る可能性があります。 また、現在、deno_modulesをvendorにリネームするPRも作成されており、今後ディレクトリやオプションなどの名前が変わる可能性も高そうです。 feat(unstable): rename deno_modules to vendor #20065 deno.jsonにdenoModulesDirという新しいオプションが導入されました。 このオプションにtrueを設定すると、リモートモジュールがdeno_modulesというディレクトリにダウンロードされるように挙動が変更されます。 { "denoModulesDir": true } この状態でスクリプトを実行すると、依存しているリモートモジュールがdeno_modulesに保存されます。 import { blue } from "https://deno....

August 6, 2023

fresh v1.3

fresh v1.3がリリースされました。 この記事では主な変更点などについて解説します。 非同期Routeコンポーネント 非同期Routeコンポーネントがサポートされました。 例えばデータベースや外部のAPIなどから非同期に取得したデータをRouteコンポーネントに渡すためには、今までは以下のようにhandlerを定義する必要がありました。 // routes/users/[id].tsx import type { Handlers, PageProps } from "$fresh/server.ts"; export const handler: Handlers<Data> = { async GET(req, ctx) { const user = await findUserByID(ctx.params.id); if (user == null) { return ctx.renderNotFound(); } const resp = await ctx.render(user); return resp; }, }; export default async function User(props: PageProps<User>) { return <UserDetail user={props.data} />; } 非同期Routeコンポーネントを利用することで、handlerを記述せずに非同期でのデータの取得とコンポーネントのレンダリングが行えるようになります。...

July 23, 2023

Deno v1.35

Deno v1.35がリリースされました。 この記事では主な変更点などについて解説します。 Deno API Deno.serveの安定化 Denoに組み込まれたHTTPサーバを起動するためのAPIであるDeno.serveが安定化されました。今後は--unstableを指定しなくても利用できます。 const ac = new AbortController(); setTimeout(() => ac.abort(), 10000); const server = Deno.serve({ signal: ac.signal, }, (req) => new Response("Hello Deno!")); await server.finished; これに合わせて、Deno.connectTlsのalpnProtocolsオプションも安定化されています。 Deno.listenTlsのalpnProtocolsオプションについては、おそらくv1.35.1で正式に安定化されるのではないかと思います。 新しいAPI Deno.errors配下に以下の新しいエラーが追加されています: NotADirectory FilesystemLoop IsADirectory NetworkUnreachable また、Deno.AtomicOperationが公開されています (今までは型定義のみが公開されていて、Deno名前空間では実際には定義されていませんでした) Web API ReadableStream.from ReadableStream.fromが実装されました。AsyncIteratorなどからReadableStreamを作成することができます。 function sleep(ms) { return new Promise((ok) => setTimeout(ok, ms)); } async function* gen() { for (let i = 0; i < 5; i++) { await sleep(i * 1000); yield i; } } const readableStream = ReadableStream....

July 9, 2023

fresh v1.2

fresh v1.2がリリースされました。 この記事では主な変更点などについて解説します。 このリリースに合わせて、PreactのメンテナーであるMarvin Hagemeister氏がDeno社に入社されたことが発表されています。これからMarvin Hagemeister氏を中心に、フルタイムでFreshの開発が進められていくことが計画されているようです。 アップデートについて freshはアップデート用のスクリプト(update.ts)を提供しています。 以下のコマンドを実行すると、v1.2へアップデートすることができます。 $ deno run -A -r https://fresh.deno.dev/update . また、このバージョン以降からinit.ts (freshのプロジェクト初期化用のスクリプト)で作成したプロジェクトでは、deno task updateでもfreshをアップデートすることができます。 Islandコンポーネントに関する改善 props.childrenのサポート Islandコンポーネントでprops.childrenがサポートされました。 import type { PageProps } from "$fresh/server.ts"; import Collapse from "../islands/Collapse.tsx"; function Content() { return <div>foobar</div>; } export default function Index(props: PageProps) { return ( <Collapse> <Content /> </Collapse> ); } またIslandコンポーネントをネストすることもできます。 export default function Index(props: PageProps) { return ( <Collapse> <Collapse> <Content /> </Collapse> </Collapse> ); } 制限として、children以外のpropsにコンポーネントを渡すことはまだサポートされていません。...

June 18, 2023

Deno v1.34

Deno v1.34がリリースされました。 この記事では主な変更点などについて解説します。 deno.json(c)の拡張 トップレベルのexcludeフィールドがサポート deno fmtやdeno lintなどの各コマンドで共通の除外対象ファイルを定義できます。 また、トップレベルのexcludeに加えてfmt.excludeやlint.excludeなども一緒に定義されている場合は、それらへマージされます。 例えば、以下のような設定があったとします。 { "fmt": { "exclude": [ "fresh.gen.ts", "README.md" ] }, "lint": { "exclude": [ "fresh.gen.ts" ] } } Deno v1.34以降であれば、以下のように設定をまとめることができます。 { "exclude": [ "fresh.gen.ts" ], "fmt": { "exclude": [ "README.md" ] } } globのサポート include/excludeやtasksなどでglob形式で対象を定義することができます。 { "lint": { "exclude": ["generated/**/*.ts"] }, "tasks": { "my_task": "cat vendor/**/*....

May 28, 2023

Deno v1.33

Deno v1.33がリリースされました。 この記事では主な変更点などについて解説します。 dynamic importに関するパーミッションチェックの見直し 静的に解析可能なdynamic importの実行時に、パーミッションが要求されないように挙動が変更されました。 このリリース以降、以下のコードを実行する際に--allow-netの指定が不要になります。(v1.32までは--allow-netが要求されます) const { delay } = await import("https://deno.land/std@0.185.0/async/delay.ts"); await delay(3000); ただし、以下のようにURLを動的に構築している場合などは、従来通り--allow-netの指定が必要です。 // Denoが`import()`の引数を静的に解析できない場合は、従来どおりパーミッションが要求されます const { delay } = await import(`https://deno.land/std@0.185.0/async/${"delay.ts"}`); await delay(3000); Deno KV Deno.AtomicOperationにmin/maxメソッドが追加 minは引数で指定された値と現在の値を比較し、小さい方の値でエントリを上書きします。maxはその逆の操作です。 const kv = await Deno.openKv(":memory:"); const result = await kv.set(["key"], new Deno.KvU64(1n)); const commitResult = await kv.atomic() .check({ key: ["key"], versionstamp: result.versionstamp }) .max(["key"], 2n) .commit(); assert(commitResult.ok); const result2 = await kv....

April 30, 2023