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

Deno v1.32

Deno v1.32がリリースされました。 この記事では主な変更点などについて解説します。 WebGPU APIの削除 Deno v1.8で追加されたWebGPU APIが削除されました。 バイナリサイズや起動速度に影響があったというのが理由のようです。 ただし、削除は一時的なもののようで、将来的には再びWebGPU APIが追加される想定のようです。 KVストア Deno本体にKVストアが実装されています。 ただし、こちらについてはまだ公式では紹介などはされておらず、今後、APIなどに大きな変更が入る可能性もあります。 詳細については、以下の記事を参照いただければと思います。 Deno v1.32でKVストアが実装されました TypeScript TypeScript v5.0.2へのアップデート Deno内部に搭載されているTypeScriptがv5.0.2へアップデートされました。 ただし、制限として、ES Decoratorsのサポートについては現時点では除外されているようです。 --allを指定しなかった際の初回の型チェックの実行が高速化 Denoでは型チェックの実行結果をSQLiteにキャッシュしておくことで、型チェックの効率化を図っています。 しかし、初回の型チェック実行時についてはこのキャッシュの仕組みが効かないため、型チェックの実行効率が少し落ちてしまいます。 この問題を解消するために、--allが指定されていない際は、ローカルのファイルのみを型チェックするように挙動が変更されました。 これによって、キャッシュが効いていない場合でも、場合によっては2倍程度の高速化が見られることもあるようです。 CLIに関する改善 deno compileでdynamic importとWeb Workerがサポート deno compileでdynamic importとWeb Workerを使用したコードのバイナリが作成できるようになりました。 例えば、以下のようなファイルがあったとします。 // sum.js export function sum(...numbers) { return numbers.reduce((a, b) => a + b, 0); } // main.js const { sum } = await import("./sum.js"); console.info(sum(1, 2, 3)); このようにシンプルなケースでは、特に設定などは不要でうまく動いてくれます。 $ deno compile -o main main....

March 26, 2023

Deno v1.31

Deno v1.31がリリースされました。 この記事では主な変更点などについて解説します。 package.jsonサポート Denoでpackage.jsonがサポートされました。 具体的には、以下のような機能などが実装されています。 package.jsonの自動探索 dependencies/devDependenciesの定義内容によるbare specifierの解決 deno taskによるscriptsの実行 package.jsonの自動探索 deno.jsonなどのファイルと同様に、Denoがpackage.jsonも自動で探索してくれるようになりました。 もしpackage.jsonが見つかった場合、必要に応じてdependenciesやdevDependenciesで記述された依存パッケージを自動でダウンロードし、デフォルトでnode_modulesディレクトリに保存してくれます。 (従来通り、package.jsonが存在しない状態でnpm:経由でnpmパッケージをimportした際は、--node-modules-dirを指定しない限り、node_modulesは作成されません) もし、package.jsonの自動探索を無効化したい場合は、以下のいずれかの手段で無効化できます (以下の機能は、それぞれ次のリリースであるv1.31.1で追加された機能のためご注意!) --no-configまたは--no-npmオプションを指定する。 DENO_NO_PACKAGE_JSON環境変数に1を指定する dependencies/devDependenciesによるbare specifierの解決 Denoがpackage.jsonのdependenciesやdevDependenciesで定義された依存関係を元に、Import Mapsライクにbare specifierを解決してくれるようになりました。 例えば、以下のような内容のpackage.jsonが存在したとします。 { "dependencies": { "chalk": "^5.2.0", "koa": "2" } } この場合、アプリケーションでは以下のようにbare specifierを記述することがでます。 import chalk from "chalk"; // => `npm:chalk@^5.2.0` import Koa from "koa"; // => `npm:koa@2` const app = new Koa(); app.use((ctx) => { ctx.body = "Hello world"; }); app....

February 26, 2023

Deno v1.30

