惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

腾讯CDC
博客园 - Franky
MyScale Blog
MyScale Blog
L
LangChain Blog
Martin Fowler
Martin Fowler
Recent Announcements
Recent Announcements
Stack Overflow Blog
Stack Overflow Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园 - 司徒正美
量子位
A
About on SuperTechFans
C
Check Point Blog
大猫的无限游戏
大猫的无限游戏
Last Week in AI
Last Week in AI
小众软件
小众软件
Apple Machine Learning Research
Apple Machine Learning Research
I
InfoQ
V
Visual Studio Blog
Vercel News
Vercel News
B
Blog
爱范儿
爱范儿
aimingoo的专栏
aimingoo的专栏
U
Unit 42

Deno

Deno 2.8 | Deno Claw Patrol: an open-source security firewall for agents | Deno Fresh 2.3: Zero JS by default, View Transitions, and Temporal support | Deno Deno 2.7: Temporal API, Windows ARM, and npm overrides | Deno Build a dinosaur runner game with Deno, pt. 6 | Deno Build a dinosaur runner game with Deno, pt. 5 | Deno Deno Deploy is Generally Available | Deno Introducing Deno Sandbox | Deno Build a dinosaur runner game with Deno, pt. 4 | Deno Build a dinosaur runner game with Deno, pt. 3 | Deno Build a dinosaur runner game with Deno, pt. 2 | Deno React / Next.js Denial-of-Service Vulnerability: Deno Deploy users protected | Deno Deno 2.6: dx is the new npx | Deno Build a dinosaur runner game with Deno, pt. 1 | Deno React Server Functions / Next.js Vulnerability: Deno Deploy users protected | Deno My highlights from the new Deno Deploy | Deno Deno's Other Open Source Projects | Deno How Deno protects against npm exploits | Deno Help Us Raise $200k to Free JavaScript from Oracle | Deno Deno 2.5: Permissions in the config file | Deno Fresh 2.0 Graduates to Beta, Adds Vite Support | Deno Deno 2.4: deno bundle is back | Deno JavaScript™ Trademark Update | Deno What's coming to JavaScript | Deno A brief history of JavaScript | Deno Reports of Deno's Demise Have Been Greatly Exaggerated | Deno An Update on Fresh | Deno How Plaid migrated 100 services to a new database platform 5x faster with Deno | Deno Deno 2.3: Improved deno compile, local npm packages, and more | Deno Add JSR packages with pnpm and Yarn | Deno
Deno 1.19 Release Notes | Deno
2022-02-17 · via Deno

Deno 1.19 has been tagged and released with the following new features and changes:

  • deno vendor
  • Permission prompt by default
  • Files, network sockets, and stdio are now native web streams
  • CompressionStream and DecompressionStream are now supported
  • Better errors for ops and resource sanitizers in Deno.test
  • console.log now displays circular references in logged objects
  • Deno.File has been renamed to Deno.FsFile
  • deno compile now works more reliably
  • Allow disabling clear screen on file watcher restarts
  • deno coverage gets --output flag
  • Stabilization of signal listener APIs
  • Serve HTTP over Unix sockets
  • New unstable API: Deno.Conn#setNoDelay() and Deno.Conn#setKeepAlive()
  • New unstable API: Deno.getUid
  • New unstable API: Deno.networkInterfaces
  • Improvements to the LSP
  • V8 9.9

If you already have Deno installed, you can upgrade to 1.19 by running:

If you are installing Deno for the first time, you can use one of the methods listed below:


curl -fsSL https://deno.land/x/install/install.sh | sh


iwr https://deno.land/x/install/install.ps1 -useb | iex


brew install deno


scoop install deno


choco install deno

New features and changes

deno vendor

Over the last couple of months we have received feedback that users would like to be able to vendor their program’s dependencies into their code repositories. This is a useful feature, if you want make sure that only some very specific code gets executed by your application.

Previously, we have recommended that users check in their DENO_DIR into the repository to do vendoring. While this generally works, it is not a great user experience. The files in DENO_DIR have non intuitive names made up of hex strings that don’t look good in version control.

