网页 综合 更新时间 2026-04-24 15:00:00

Fresh 2.3: Zero JS by default, View Transitions, and Temporal support | Deno

自动蜘蛛 deno.com 正文约 5335 字
Fresh 2.3: Zero JS by default, View Transitions, and Temporal support | Deno
Fresh 2.3 is out, with over 100 commits from 20 contributors. This release makes the “zero JavaScript by default” promise actually hold, adds View Transitions support, pre-compiles middleware chains, and rounds out a long list of Vite integration fixes.
You can start a new project with:
or update an existing one with:
Fresh has always said that pages ship no JavaScript unless they need to, but that wasn’t strictly true. Every page ended up with a small client-entry script to bootstrap the island reviver and partials engine, even when neither was used.
Thanks to Jeroen Akkerman in #3696, Fresh now checks whether the page actually uses islands or partials (f-client-nav) before injecting anything. If it doesn’t, the page ships with no <script> tag, no module preload headers, and no client-side bundle at all.
There is nothing to configure. Static pages will just stop shipping JavaScript after upgrading.
The View Transitions API lets browsers animate between DOM states natively. Fresh 2.3 wires it up to the existing partials system, so you can opt in by adding one attribute:
Partial navigations will then be wrapped in document.startViewTransition() and you can customize the animation with regular CSS:
Or target individual elements:
Browsers without support fall back to normal partial updates. See the View Transitions docs for more.
Fresh now has built-in WebSocket support (#3774). The quickest way to add a WebSocket endpoint is app.ws():
For file-based routes, use ctx.upgrade() inside a GET handler. In managed mode, pass handlers and get the response back directly:
There’s also a bare mode. Call ctx.upgrade() without arguments to get the raw WebSocket object, useful when you need to store sockets in a shared structure like a chat room:
Non-WebSocket requests to a WebSocket route automatically get a 400 response. See the WebSocket documentation for the full API including idleTimeout and protocol options.
A lot of this cycle went into making the Vite integration more robust, especially around npm package compatibility.
Work in this area is continuing. #3767 removes the rest of the Babel transforms (~2,050 lines) and lets Vite handle CJS packages natively end to end. That should land shortly after 2.3.
Two new security middleware ship with this release.
CSP nonce injection (#3709) generates a unique nonce per request and adds it to every inline <script> and <style> tag. The corresponding Content-Security-Policy header uses 'nonce-{value}' instead of 'unsafe-inline', so only scripts and styles that Fresh rendered are allowed to execute.
User-supplied CSP directives now override the defaults rather than duplicating them (#3724). See the CSP documentation for the full list of options.
IP filter middleware (#3035, thanks to Octo8080X) adds built-in IP-based allow/deny lists with CIDR support:
See the IP filter documentation for custom response handling and more examples.
Fresh already instruments middleware, route handlers, and rendering with OpenTelemetry spans. In 2.3, it also injects a W3C traceparent meta tag into the HTML response (#3729), so browser-side telemetry SDKs can connect client spans to the server trace.
Enable tracing with Deno’s built-in OpenTelemetry support:
Fresh will then automatically add the meta tag to every rendered page:
No code changes required. See the OpenTelemetry documentation for exporter configuration and the full list of instrumented spans.
The Temporal API is landing in JavaScript engines, and Fresh now supports passing all eight Temporal types as island props:
You can pass a Temporal value from a route straight through to an island:
The staticDir option now accepts an array (#3759). When the same filename exists in multiple directories, the first entry wins. This is useful when a build step generates assets into a separate directory and you want to keep those separate from hand-authored files.
See the static files documentation for more.
Loading indicators used to only work for link clicks. In 2.3 they work for form submissions too (#3753). Fresh checks the submitter element first (for example, the clicked button) and falls back to the form, so you can have per-button indicators when a form has multiple submit buttons:
Apps behind nginx, Caddy, or a cloud load balancer can now opt into trustProxy so that ctx.url reflects the actual client-facing URL (#3757):
With this enabled, Fresh reads the X-Forwarded-Proto and X-Forwarded-Host headers and rewrites ctx.url accordingly. If your proxy terminates TLS and forwards X-Forwarded-Proto: https, ctx.url.protocol will be https: instead of http:. See the reverse proxy documentation for details.
With Deno 2.7+, you can scaffold a new Fresh project using deno create (#3706):
The old deno run -Ar jsr:@fresh/init form still works but now shows a deprecation warning.
A non-exhaustive list of the most impactful fixes in this release:
We’re continuing to improve Vite support: upgrading to Vite 8 with Rolldown (#3760) and removing the remaining Babel transforms entirely (#3767).
The other big focus is build-time prerendering (#3766). Mark a route with prerender: true and Fresh renders it to static HTML during the build. Dynamic routes can enumerate their paths too, effectively turning Fresh into a static site generator for pages that don’t need a server.
Follow along on GitHub.
访问原文 返回搜索 https://deno.com/blog/fresh-2.3
本页为82搜索生成的网页快照,内容来自站内索引;演示数据的原文链接仅作示例。