Deno v1.30がリリースされました。 この記事では主な変更点などについて解説します。 Node.js互換性の改善 2023年 Q1のロードマップで発表されていたNode.js組み込みパッケージの利用が正式にサポートされました。 以下のように、node:<パッケージ名>の形式でimportを記述すると、Node.js組み込みパッケージをDenoから利用することができます。 import { EventEmitter } from "node:events"; const emitter = new EventEmitter(); emitter.on("foo", console.log); emitter.emit("foo", "bar"); また、Node-APIの互換性の改善も引き続き実施されており、以下のAPIなどの互換性が向上されています。 napi_adjust_external_memory napi_detach_arraybuffer napi_is_detached_arraybuffer deno.jsonでのImport Mapsの定義がサポート こちらも2023年 Q1のロードマップで発表されていた機能になります。 deno.jsonでimportsやscopesなどが定義されていると、--import-map使用時と同様に、deno.jsonの定義内容を元にDenoがbare specifierが解釈してくれます。 例えば、以下のような内容のdeno.jsonが存在したとします。 { "imports": { "dax": "https://deno.land/x/dax@0.24.0/mod.ts" } } この場合、ソースコードでは以下のようにしてdaxモジュールを利用することができます。 import { $ } from "dax"; await $`echo foobar`; deno fmtでセミコロンの有無を制御できるように 今まで、Denoに搭載されたフォーマッタであるdeno fmtコマンドでは、ソースコードにおける行末のセミコロンの有無をカスタマイズすることができませんでした。 今回のリリースでは、deno.jsonでfmt.options.semiColonsオプションがサポートされました。 このオプションにfalseを設定すると、deno fmtの実行時に行末のセミコロンが取り除かれます。 { "fmt": { "options": { "semiColons": false } } } また、--options-no-semicolonsオプションにより、CLI経由でセミコロンの有無を制御することも可能です。...

January 29, 2023

Deno v1.29

Deno v1.29がリリースされました。 この記事では主な変更点などについて解説します。 サブプロセスAPIに関する変更 Deno.spawn, Deno.spawnSync, Deno.spawnChildの削除 Deno v1.28でDeno.Commandが実装されたため、下記のAPIが削除されています。 Deno.spawn Deno.spawnSync Deno.spawnChild このあたりの背景などについては、下記の記事で詳しく解説されています。 Deno.run と Deno.spawn と Deno.Command のどれを使えば良いのか また、Deno.Commandについてもv1.28.3でAPIが若干変更されています。 Deno.spawn系統のAPIからDeno.Commandへの移行について Deno.spawn()はDeno.Child#output(), Deno.spawnSync()はDeno.Child#outputSync()で代用できます。 const command = new Deno.Command("deno", { args: ["info", "--json"], }); const status = await command.output(); if (status.success) { console.info(new TextDecoder().decode(status.stdout)); } Deno.spawnChild()はDeno.Child#spawn()で代用できます。 const command = new Deno.Command("deno", { args: ["fmt", "--ext=json", "-"], stdin: "piped", stdout: "piped" }); const child = command....

December 18, 2022

Deno v1.28

Deno v1.28がリリースされました。 この記事では主な変更点などについて解説します。 npmパッケージサポートの安定化 Deno v1.25で実装されたnpmパッケージサポートが安定化されました。 今後は--unstableなしでnpmパッケージを読み込むことができます。 $ cat main.js import chalk from "npm:chalk@5.1.2"; console.log(chalk.green("Deno")); $ deno run --allow-read --allow-env main.js ただし、リモートモジュールの中にnpm:が含まれていた際は、従来どおり--unstableが要求されるため注意が必要そうです。 その他にも以下の改善などが実施されています。 peerDependenciesがサポート deno info --jsonでnpm:がサポート import.meta.resolveでnpm:が無効化 今後npmパッケージサポートに関して計画されている変更内容についてはロードマップを参照ください。 ロックファイルの自動適用と生成がサポート Denoにはアプリケーションが依存するサードパーティモジュールの内容を元にハッシュ値を計算し、ロックファイルと呼ばれるファイルに保存する機能があります。 アプリケーションを実行する際にサードパーティモジュールから再度ハッシュ値を計算し、ロックファイルに書き込まれたハッシュ値と比較することで、サードパーティモジュールの内容が改ざんされていないことを保証することができます。(インテグリティチェック) この挙動を有効化するには、従来では--lockと--lock-writeの指定が必要でした。 このリリースでは、deno.json(c)が存在する場合、ロックファイル(deno.lock)の生成とインテグリティチェックが自動で実施されるように挙動が変更されました。 $ ls deno.json main.js $ deno run main.js $ ls deno.json deno.lock main.js この変更に合わせて、既存のオプションやインテグリティチェックに関する挙動も一部変更されています。 --lockオプションの引数がオプショナルに変更 (デフォルトはdeno.lock) ロックファイルに列挙されていないパッケージが見つかった際に、インテグリティチェックが失敗しないように挙動が変更 新しく検出されたパッケージについては、ハッシュが自動でロックファイルに書き込まれます。そのパッケージのインテグリティチェックについては、次回以降のDenoの実行から適用されます。 また、このロックファイルの自動適用と生成を無効化するために--no-lockという新しいオプションも追加されています。 Deno.Commandの追加 Deno.CommandというDenoからサブプロセスを生成するための新しいAPIが実装されました。 利用するには--unstableと--allow-runの指定が必要です。 使用例 コマンドの実行結果の非同期での取得: const command = new Deno....

November 20, 2022