🦕

Denoのフロントエンド開発の動向【2025年夏】

に公開

以前に以下のような記事を書きました。

https://zenn.dev/uki00a/articles/frontend-development-in-deno-2024-winter

上記記事の公開から一年以上が経過し、その間にDenoにおけるフロントエンド開発に関する様々なアップデートがありました。この記事では重要そうな話題に限定していくつか紹介いたします。

Deno本体のアップデート

Deno v2の正式リリース付近のタイミングから、Deno本体でフロントエンド関連の機能の拡充が少しずつ進められています。

deno bundleコマンドの再導入

deno bundleコマンドがDeno本体に再導入されています。

Deno v1におけるdeno bundleコマンド

Deno v1にはdeno bundleというコマンドがありました。ただし、Deno v1の時点におけるdeno bundleコマンドはwebpackやesbuildなどの高機能なバンドラーを置き換えることを想定したものではありませんでした。deno bundleコマンドは元々、ソースコードの配布やデプロイなどを容易にすることなどを主な目的としており、ユーザーが想定している用途 (高機能なバンドラーがほしい) との間に大きなギャップがありました。そういった事情もあり、Deno v2のリリースに伴ってdeno bundleコマンドは一度、削除されました。

https://zenn.dev/uki00a/articles/deno-v2-what-has-changed-from-v1

新しいdeno bundleコマンド

まだ実験的サポートの段階ではありますが、Deno v2.3.6にてdeno bundleコマンドが再導入されました。

https://deno.com/blog/v2.4#deno-bundle

Deno v1におけるdeno bundleコマンドとの大きな違いとして、esbuildをベースに再実装されています。--platform browserオプションを指定することによってブラウザー向けのバンドルを生成することも可能で、--watchオプションなどと併用することで、フロントエンド開発にも活用できる余地がありそうです。

Denoの公式ドキュメントではReactアプリケーションにおいての使用例が公開されています。

このdeno bundleコマンドは比較的新しい機能であり、今後、プログラムから操作できるようにするためのAPIやプラグインのサポートなどが検討されているようです。

また、後述する Fresh においてもこのdeno bundleとの統合が検討されているようです。

https://x.com/rough__sea/status/1933244186104639839

deno lint

deno lintはDeno本体から提供されるコマンドの一つで、ESLintなどのようにソースコードを検証することができます。

フロントエンド関連のルールが拡充

Deno v2.2でフロントエンド関連のルールが拡充されました。現時点の最新バージョンであるDeno 2.4.3では以下のように様々なルールがサポートされています。

$ deno lint --rules --json | jq '.rules | map(select(.tags | (contains(["jsx"]) or contains(["react"])))) | .[].code'
"jsx-boolean-value"
"jsx-button-has-type"
"jsx-curly-braces"
"jsx-key"
"jsx-no-children-prop"
"jsx-no-comment-text-nodes"
"jsx-no-duplicate-props"
"jsx-no-unescaped-entities"
"jsx-no-useless-fragment"
"jsx-props-no-spread-multi"
"jsx-void-dom-elements-no-children"
"react-no-danger"
"react-no-danger-with-children"
"react-rules-of-hooks"

特にreact-rules-of-hooksルールなどは重要であると思うため、フロントエンド開発をする際はぜひ有効化しておくと良さそうです。deno.jsonで以下のように設定しておくと有効化することができます:

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

プラグインシステム

Deno v2.2deno lintにプラグインシステムが導入されています。このプラグインシステムを活用することで、JavaScriptやTypeScriptによって独自のルールを実装することができます。もしほしいルールがdeno lintによって提供されていない場合に利用を検討してみると良さそうです。

deno lintのプラグインを利用したい場合、deno.jsonlint.pluginsで利用したいプラグインの一覧を指定する必要があります。

{
  "lint": {
    "plugins": [
      "./my-lint-plugin.ts",
      "jsr:@uki00a/deno-lint-plugin-extra-rules@0.9.0"
    ]
  }
}

プラグインの実例として、Denoの標準ライブラリであるdeno_stdのリポジトリにおいては、独自のプラグインが実装され、開発で活用されています。

https://github.com/denoland/std/blob/c3331d588f0e049fb464499161b8b8cd9977a508/_tools/lint_plugin.ts

--conditions

Deno v2.4で実装された機能です。これはNode.jsにおける同名オプションに相当し、例えば、react-server conditionを有効化したい場合などに利用できます:

$ deno run --conditions react-server -A main.mjs

また、DENO_CONDITIONS環境変数によって同様のことを実現することも可能です。

deno fmtにおける対応言語の拡充

以下の記事でも紹介しましたが、Deno v2のリリース直前ごろのタイミングでdeno fmtコマンドにおいてCSSやHTML, Svelte, Vueなどの様々な言語のサポートが追加されています:

https://zenn.dev/uki00a/articles/whats-new-for-deno-in-2024

Denoでフロントエンド開発を行う場合は活用を検討すると良さそうです。(一部フォーマットはまだ実験的サポートの段階であり、利用したい場合はdeno fmtの実行時に--unstable-componentオプションの指定が必要です)

Node.js互換性の改善

Denoにおいては引き続き、Node.js互換性の改善が進められています。
現時点でどれほどの互換性があるかを可視化するため、Denoの公式からnode-test-viewer.deno.devというWebサイトが公開されています。DenoはNode.jsとの互換性を担保するために、Node.jsが実行しているテストをDeno本体でも実行しており、このnode-test-viewer.deno.devではテストの網羅率が可視化されています。

Deno Deploy EA

Deno DeployはDeno公式から提供されているサーバーレスJavaScriptランタイムです。

現在、Deno Deployの新バージョンであるDeno Deploy EA (Early Access)の開発が進められているようで、公式ドキュメントにページが公開されています。

筆者もまだ試してはいない状況ですが、ドキュメントによると以下のような機能などが公開されています:

機能 概要
OpenTelemetry Deno v2.1から実装されているOpenTelemetryサポートとの統合
Cloud Connections AWSやGCPなどのリソースへ安全かつ容易にアクセス出来るようにすることを目的とした機能のようです
Databases Deno Deployが各種環境 (本番、プレビューなど) ごとに専用のデータベースを作成し、アプリケーションから設定なしで接続できるよう環境変数などを自動で注入してくれる機能のようです

Deno Deploy EAの最新情報はhttps://docs.deno.com/deploy/early-access/changelog/にて公開されているため、こちらのページなどを参照すると良さそうです (現時点での最新情報: deploy/early-access/changelog.md)

Fresh v2

FreshはDeno公式によって開発されているPreact+Denoをベースとしたフレームワークです。Freshでは現在、v2の正式リリースに向けて開発が進められています。

v2の正式リリース時期について

An Update on Freshという記事がDeno公式ブログで公開されました:

https://deno.com/blog/an-update-on-fresh

この記事によるとおおよそ2025年9月ごろでの正式リリースが計画されているようで、もうまもなくリリースされる可能性がありそうです。

直近で追加された新機能

以前に以下の記事でFresh v2において実施予定の新機能などについて紹介しました:

https://zenn.dev/uki00a/articles/toward-deno-v2

今回は、上記で紹介した以降に追加されたFresh v2向けの新機能について紹介します。

Viteプラグイン (@fresh/plugin-vite)

実験的ではありますが、FreshのViteプラグインが実装されました。

https://github.com/denoland/fresh/pull/3187

@fresh/plugin-viteという名前でJSRパッケージが公開されており、これによって、Vite向けの様々なエコシステムを活用した開発が行いやすくなりそうです。

Freshの初期化用スクリプトである@fresh/initではまだViteベースのプロジェクトの生成はサポートされていません。現時点では、Freshのリポジトリにあるpackages/plugin-vite/demoREADME.mdを参考にセットアップすると良さそうです。

# (1) `@fresh/init`でプロジェクトを作成
$ deno run -A jsr:@fresh/init@2.0.0-alpha.57

# (2) 作成されたプロジェクトへ移動
$ cd path/to/fresh-project

# (3) `@fresh/plugin-vite`とViteを導入
$ deno install jsr:@fresh/plugin-vite@0.0.3 npm:vite@7

依存関係をセットアップしたら、vite.config.tsを用意します:

vite.config.ts
import { defineConfig } from "vite";
import { fresh } from "@fresh/plugin-vite";

export default defineConfig({
  plugins: [
    fresh(),
  ],
});

その後、deno.jsontasks配下のdevおよびbuildスクリプトを以下のように書き換えます:

-    "dev": "deno run -A --watch=static/,routes/ dev.ts",
-    "build": "deno run -A dev.ts build",
+    "dev": "vite",
+    "build": "vite build",

