Deno 1.0, let’s take a look

Deno 1.0, let’s take a look

Editor's note: Li Songfeng, the translator of this article, a senior technical book translator, has translated and published more than 40 technical and interactive design monographs. He is currently a senior expert in the Web front-end development of 360 Qi Dance Group, a member of the 360 ​​Front-end Technical Committee, and a W3C AC representative.

Original Address: https://blog.logrocket.com/deno-1-0-what-you-need-to-know/ original author: David Else

After nearly two years of waiting, it was officially announced that Deno 1.0 will be released on May 13. Today, the API has been frozen and the countdown has begun.

With the help of the founder's name and his forward-looking vision, Deno's release is undoubtedly the most exciting and controversial JavaScript topic in the near future.

Deno is a general-purpose JavaScript/TypeScript programming environment that integrates many of the best open source technologies and provides a comprehensive solution in a small executable file.

As the founder of Node.js, Ryan Dahl created Deno. Deno took advantage of the new features of JavaScript after the release of Node.js in 2009, and also solved the design flaws mentioned by Ryan in his "Top 10.Regrets of Node.js" (speech). Some people call it a successor to Node.js, but the author himself did not say that.

Unlike Node.js using C++, Deno is developed using Rust and built on the Tokio (https://tokio.rs/, Rust asynchronous runtime) platform. But similar to Node.js, Deno also uses the V8 engine to run JavaScript. Built-in TypeScript is an obvious feature of Deno. Although it needs to be compiled into JavaScript before running, this process is done internally, so it looks like Deno natively supports TypeScript.

1. Get started

You can download Deno according to the instructions on the official website homepage (https://deno.land/). To upgrade to the new version, run deno upgrade. If the version of Deno you installed before is too low, you can try to run the terminal script installation again.

To understand the Deno subcommands, use any of the following commands.

  • deno [subcommand] -h: display summary
  • deno [subcommand] --help: display detailed information

This article will introduce the key features of Deno 1.0, including examples of applying these features using the latest syntax. We will use TypeScript as much as possible, and equivalent JavaScript is of course no problem.

I believe you will love Deno after reading this article. This article will formally lead readers into the door of Deno development.

2. Security

Deno is safe by default. In contrast, Node.js has access to the file system and network by default.

To run a program that needs to start a child process without authorization, such as:

deno run file-needing-to-run-a-subprocess.ts

If you need relevant permissions, you will see a warning message:

error: Uncaught PermissionDenied: access to run a subprocess, run again with the --allow-run flag

Deno uses command line options to explicitly allow access to different parts of the system. The most commonly used include:

  • surroundings
  • The internet
  • File system read/write
  • Run child process

To understand the full permissions of the included example, run deno run -h.

The best practice is to use permission whitelists for read, write, and net. This allows you to specify more specifically what Deno is allowed to access. For example, to grant Deno read-only access to the/etc directory, you can do this:

deno --allow-read=/etc

2.1 Shortcuts to use permissions

It quickly becomes troublesome to authorize every time you run an application. For this, the following methods can be used.

1. Allow all permissions

You can use --allow-all or shortcut-A. This is not recommended, because it will not control specific permissions.

2. Write a bash script

Write a bash script to run the application and authorize the minimum permissions required by the application.

#!/bin/bash
//Allow running child processes and file system write permissions deno run --allow-run --allow-write mod.ts

The disadvantage of this method is that you may have to write separate scripts for running, testing, and packaging.

3. Use Task Runner

You can use the GNU tool make to create a file containing a set of Deno commands and related permissions. You can also use the Deno-specific version of Drake (https://deno.land/x/drake/).

4. Safe and executable Deno program

Use deno install to install a Deno program (https://github.com/denoland/deno/tree/master/docs) that contains the permissions required for its execution. After installation, the path of this program is in $PATH.

3. Standard Library

The Deno standard library (https://deno.land/std/) contains commonly used modules and is maintained by the Deno project to ensure that they can be used in Deno. The standard library covers the most commonly used tools, and the API style and features mirror the standard library of the Go language.

JavaScript has always been criticized for lack of a standard library. Users have to repeat the "inventing wheel" for this. Developers often search the npm repository to find modules that solve common problems, and these modules should have been provided by the platform.

Third-party packages like React that solve complex problems are another matter, but simple tasks like generating UUIDs (https://en.wikipedia.org/wiki/Universally_unique_identifier) ​​are best done using the standard library. These small libraries can be used as components of larger libraries, making development faster and less frightening. I don’t know how many times a popular library is suddenly declared obsolete, and users can only maintain it themselves or look for new alternative libraries. The survey shows that 10-20% of commonly used open source software packages are no longer actively maintained.

3.1 Built-in modules and corresponding npm packages

Deno module

Description

npm package

colors

Set color for terminal output

chalk, kleur, colors

datetime

Help handle JavaScript's Date object

encoding

Added support for external data structures such as base32, binary, csv, toml and yaml

flags

Help with command line parameters

minimist

fs

Help implement file system operations

http

Support access to local files via HTTP

http-server

log

Used to create logs

winston

testing

Used for unit testing and benchmarking

chai

uuid

Generate UUID

uuid

ws

Help create WebSocket client/server

Ws

4. Built-in TypeScript

TypeScript is a superset of JavaScript and adds explicit type declarations. Any valid JavaScript is also valid TypeScript, so there is no cost to convert your code to TypeScript. Just change the extension to .ts, and then add the type.

With TypeScript in Deno, you don't have to do anything. If you don't have Deno, you must compile TypeScript to JavaScript before you can run it. Deno compiles it for you internally, which makes it easier for you to use TypeScript.

4.1 Use your own tsconfig.json

Those familiar with TypeScript may know to use the tsconfig.json file to specify compilation options. But this file is not necessary when using Deno. Because Deno has its own default configuration. If you want to use your own tsconfig.json and its options conflict with Deno, you will see a warning message.

This feature requires using the -c option and specifying your own tsconfig.json.

deno run -c tsconfig.json [file-to-run.ts]

For details of the default tsconfig.json, you can refer to the Deno manual (https://github.com/denoland/deno/tree/master/docs).

If you are like most developers, you will be happy to hear that Deno uses strict mode by default. Unless someone deliberately overwrites this setting, Deno will do its best to report sloppiness in the code to the user.

5. Deno stays close to Web standards

The development of Web standards takes a long time, and once published, no one can turn a blind eye. Although all kinds of frameworks are on the stage, the web standards are always the same. The time spent on learning Web standards will never be wasted, because no one dared to overthrow the Web. In the foreseeable future decades, even to the end of your career, the Web will continue to exist and develop.

fetch is a Web API used to obtain resources. There is a JavaScript method in the browser called fetch(). If you want to use this standard API in Node.js, you need to rely on the third-party Node Fetch (https://github.com/node-fetch/node-fetch). In Deno, this API is built-in, just like the version in the browser, out of the box.

Deno 1.0 provides the following Web-compatible APIs.

  • addEventListener
  • atob
  • btoa
  • clearInterval
  • clearTimeout
  • dispatchEvent
  • fetch
  • queueMicrotask
  • removeEventListener
  • setInterval
  • setTimeout
  • AbortSignal
  • Blob
  • File
  • FormData
  • Headers
  • ReadableStream
  • Request
  • Response
  • URL
  • URLSearchParams
  • console
  • isConsoleInstance
  • location
  • onload
  • onunload
  • self
  • window
  • AbortController
  • CustomEvent
  • DOMException
  • ErrorEvent
  • Event
  • EventTarget
  • MessageEvent
  • TextDecoder
  • TextEncoder
  • Worker
  • ImportMeta
  • Location

The above APIs are in the top-level scope of the program. This means that if you don't use any of the methods in the Deno() namespace, your code should be able to run in Deno and the browser at the same time. Although Deno's APIs are not 100% compliant with Web standards, they are still a major benefit to front-end developers.

6. ECMAScript module

One major change of Deno compared to Node.js is the use of the official ECMAScript module standard instead of the old CommonJS. Node.js did not support ECMAScript modules in 13.2.0 until the end of 2019. Even so, the support is still incomplete, and the controversial .mjs extension needs to be included.

Deno waved goodbye to the past by embracing modern web standards in its modular system. Modules can be referenced using URLs or file paths with mandatory extensions. E.g:

import * as log from "https://deno.land/std/log/mod.ts";import {outputToConsole} from "./view.ts";

6.1 Problems using extensions

Deno wants the module to include the file extension, but TypeScript doesn't want it:

Using extensions is logical and an obvious way. Unfortunately, reality is always more complicated than ideal. So far, you can use the Visual Studio Code Deno extension (https://marketplace.visualstudio.com/items?itemName=axetroy.vscode-deno) to solve this problem in the Deno project.

TypeScript founders seem to have their own views on this issue. Before finally abandoning CommonJS, I don't think there will be a simple solution to this problem.

For wise but older programming gods, we still need a little more patience. I hope they will abandon these outdated formats as soon as possible, and punish those who hold on to them and hurt us.

7. Package Management

Deno's package management approach has undergone a radical change. No longer relying on centralized warehouses, Deno's package management is characterized by decentralization. Anyone can host a package just like hosting any type of file on the Web.

Centralized warehouses like npm have both advantages and disadvantages, and this is where Deno has been controversial.

7.1 Deno's new containment management mechanism

Importing a package has become so easy that it may scare you.

import {assertEquals} from "https://deno.land/std/testing/asserts.ts";

Let's analyze the changes below.

  • There is no longer a centralized package manager, but instead import ECMAScript modules directly from the Web.
  • No more "magic" Node.js module parsing. Now, the intuitive syntax makes it easier to locate the source.
  • There is no more node_modules directory. On the contrary, the dependency will hide in your hard drive after downloading, you can't see it. If you want to refresh the cache and download again, just add --reload after the command.

If you want to download dependencies near the project code instead of using the global cache, you can use the $DENO_DIR environment variable.

7.2 Find compatible third-party libraries

There is currently a user area (https://deno.land/x/) that stores third-party libraries compatible with Deno, but the navigation design is very simple. For example, you cannot search by popularity or downloads. It is expected that this user area will either be expanded or alternative websites will appear for hosting third-party modules contributed by the community.

Although there is no official support for backward compatibility with Node.js, there are still many libraries and applications that can be used under Deno. Some can be used out of the box, while others require some adjustments.

Library type

compatibility

Run in the browser using ESM syntax

It should be possible to try Pika CDN out of the box (https://www.pika.dev/cdn)

Run in the browser using CommonJS syntax

Use jspm.io (https://jspm.io/) to encapsulate with ESM syntax

Do not run in the browserDo not use Node.js API

Use jspm.io to encapsulate with ESM syntax

Use Node.js API

It may not be available, but you can try this official compatibility layer for Node.js (https://deno.land/std/node/)

7.3 Install third-party modules

Deno is still very new, and the surrounding ecology has yet to be improved. At the time of writing this article, I recommend Pika (https://www.pika.dev/cdn) as the first choice for searching compatible modules after the standard library and user library.

The developers of Pika have already provided a TypeScript type for Deno through ECMAScript, called X-TypeScript-Types (https://dev.to/pika/introducing-pika-cdn-deno-p8b). To find a bag in Pika:

  • First search through https://www.pika.dev/search
  • Found compatible modules; at the time of writing this article, searching for react returned: Package found! However, no web-optimized "module" entry point was found in its package.json manifest.

However, preact is compatible. Click it, then click import, and then copy the import statement that appears to your code:

import * as pkg from'https://cdn.pika.dev/preact@^10.3.0';

7.4 Beyond package.json

The main dependency of the JavaScript ecosystem still relies on package.json. This file has expanded to several roles, such as:

  • Save project metadata
  • List the dependencies of the project with version
  • Distinguish dependencies into dependencies and devDependencies
  • Define the entry point of the program
  • Store terminal scripts related to the project
  • The definition type is newly added to improve the support for ECMAScript modules
{"name": "Project Name",//Metadata "version": "1.0.0",//Metadata "description": "My application",//Metadata "type": "module",//Module function "main": "src/mod.ts",//Module function "scripts": {"build": "npm run _copy-build-files && rollup -c", "build-watch": "npm run _copy-build-files && rollup -cw" },//Script function "license": "gpl-3.0",//Metadata "devDependencies": {"@rollup/plugin-typescript": "^3.1.1 ", "rollup": "^1.32.1", "typescript": "^3.8.3" },//Version and classification function "dependencies": {"tplant": "^2.3.3"}//Version And classification function}

All these functions have been added over time and have now become the standard way for JavaScript ecosystem operation. Many people will forget that this is not a formal standard, and will only remember these functions when necessary. Since JavaScript is so popular, think about it from the beginning.

Deno can't replace the full functionality of package.json, but there are some solutions right now.

7.5 Use deps.ts and URL management version

Deno has a convention of managing pack versions, which is to use a special file deps.ts. In this file, the dependencies will be exported again. In this way, different modules in the application can refer to the same source.

Rather than telling npm which version of the module to download, deps.ts puts the version in the URL:

export {assert} from "https://deno.land/std@v0.39.0/testing/asserts.ts";export {green, bold} from "https://deno.land/std@v0.39.0/fmt/colors.ts";

If you want to update a certain module, you can modify the URL in deps.ts. For example, replace @v0.39.0 with @v0.41.0 so that the new version will be used elsewhere. If you directly import https://deno.land/std@v0.39.0/fmt/colors.ts in each module, then you have to search the entire application and replace them one by one.

Assuming that the previously downloaded modules will not be affected by the later downloaded modules, there is also a security risk. This is why there is an option to create a lock file (https://github.com/denoland/deno/tree/master/docs). This ensures that the newly downloaded module is the same as the originally downloaded module.

7.6 deno doc and the use of JSDoc for metadata

JSDoc was released in 1999, 21 years ago. It is currently the most widely used and supported JavaScript and TypeScript document method. Although not an official web standard, JSDoc is a perfect alternative to all metadata in package.json.

/** * @file Manages the configuration settings for the widget * @author Lucio Fulci * @copyright 2020 Intervision * @license gpl-3.0 * @version 1.0 *

Deno has built-in support for JSDoc and uses it to build a documentation system. Although metadata similar to the above has not been used yet, the deno doc example will read the description of the function and its parameters.

/** * Returns a value of (true?) if the rule is to be included * * @param key Current key name of rule being checked * @param val Current value of rule being checked **/

You can use deno doc <filename> to query your program documentation.

deno doc mod.ts
function rulesToRemove(key: string, val: any[]): boolean Returns a value of if the rule is to be included

If your program is hosted online, you can use this online document viewer: https://doc.deno.land/.

8. Deno's built-in tools

This is the area that has the greatest impact on front-end developers. The current situation of JavaScript tools can be said to be quite messy. Coupled with TypeScript tools, the complexity will increase further.

Does JavaScript itself need to be compiled, so it can be run directly in the browser. So you can quickly know if there is a problem with your code. In short, the threshold is very low, only a text editor and a browser are needed.

Unfortunately, this simplicity and low barriers have been unknowingly destroyed by something called extreme tool worship. As a result, JavaScript development has become a complex nightmare. I once took a complete course that explained how to configure Webpack. Life is short, this meaningless life should be over.

The chaos of tools has made many people eager to return to the state of writing code instead of fiddling with configuration files or worrying about choosing between different competitive standards. Facebook's Rome (https://github.com/facebookexperimental/rome) is a project that emerged to solve this problem. At the time of writing, this project is still in its infancy. Although this project is beneficial, Deno should be a more essential solution.

Deno itself is a complete ecosystem, including runtime and its own module/package management system. This determines that its own built-in tools will have a wider range of applications. Below we will introduce the built-in tools in Deno 1.0 and how to use them to reduce dependence on third-party libraries and simplify development.

Of course, it is impossible for Deno to replace the entire front-end construction tool chain, but we should not be far from this day.

8.1 Test

The test runner is built into the core of Deno in the form of the Deno.test() function, and the assertion library (https://deno.land/std/testing/) is also included in the standard library. Your favorite assertEquals() and assertStrictEq() are not a few, and they also contain some less common assertions, such as assertThrowsAsync().

At the time of writing, there is no test coverage feature. In addition, the monitoring mode also needs to be set using third-party tools such as Denon (https://deno.land/x/denon/).

To understand all the options of the test runner, use deno test --help. Although it is still very limited, it may contain a lot of features in programs you are familiar with, such as Mocha. For example, --failfast will stop when the first error is encountered, and --filter can be used to filter the tests to be run.

1. Use the test runner

The most basic syntax is deno test. This command will run all files in the working directory that end with _test or .test and have the extension .js, .ts, .jsx or .tsx (such as example_test.ts).

import {assertEquals} from "https://deno.land/std/testing/asserts.ts";
Deno.test({ name: "testing example", fn(): void {assertEquals("world", "world"); assertEquals({ hello: "world" }, {hello: "world" }); }, });

If your code uses DOM, you need to provide your own tsconfig.json file, including lib: ["dom", "esnext"]. The details will be described below.

2. Format

Formatting is based on dprint (https://github.com/dprint/dprint), which is an alternative library for Prettier, copying all the approved rules of Prettier 2.0.

To format files, you can use deno fmt <files> or the Visual Studio Code extension (https://marketplace.visualstudio.com/items?itemName=axetroy.vscode-deno), which will be introduced later.

3. Compilation and packaging

Deno can create simple packages through the command line deno bundle, but it also exposes the internal compiler API (https://deno.land/std/manual.md#compiler-api), so users can control their own output. It can be customized for use in the front end. This API is currently marked as unstable, so you need to use the --unstable tag.

Although Deno has some Web-compatible APIs, they are not complete. If you want to compile the front-end TypeScript that references the DOM, you need to tell Deno the relevant type when compiling or packaging. You can use the compiler API option lib.

index.html

<!DOCTYPE html><html lang="en"> <head> <meta charset="UTF-8"/> <meta name="viewport" content="width=device-width, initial-scale=1.0"/> <title>Document</title> </head> <body> <h1 id="greeter">Replace me</h1> </body></html>

test-dom.ts

let greeter: HTMLElement | null = document.getElementById("greeter")!;//Please forgive the Non-Null Assertion Operator
greeter.innerText = "Hello world!";

compile.ts

const [errors, emitted] = await Deno.compile("test-dom.ts", undefined, {lib: ["dom", "esnext"],//include "deno.ns" for deno namespace outDir: "dist ",});
if (errors) {console.log("There was an error:"); console.error(errors);} else {console.log(emitted);//normally we would write the file}

The following is the result printed in the terminal.

{dist/test-dom.js.map: "{\"version\":3,\"file\":\"test-dom.js\",\"sourceRoot\":\"\",\" sources\":[\"file:///home/david/Downloads/deno-arti...", dist/test-dom.js: "\"use strict\";\nlet greeter = document.getElementById(/"greeter\");\ngreeter.innerText =/"Hello world!\";\n..."}

In the above example, we compiled the test-dom.ts file that references the DOM. In the lib option of Deno.compile(), the default lib value of Deno is overwritten, so esnext needs to be added as well. In addition, if you want to use the Deno namespace, you can also choose to add deno.ns.

This is still a bit experimental, but I hope that the bundle command can be developed to achieve a function similar to tree shaking, similar to Rollup.js.

8.2 Debug

Dene has built-in debugging capabilities, but at the time of this writing, the Visual Studio Code extension does not support it. To debug, you need to perform the following operations manually.

  • deno run -A --inspect-brk fileToDebug.ts (note: use the lowest permission for the module)
  • Open chrome://inspect in Chrome or Chromium and you will see a screen similar to the one below
  • Click "inspect" to connect and start debugging the code.

8.3 File monitoring

Deno has a built-in file monitoring function based on Rust notify (https://github.com/notify-rs/notify), which is used through Deno.watchFs(). Deno likes to expose powerful APIs in the background, allowing users to implement their own code according to their preferences. So there is no --watch flag, but you need to create your own implementation or use a third-party module.

When writing your own file monitor, the only difficulty is to eliminate jitter. This API may trigger many events continuously, and we may not want to perform an operation multiple times. Github user Caesar2011 used Date.now() to solve this problem with 23 lines of TypeScript code (https://github.com/Caesar2011/rhinoder/blob/master/mod.ts).

There is also a more advanced Deno file monitoring tool called Denon (https://deno.land/x/denon/), which is equivalent to nodemon. If you want to monitor changes in the workspace and re-run the test, just execute the following command:

denon test

9. Visual Studio Code Plugin

The plug-in released by axetroy in Visual Studio Market Place (https://marketplace.visualstudio.com/items?itemName=axetroy.vscode-deno) is currently the best extension. After installation, create a .vscode/settings.json file in the project directory, and then you can start this extension independently in each project.

//.vscode/settings.json{ "deno.enable": true,}

Then you can use all coding assistance functions including IntelliSense.

10. Summary

The rapid development of JavaScript ecology has its own advantages and disadvantages. On the positive side, there have never been so many high-quality tools. On the negative side, the endless intensive appearance of various frameworks and libraries can easily make developers complain and even doubt life.

Deno has successfully avoided many shortcomings of JavaScript development. Here are just a few.

  • By using web standards, Deno makes its API more future-oriented. At the same time, this also gives developers a lot of confidence and no longer has to waste time learning things that are quickly obsolete.
  • Use TypeScript to enhance JavaScript while removing the burden of compiling, achieving tighter integration.
  • Built-in tools mean common functions are available out of the box, so you no longer waste time searching.
  • Decentralized package management frees users from npm, and the ECMAScript module system is also eye-catching compared to the old CommonJS.

Although it can't completely replace Node.js, Deno has become an excellent programming environment that can be used daily.

Reference: https://cloud.tencent.com/developer/article/1633490 Deno 1.0, let’s learn about it-Cloud + Community-Tencent Cloud