
























We are excited to announce the release of Deno 1.40, a significant step forward in the evolution of Deno. This new version is packed with features that enhance the Deno experience, introducing the powerful Temporal API for advanced date and time operations, and embracing the latest decorator syntax for more expressive code. Alongside these advancements, we’ve implemented a series of deprecations, stabilizations, and removals aimed at streamlining Deno’s capabilities and preparing for Deno 2.
If you already have Deno installed, upgrade to version 1.40 in your terminal with:
If you don’t yet have Deno installed, you can install it with one of the following commands, or many other ways.
MacOS / Linux Install
curl -fsSL https://deno.land/install.sh | shWindows Install
irm https://deno.land/install.ps1 | iex
Here’s an overview of what’s new in Deno 1.40:
Temporal APIimport.meta.filename and import.meta.dirnameimports in deno.jsonrejectionhandled eventdeno lint updatesTemporal APIThe Temporal API is designed to
address some of the shortcomings and complexities associated with the existing
Date object in JavaScript.
Temporal proposal is actively implemented by all major JavaScript engines and
we’re happy to announce it’s now available in Deno with the
--unstable-temporal flag.
const birthday = Temporal.PlainMonthDay.from("12-15"); const birthdayIn2030 = birthday.toPlainDate({ year: 2030 }); console.log(birthdayIn2030.toString()); console.log("day of week", birthdayIn2030.dayOfWeek);
It’s unlikely that Temporal API will be changed and we aim to stabilize it in
Deno 2. We encourage you to explore the
Temporal API docs.
Deno now supports import.meta.filename and import.meta.dirname properties.
These properties mirror __filename and __dirname properties from the
CommonJS module system:
import.meta.filename provides the absolute path to the current module fileimport.meta.dirname provides the absolute path to the directory containing
the current module fileBoth of these properties are aware of the OS specific path separator and provide proper separators for the current platform:
console.log(import.meta.filename); console.log(import.meta.dirname);
In Unix:
$ deno run /dev/my_module.ts /dev/my_module.ts /dev/
And in Windows:
$ deno run C:\dev\my_module.ts C:\dev\my_module.ts C:\dev\
These properties are available only for local modules (ie. modules loaded from
the file system) and are undefined for remote modules (modules imported from
http:// or https://).
Deno now supports the TC39 stage 3 Decorators proposal, which will soon be implemented in all browsers.
Decorators are a proposal for extending JavaScript classes which is widely adopted among developers in transpiler environments, with broad interest in standardization. TC39 has been iterating on decorators proposals for over five years. This document describes a new proposal for decorators based on elements from all past proposals.
This feature is available in .ts, .jsx and .tsx files. Support in pure
JavaScript is waiting on implementation in V8.
Here is an example of an @trace decorator that logs out whenever a function is
called, and when it returns:
function trace(fn: any, ctx: ClassMethodDecoratorContext) { return function (...args: unknown[]) { console.log("ENTERED", ctx.name); const v = fn(...args); console.log("EXITED", ctx.name); return v; }; } class App { @trace static start() { console.log("Hello World!"); } } App.start();
If you rely on the legacy “experimental TypeScript decorators”, you can still use them with the following configuration:
{ "compilerOptions": { "experimentalDecorators": true } }
Note: There was a bug discovered after v1.40.0 was cut that TypeScript’s
experimentalDecorators was still turned on in the LSP. Please upgrade to
v1.40.1.
imports in deno.jsonThe imports field in deno.json now supports a simpler syntax for specifying
dependencies that have subpath exports. Previously, when wanting to use preact
from npm, you had to add this to your imports object in your deno.json:
{ "imports": { "preact": "npm:preact@10.5.13", "preact/": "npm:/preact@10.5.13/" } }
This allowed you to import both preact, and subpath exports, like
preact/hooks.
In this release we have simplified this, so that you can now just do:
{ "imports": { "preact": "npm:preact@10.5.13" } }
In Deno 1.40.0, this will allow you to import both preact and preact/hooks
from npm.
Previously Deno considered the imports field in deno.json to just be a
regular
import map.
Now, we pre-process the imports field in deno.json and expand any entries
with a npm: prefix on the right hand side into two entries in an internal
import map that we use for resolution.
As we gear up for Deno 2, we’re committed to refining the runtime while ensuring a smooth transition from Deno 1. While most Deno 1 code will remain compatible, we’re streamlining certain APIs for the platform’s long-term health.
We’re introducing deprecations to phase out older APIs, alongside warnings to assist your migration:
window – The global variable window is used often across the
JavaScript ecosystem to test if code is running in a browser. It is an easy
fix to use globalThis or self instead. There is no runtime warning for
this deprecation yet, but it will show up in deno lint in starting this
release.
Deno.run() – This is the old and error-prone subprocess API. We have
since introduced the much more versatile
Deno.Command API which
was stabilized a year ago.
Deno.serveHttp() – Replaced by the faster and simpler Deno.serve().
Documentation here.
Deno.metrics() – To focus on performance, we’re shifting towards more
targeted command-line flags and APIs. Custom metrics implementations are
available via
op_metrics_factory_fn
and a new --strace-ops flag for runtime ops tracing.
Stream-related Functions: Transitioning to Web Streams, we’re deprecating
several Deno.Reader/ Deno.Writer stream functions. The deprecated
functions are still accessible via the Deno standard library:
Deno.iter() and Deno.iterSync()Deno.copy() – available at https://deno.land/std/io/copy.tsDeno.readAll() and Deno.readAllSync() – available at
https://deno.land/std/io/read_all.tsDeno.writeAll() and Deno.writeAllSync() – available at
https://deno.land/std/io/write_all.tsDeno.Buffer – available at https://deno.land/std/io/buffer.tsDeno.FsWatcher.return() – To align with other async iterators, we’re
deprecating this in favor of explicit close methods.
Deno.customInspect – To encourage browser-compatible code, we’ve
switched to Symbol.for("Deno.customInspect").
In Deno 2, we are removing the concept of “resource ids”. Resource ids are integer references to sockets, files, or other resources managed outside of JavaScript. They’re analogous to file descriptors. However most users do not touch these directly, and we’d like to start introducing resources reference by native JavaScript objects. For this reason we’re deprecating these APIs:
Deno.isatty() – instead use the isTerminal() method, for example
Deno.stdout.isTerminal().
Deno.close() – this API also operates on rid. Users are encouraged to
use .close() method on relevant objects instead. For example, file.close()
rather than Deno.close(file.rid).
Deno.resources() – This API also exposes resource ids and has little
utility.
Deno.ftruncate() and Deno.ftruncateSync() – These function are now
avaiable on Deno.FsFile as truncate() and truncateSync().
All rid properties are now deprecated and will be removed in Deno 2.0:
Deno.Conn.ridDeno.FsWatcher.ridDeno.TcpConn.ridDeno.TlsConn.ridDeno.UnixConn.ridDeno.Listener.ridLoading certificates from files is now deprecated, read them yourself instead:
Deno.ListenTlsOptions.certFile - Use Deno.ListenTlsOptions.cert and
Deno.readTextFile instead.Deno.ListenTlsOptions.keyFile - Use Deno.ListenTlsOptions.key and
Deno.readTextFile instead.Deno.ConnectTlsOptions.certFile -Use Deno.ConnectTlsOptions.cert and
Deno.readTextFile instead.Following Deno APIs have been stabilized and un-flagged:
Deno.Conn.ref()Deno.Conn.unref()Deno.connect() for unix transportDeno.connectTlsDeno.stderr.isTerminal()Deno.stdin.isTerminal()Deno.stdout.isTerminal()Deno.TlsConn.handshake()Finally, the unstable API Deno.upgradeHttp has been removed. This API was
error prone and easy to misuse. We encourage everyone to use
Deno.serve() and
Deno.upgradeWebsocket().
rejectionhandled eventWe’ve added support for the
rejectionhandled event,
which is emitted anytime a .catch() handler is attached to a promise that has
already been rejected. Also, this event will only emitted if you have a
unhandledrejection event listener that calls event.preventDefault()
(otherwise the promise will be rejected and the process will exit with an
error).
globalThis.addEventListener("unhandledrejection", (event) => { event.preventDefault(); console.log("unhandledrejection", event.reason); }); globalThis.addEventListener("rejectionhandled", (event) => { console.log( "A .catch() handler was added to the promise after it has already rejected.", event.reason, ); }); const a = Promise.reject(new Error("boom!")); setTimeout(async () => { a.catch(() => console.log("Added catch handler to the promise")); }, 10);
$ deno run main.js
unhandledrejection Error: boom!
at file:///dev/main.js:12:26
Added catch handler to the promise
A .catch() handler was added to the promise after it has already rejected. Error: boom!
at file:///dev/main.js:12:26We’re introducing a new unstable Deno.UnsafeWindowSurface API to address
windowing in Deno. Our goal is to provide a windowing solution for WebGPU
without linking to native windowing systems like X11.
This is a low level API that can be used by FFI windowing libraries like
sdl2, glfw,
raylib, winit and more to
create a WebGPU surface using native window and display handles.
Here’s an example using deno.land/x/sdl2:
import { EventType, WindowBuilder, } from "https://deno.land/x/sdl2@0.8.0/mod.ts"; const win = new WindowBuilder("Hello, World!", 800, 600).build(); const adapter = await navigator.gpu.requestAdapter(); const device = await adapter.requestDevice(); const surface = win.windowSurface(); const context = surface.getContext("webgpu"); context.configure({}); for (const event of win.events()) { if (event.type == EventType.Quit) break; const r = Math.sin(Date.now() / 1000) / 2 + 0.5; const g = Math.sin(Date.now() / 1000 + 2) / 2 + 0.5; const b = Math.sin(Date.now() / 1000 + 4) / 2 + 0.5; const textureView = context.getCurrentTexture().createView(); const renderPassDescriptor = { colorAttachments: [ { view: textureView, clearValue: { r, g, b, a: 1.0 }, loadOp: "clear", storeOp: "store", }, ], }; const commandEncoder = device.createCommandEncoder(); const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor); passEncoder.end(); device.queue.submit([commandEncoder.finish()]); surface.present(); }
Running with deno run --allow-ffi --unstable-webgpu --unstable-ffi:

Here’s a demo music player app built using this API: https://github.com/littledivy/wgui
For more details on low level use, check out the PR: https://github.com/denoland/deno/pull/21835
Read more about GPUCanvasContext
here.
The following built-in Node APIs are now available:
crypto.pseudoRandomBytes()fs.contantsfs.cp()fs.cpSync()fs.promises.cp()net.ClientRequest.setNoDelay()net.UdpSocket.ref() and net.UdpSocket.unref()net.WriteStream.isTTYos.cpus()os.machine()process.abort()process.on("rejectionHandled")Additionally we fixed several bugs in already supported Node.js APIs:
child_process.ChildProcess.send() on Windowscrypto.createDeciperiv() now supports aes-192-ecb and aes-256-ecbfs.promises.readFile()http.ClientRequest.socket.remoteAddresshttp.ClientRequest.socket.remotePortquerystring.stringify()test module supports nested testszlib.brotliCompress()zlib.brotliCompressSync()zlib.gzipSync()zlib.unzipSync()Since v1.39.0, we’ve strengthened integration with our embedded instance of TypeScript’s Language Service API to achieve significant performance boosts and some bug fixes. Data is exchanged between Rust and the TypeScript isolate more efficiently and less frequently, owing to smarter project-state synchronization and caching.
Quality-of-life improvement for users of the jsxImportSource compiler option:
The specified remote resource will be cached automatically when the containing
deno.json file is saved. This was necessary because unlike an uncached import,
the diagnostics resulting from this missing resource were vague and did not
point to the cause of the problem (neither from the perspective of the user nor
the language server’s quick-fix generator).
Auto-import completions will work more consistently. Some cases where the completion resolution would silently error are fixed, due to better state preservation in the TypeScript isolate. Import-mapped NPM specifiers with subpaths are correctly substituted with the expected alias.
There is a new diagnostic printer in for deno lint and deno doc. We’ll be
expanding this to other subcommands in the coming release.