In this release we are introducing an improved method to vendor dependencies: deno vendor. This subcommand can be invoked with one or more entrypoints to the modules to be vendored. Deno will then build a module graph from these files by analyzing all of the imports and exports of the modules. The resulting list of modules is then written to the vendor/ folder with names that as closely resemble the original module names as possible. Sometimes we have to strip or append some characters to the name to make the specifier a valid file system path. Inside of the vendor folder we then generate an import map that maps all of the remote modules that were vendored to the local vendor directory.

To then use the vendored dependencies in your program, you just add --import-map=vendor/import_map.json to your Deno invocations. You can also add --no-remote to your invocation to completely disable fetching of remote modules (only allow importing modules in the vendor directory).

$ deno vendor main.ts
$ tree
.
├── main.ts
└── vendor
    ├── deno.land
    ├── import_map.json
    └── raw.githubusercontent.com
$ deno run --no-remote --import-map=vendor/import_map.json main.ts

The vendor directory should be checked into version control. The file names stay as consistent as possible across runs of deno vendor to minimize bloated git diffs.

One other great use case for this feature is to allow you to temporarily add some console.log entries or similar to dependency code while debugging. To do this you can just vendor the specific module you want to modify, and then edit that source code in the vendor directory. Once you are done debugging, you can just remove the vendor directory again and continue as normal.

We’d love to hear your feedback on this feature. We are aware of a few issues that we’ll iron out over the next few weeks, but it is working well in most cases.

Permission prompt by default

One complaint is that Deno requires so many command-line flags. Often these flags are --allow-* permission allowances. Before this version, Deno would throw an exception if a permission check fails, requiring users to specify these flags each time. Now in Deno 1.19, if access is not granted, a command-line prompt will allow the user to interactively accept or deny each individual access check.

# deno run https://deno.land/std/http/file_server.ts
⚠️  ️Deno requests read access to <CWD>. Run again with --allow-read to bypass this prompt.

Allow? [y/n (y = yes allow, n = no deny)] y
⚠️  ️Deno requests net access to "0.0.0.0:4507". Run again with --allow-net to bypass this prompt.

Allow? [y/n (y = yes allow, n = no deny)] y
HTTP server listening on http://localhost:4507/

This feature has long been available by using the --prompt flag, but is now on by default. To disable the prompt, use --no-prompt. These permission prompts will only happen if you’re connected to a TTY, so one shouldn’t need to supply --no-prompt in, for example, CI scripts.

Files, network sockets, and stdio are now native web streams

The Deno.FsFile and Deno.Conn interfaces now have readable and writable properties of type ReadableStream and WritableStream respectively. This makes them integrate with other web APIs that use web streams very nicely. Some examples:


const file = await Deno.create("./example.html");
const resp = await fetch("https://example.com");
await resp.body.pipeTo(file.writable);


const resp = await fetch("https://example.com", {
  method: "POST",
  body: Deno.stdin.readable,
});
console.log("Upload succeeded?", resp.ok);

Because all of the APIs in Deno now support web streams out of the box, including our native HTTP server, composing all these APIs together is now very simple:

import { serve } from "https://deno.land/std/http/server.ts";

serve(async (req) => {
  if (req.method === "POST") {
    
    const path = await Deno.makeTempFile();
    const file = await Deno.create(path);
    await req.body.pipeTo(file.writable);
    return new Response(`Saved file to ${path}`);
  } else {
    
    const path = "./example.html";
    const file = await Deno.open(path);
    return new Response(file.readable, {
      headers: { "content-type": "text/html" },
    });
  }
});

The new readable and writable properties can also be composed with built in stream transformers like TextEncoderStream or CompressionStream. Here is an example of a program that reads from stdin, performs gzip compression, and then writes the result to stdout:

await Deno.stdin.readable
  .pipeThrough(new CompressionStream("gzip"))
  .pipeTo(Deno.stdout.writable);

CompressionStream and DecompressionStream are now supported

This release is adding two new built-in stream transformers called CompressionStream and DecompressionStream. This web standard API allows you to compress and decompress data in multiple file formats (currently gzip and deflate).

The API has already shipped in Chrome, and is hopefully coming to other browsers soon.