これでビルドとサーバーの起動が行えます:

# (1) 本番ビルドの実行
$ deno task build

# (2) サーバーの起動
$ deno task start

Tailwind CSS v4のサポート

Fresh v2向けのTailwind CSSプラグインである@fresh/plugin-tailwindv0.0.1-alpha.8から、Tailwind CSS v4のサポートが追加されました。

https://github.com/denoland/fresh/pull/3054

Freshの初期化用スクリプトである@fresh/initを実行してTailwind CSSベースのFreshプロジェクトを作成すると、自動で@fresh/plugin-tailwindもセットアップされます。

また、Tailwind CSS v3については@fresh/plugin-tailwind-v3という別のパッケージから別途、サポートが提供されます。

https://github.com/denoland/fresh/pull/3135

公式ミドルウェアの拡充

Octo8080Xさんを中心にミドルウェアの拡充が実施されています。具体的にはCORSやCSRF向けのミドルウェアがすでにFresh本体へ追加されています。

https://github.com/denoland/fresh/pull/3013

https://github.com/denoland/fresh/pull/3018

これらの公式ミドルウェアは@fresh/coreパッケージから提供されます。

Aleph.jsのメンテナンスが停止

Deno向けのフロントエンドフレームワークとして長らく人気のあったAleph.jsのメンテナンスが停止され、リポジトリがアーカイブされました。

https://github.com/alephjs/aleph.js/commit/30abde17f247230ea6f3a7fb98a1c943cd71d891

Aleph.jsはかつてDeno公式から公開されていたMeet Meというアプリケーションにおいても採用されており、Denoのコミュニティーにおいても影響の大きいフレームワークであったと思います。現在ではPartials機能の導入などによりFreshでもクライアントサイドでのナビゲーションなどが実現できるようになったこともあり、Aleph.jsのREADMEにおいてもFreshへの移行が推奨されています。

Aleph.jsの作者であるije氏によって開発されているesm.shについては、引き続き開発が継続されています。

Deno公式パッケージ

Deno公式からフロントエンド関連の様々なパッケージが公開されています。

@deno/loader

@deno/loaderという各種バンドラーなど向けにDenoの依存解決ロジックなどを提供することを目的としたパッケージが公開されています:

https://github.com/denoland/deno-js-loader

ユーザーが直接このパッケージを使用する機会は多くはないと思われますが、前述の@fresh/plugin-viteや後述する@deno/esbuild-pluginなどの様々なパッケージの基盤として活用されています。

@deno/esbuild-plugin

@deno/esbuild-pluginというDeno公式のesbuildプラグインが公開されました:

https://github.com/denoland/deno-esbuild-plugin

@deno/loaderをベースとしているのが特徴で、Fresh v2 においてもesbuild_deno_loaderから@deno/esbuild-pluginへの移行が実施されています:

https://github.com/denoland/fresh/pull/3034

@deno/vite-plugin

@deno/vite-pluginはDeno公式のViteプラグインです:

https://github.com/denoland/deno-vite-plugin

npm:/jsr:/https:のサポートや、deno.jsonで定義されたImport mapsの解決などがサポートされています。

@deno/rolldown-plugin

@deno/rolldown-pluginはDeno公式のRolldownプラグインです:

https://github.com/denoland/deno-rolldown-plugin

こちらも@deno/loaderをベースに実装されています。

@deno/svelte-adapter

Deno公式のSvelteKitアダプタが公開されました:

https://github.com/denoland/svelte-adapter

今まではコミュニティから提供されていたアダプタ (pluvial/svelte-adapter-deno) なども存在しましたが、今後は@deno/svelte-adapterを利用すると良さそうです。

おわりに

Denoではさらなるユースケースの拡充のため、ここ一年ぐらいでフロントエンド関連の機能の開発やパッケージの公開 (deno bundle, @deno/esbuild-plugin) なども少しずつ進められているようです。Node.jsの互換性の改善に伴ってViteなどのエコシステムを活用しやすくなったこともあり、今後はFreshの開発でもViteを活用できるようになりそうです。

また、Deno DeployではDeno Deploy EAという新規バージョンの開発も進められており、今後リリースされるFresh v2製のアプリケーションをデプロイする際の選択肢の一つとなりそうです。

Discussion