deno lint updatesThree new rules are available in deno lint:
no-consoleno-self-compareno-windowThe no-window rule is enabled by default, while the other two are opt-in and
you need to enable them in your configuration file:
{ "lint": { "rules": ["no-console", "no-self-compare"] } }
Maintaining code quality is paramount to the success of your project and we all found ourselves in a situation where we need to suppress a warning from a linter.
In most instances we just ignore a warning and move on, but this approach doesn’t help out team members or future self in understanding why a particular warning was suppressed.
deno lint now supports additional explanation in // deno-lint-ignore and
// deno-lint-ignore-file directives:
var __global$ = globalThis || (typeof window !== "undefined" ? window : self); var cu=Object.create;var R=Object.defineProperty;var lu=Object.getOwnPropertyDescriptor;var iu=Object.getOwnPropertyNames;var nu=Object.getPrototypeOf...
export function noop() {}
We’re evolving our approach to managing unstable features. The --unstable
flag, while useful, has been somewhat imprecise, activating all unstable
features simultaneously. In Deno 1.38, we introduced more
granular flags to give you finer
control over specific unstable features, for example --unstable-webgpu enables
the new WebGPU API. Building on this, Deno 1.40 marks the beginning of the
deprecation phase for the broad --unstable flag, setting the stage for its
removal in Deno 2.
Additionally, we’ve improved type checking with respect to unstable APIs in
deno check and the LSP. Now, type definitions for both stable and unstable
APIs are automatically included during type checking. This eliminates the need
to specify --unstable for accessing unstable API type definitions. However,
remember to enable the specific unstable feature flags when running your
program. Omitting these flags will still lead to errors, ensuring you’re aware
of the unstable features in use.
This change streamlines development, offering more clarity and control over the use of Deno’s feature set.
We couldn’t build Deno without the help of our community! Whether by answering questions in our community Discord server or reporting bugs, we are incredibly grateful for your support. In particular, we’d like to thank the following people for their contributions to Deno 1.40: Anwesh, Dean Srebnik, Joel Walker, Jovi De Croock, Julien Cayzac, Jérôme Benoit, Kenta Moriuchi, Kitson Kelly, Lino Le Van, Raashid Anwar, cions, king8fisher, nokazn, 林炳权.
Would you like to join the ranks of Deno contributors? Check out our contribution docs here, and we’ll see you on the list next time.
Believe it or not, the changes listed above still don’t tell you everything that got better in 1.40. You can view the full list of pull requests merged in Deno 1.40 on GitHub here.
Thank you for catching up with our 1.40 release, and we hope you love building with Deno!
🍋 Fresh 1.6 is out.
Fresh v1.6 apps have expanded plugin APIs, faster route matching, and official Tailwind CSS support.
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。