Here is an example of performing streaming decompressing a .gz file:

const input = await Deno.open("./file.txt.gz");
const output = await Deno.create("./file.txt");
await input.readable
  .pipeThrough(new DecompressionStream("gzip"))
  .pipeTo(output.writable);

We’re currently working with the web standards groups to add support for the brotli compression algorithm to the CompressionStream and DecompressionStream APIs. You can follow this issue for updates.

Better errors for ops and resource sanitizers in Deno.test

Since the first stable release of deno test it has had resource and op sanitizers. These sanitizers check that a test does not leak resources (like open file handles) or async ops (like timers). This is done because leaking resources or async ops can often cause hard to debug test failures or flakes, and they often point to logic errors in the code.

This release completely overhauls the error messages from these sanitizers to make them more usable, and easier to understand for new users. Take this test that leaks a Deno.FsFile resource, for example:

Deno.test("leaky", () => {
  const file = Deno.openSync("/etc/passwd");
});

It would have previously failed with this error:

running 1 test from ./test.ts
test leaky ... FAILED (4ms)

failures:

leaky
AssertionError: Test case is leaking resources.
Before: {
  "0": "stdin",
  "1": "stdout",
  "2": "stderr"
}
After: {
  "0": "stdin",
  "1": "stdout",
  "2": "stderr",
  "3": "fsFile"
}

Make sure to close all open resource handles returned from Deno APIs before
finishing test case.
    at assert (deno:runtime/js/06_util.js:41:13)
    at resourceSanitizer (deno:runtime/js/40_testing.js:153:7)
    at async Object.exitSanitizer [as fn] (deno:runtime/js/40_testing.js:169:9)
    at async runTest (deno:runtime/js/40_testing.js:427:7)
    at async Object.runTests (deno:runtime/js/40_testing.js:540:22)

failures:

        leaky

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out (11ms)

It now fails with a much more concise and useful message:

running 1 test from ./test.ts
test leaky ... FAILED (4ms)

failures:

leaky
AssertionError: Test case is leaking 1 resource:

 - A file (rid 3) was opened during the test, but not closed during the test. Close the file handle by calling `file.close()`.

    at assert (deno:runtime/js/06_util.js:46:13)
    at resourceSanitizer (deno:runtime/js/40_testing.js:313:7)
    at async Object.exitSanitizer [as fn] (deno:runtime/js/40_testing.js:329:9)
    at async runTest (deno:runtime/js/40_testing.js:587:7)
    at async Object.runTests (deno:runtime/js/40_testing.js:700:22)

failures:

        leaky

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out (10ms)

The same treatment has also been applied to async op sanitizer errors. This test leaks a sleep operation:

Deno.test("leaky", () => {
  setTimeout(() => {}, 1000);
});

Previously it would have failed with this error:

running 1 test from ./test.ts
test leaky ... FAILED (4ms)

failures:

leaky
AssertionError: Test case is leaking async ops.
Before:
  - dispatched: 0
  - completed: 0
After:
  - dispatched: 2
  - completed: 1
Ops:
  op_sleep:
    Before:
      - dispatched: 0
      - completed: 0
    After:
      - dispatched: 2
      - completed: 1

Make sure to await all promises returned from Deno APIs before
finishing test case.
    at assert (deno:runtime/js/06_util.js:41:13)
    at asyncOpSanitizer (deno:runtime/js/40_testing.js:121:7)
    at async resourceSanitizer (deno:runtime/js/40_testing.js:137:7)
    at async Object.exitSanitizer [as fn] (deno:runtime/js/40_testing.js:169:9)
    at async runTest (deno:runtime/js/40_testing.js:427:7)
    at async Object.runTests (deno:runtime/js/40_testing.js:540:22)

failures:

        leaky

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out (9ms)

The new error has a helpful hint about what causes this problem, and it even includes a stack trace of where the async operation was started so you don’t have to manually try to find it with console logs:

running 1 test from ./test.ts
test leaky ... FAILED (8ms)

failures:

leaky
Test case is leaking async ops.

- 1 async operation to sleep for a duration was started in this test, but never completed. This is often caused by not cancelling a `setTimeout` or `setInterval` call. The operation was started here:
    at Object.opAsync (deno:core/01_core.js:155:42)
    at runAfterTimeout (deno:ext/timers/01_timers.js:234:31)
    at initializeTimer (deno:ext/timers/01_timers.js:200:5)
    at setTimeout (deno:ext/timers/01_timers.js:337:12)
    at ./test.ts:2:3
    at testStepSanitizer (deno:runtime/js/40_testing.js:432:13)
    at asyncOpSanitizer (deno:runtime/js/40_testing.js:145:15)
    at resourceSanitizer (deno:runtime/js/40_testing.js:360:13)
    at Object.exitSanitizer [as fn] (deno:runtime/js/40_testing.js:415:15)
    at runTest (deno:runtime/js/40_testing.js:673:18)

failures:

        leaky

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out (17ms)

console.log now displays circular references in logged objects

Previously inspection of circular objects would only tell you that there is some sort of circularity, but not which objects are being referenced in it. With this change, we now provide a counter and reference indicator of the object causing a circular reference.

Example:

const x = { a: {}, b: {}, foo: { deno: "land", bar: 1 } };
x.a.x = x;
x.b.y = x;
console.log(x);
<ref *1> { a: { x: [Circular *1] }, b: { y: [Circular *1] }, foo: { deno: "land", bar: 1 } }

This doesn’t only apply to objects, but also Error.causes:

const x = new Error("foo");
const y = new Error("bar", { cause: x });
x.cause = y;
console.log(y);
<ref *1> Error: bar
    at file:///dev/denoland/dotcom/test.ts:2:11
Caused by Error: foo
    at file:///dev/denoland/dotcom/test.ts:1:11
Caused by [Circular *1]

Deno.File has been renamed to Deno.FsFile

Deno’s abstraction for file system files was previously called Deno.File. Unfortunately this name causes a lot of confusion for users because of the File Web API that is available globally both in browsers and Deno.

To avoid confusion in the future we’ve decided to deprecate Deno.File and replace it with Deno.FsFile which should better convey the message that it abstracts files on the file system. Deno.File API will be available until Deno 2.0, but we suggest you migrate existing code immediately.

This is purely a rename - all methods on the Deno.File class are still the same. Only the name changes from Deno.File to Deno.FsFile.

A new lint was added to deno lint that will help catch uses of Deno.File and suggest changes to avoid using a deprecated API.

deno compile now works more reliably

Previously deno compile would bundle your entire JS program into a single ES module during compilation. This bundling sometimes leads to the code not behaving exactly the same as prior to bundling: stack traces might be off, import.meta.url is incorrect, order of execution might differ slightly to prior to bundling.

To combat this deno compile now serializes your ES module graph into the produced binary “as is” without bundling. This means that the order of execution of the code stays correct, and things like import.meta.url stay intact.

To do this we are making use of our eszip library and file format, which allows for very fast serialization and deserialization of ES module graphs.

Thank you to @williamtetlow for contributing this feature.

Allow disabling clear screen on file watcher restarts

Deno ships with a built-in file watcher that restarts running process when files change; it can be used with multiple subcommands by passing the --watch flag. Deno automatically discovers which files should be watched, but you can additionally pass paths you want to be watched (deno run --watch=file1.ts,file2.js script.ts).

The file watcher automatically cleared your terminal screen on each restart, but users reported that in some situations this is not desirable. In this release we added the --no-clear-screen flag that can be used with the --watch flag to tell Deno not to clear the terminal screen:

deno lint --watch --no-clear-screen

Thank you to @ah-yu for contributing this feature.

deno coverage gets --output flag

This release adds --output flag to deno coverage subcommand that can be used when producing lcov report.

Before this release the report was printed to standard output and could be piped manually to a file:

deno coverage --lcov cov/ > cov.profile

Starting with this release you can instead use --output flag to write to a file directly:

deno coverage --lcov --output=cov.profile cov/

Thank you to @VishnuJin for contributing this feature.

Stabilization of signal listener APIs

We have stabilized the signal listener APIs in this release. These APIs can be used to intercept and handle signals like SIGINT (Ctrl-C in your shell) with custom logic. You don’t need to pass the --unstable flag to use these APIs anymore.

const listener = () => {
  console.log("Got SIGTERM!");
};


Deno.addSignalListener("SIGTERM", listener);


Deno.removeSignalListener("SIGTERM", listener);

Note: While this API is now stable, the API is not yet available on Windows. Please follow the issue #10236 for updates on this. Stabilization here means that the API surface will not be changed in future minor releases.

Serve HTTP over Unix sockets

Deno’s HTTP server API now supports connections established over Unix sockets in addition to TCP.

import { serveListener } from "https://deno.land/std/http/server.ts";

const listener = Deno.listen({ transport: "unix", path: "/path/to/socket" });

serveListener(listener, (req) => {
  return new Response("Hello World");
});

Just like with Unix sockets in general, this API is still unstable. You need to pass the --unstable flag to use it.

Thank you to @ylxdzsw for contributing this feature.

New unstable API: Deno.Conn#setNoDelay() and Deno.Conn#setKeepAlive()

Two new APIs were added to Deno.Conn:

  • Deno.Conn.setNoDelay()
  • Deno.Conn.setKeepAlive()

These APIs allow to configure use of Nagle’s algorithm and keepalive functionality for TCP connections.

Example:

const conn = await Deno.connect({ hostname: "127.0.0.1", port: 3500 });


conn.setNoDelay(false);


conn.setNoDelay(true);


conn.setKeepAlive(true);


conn.setKeepAlive(false);

Note: The API is still unstable. You need to pass the --unstable flag to use it.

Thank you to @yos1p for contributing this feature.

New unstable API: Deno.getUid

Deno 1.19 adds a new Deno.getUid API. Upon invocation this returns the user ID of the Deno process on Linux and macOS. You need to pass the --allow-env permission flag to use this API.

const uid = Deno.getUid();
console.log(uid); 
$ deno run --unstable --allow-env getuid.ts
501

Note: The API is still unstable. You need to pass the --unstable flag to use it.

New unstable API: Deno.networkInterfaces

This release adds a new Deno.networkInterfaces API. This API returns an array of objects containing information about the available network interfaces. You need to pass the --allow-env permission to use this API.

const interfaces = Deno.networkInterfaces();
console.log(interfaces); 
$ deno run --unstable --allow-env network_ifs.js
[
  {
    family: "IPv4",
    name: "lo0",
    address: "127.0.0.1",
    netmask: "255.0.0.0",
    scopeid: null,
    cidr: "127.0.0.1/8",
    mac: "00:00:00:00:00:00"
  },
  ...
]

Note: The API is still unstable. You need to pass the --unstable flag to use it.

Improvements to the LSP

As always, this release brings another round of improvements to the LSP:

Code action to replace specifiers that are redirected

When importing an module from a registry like https://deno.land/x without specifying a version, the registry will automatically redirect the request to the latest version of that module. If this happens, the LSP will now offer to replace the specifier with the one that was redirected to. In combination with the warning that is shown for unversioned imports, this will make it easier for users to use versioned imports across their codebase.

Import completions now take into account import maps

Import completions now interact nicely with import maps. Specifiers specified in your import map will be offered as completions.

The hover cards that the Deno LSP offers now correctly render @link tags in JSDoc comments as clickable links to symbols. Here is an example of linking to a symbol in a deprecation message:

V8 9.9

This release of Deno upgrades V8 to 9.9, which adds some new Intl features:

Intl.Locale extensions

This release adds seven new properties to the Intl.Locale object: calendars, collations, hourCycles, numberingSystems, timeZones, textInfo, and weekInfo.

These can be used to determine valid values for these properties for a given language. For example, here are all of the calendars that the Egyptian language supports:

const arabicEgyptLocale = new Intl.Locale("ar-EG");
arabicEgyptLocale.calendars;

Intl Enumeration

This release also adds a new Intl.supportedValuesOf(code) function that returns the list supported identifiers in V8 for the Intl APIs. For example to get a list of all calendars supported by the Intl APIs:

Intl.supportedValuesOf("calendar");

Or all supported currencies:

Intl.supportedValuesOf("currency");

HN Comments