If you’ve been following the Web development world, you’ve probably been hearing a lot about Deno lately — a new JavaScript runtime that might also be considered a successor to Node.js. But what does that mean, do we need “the next Node.js”?

What is Deno?

Deno is a JavaScript/TypeScript runtime that uses a secure environment to execute code by default, making it a great development experience.

Deno is built on V8, Rust and Tokio.

Function highlights

  • Secure by default. External codes have no access to the file system, network, or environment unless explicitly enabled.

  • An environment that supports TypeScript out of the box.

  • Only one separate executable (denO) is distributed.

  • There are built-in toolkits, such as a dependency message viewer (deno Info) and a code formatting tool (deno FMT).

  • There is a set of audited standard modules that are guaranteed to work on Deno.

  • The script code can be packaged as a separate JavaScript file.

Deno VS Node

  • Instead of using NPM, Deno references modules using urls or file paths.

  • Deno does not use package.json in its module parsing algorithm.

  • All asynchronous operations in Deno return promises, so Deno provides a different API than Node.

  • Deno requires explicit file, network, and environment permissions.

  • Deno always exits unexpectedly when an uncaught error occurs.

  • Using the ES module, require() is not supported. The third-party module is imported through the URL.

    import * as log from "https://deno.land/std/log/mod.ts";
    Copy the code
Node Deno
API reference mode Module import Global object
Module system CommonJS & New Experimental ES Module for Node ES Module browser implementation
security No safety restrictions The default security
Typescript Third-party, such as ts-Node Native support
Package management npm + node_modules Native support
Asynchronous operations The callback Promise
Package distribution Centralized npmjs.com Decentralize import URLS
The entrance Package. The json configuration Import URL Imports directly
Package, test, format Third parties such as ESLint, Gulp, Webpack, Babel, etc Native support

Install Deno

Deno runs on macOS, Linux and Windows. Deno is a separate executable file that has no additional dependencies.

The official installation

Deno. land/#installati…

Multi-version management installation

I’m going to focus on the DVM, but if you know Node, you know that Node has a version control called NVM, and Deno has a version control called DVM.

With Shell:

curl -fsSL https://deno.land/x/dvm/install.sh | sh
Copy the code

With PowerShell:

iwr https://deno.land/x/dvm/install.ps1 -useb | iex
Copy the code

DVM using:

$ dvm --helpDVM 1.1.10 Deno Version Manager - Easy way to manage multiple active Deno versions. USAGE: DVM [SUBCOMMAND] OPTIONS: -h, --help
            Prints help information

    -V, --version
            Prints version information


SUBCOMMANDS:
    completions    Generate shell completions
    help           Prints this message or the help of the given subcommand(s)
    info           Show dvm info
    install        Install deno executable to given version [aliases: i]
    list           List installed versions, matching a given <version> if provided [aliases: ls]
    use            Use a given version

Example:
  dvm install 1.3.2     Install v1.3.2 release
  dvm install           Install the latest available version
  dvm use 1.0.0         Use v1.0.0 release
Copy the code

Deno early experience

Some of you have already installed Deno, so let’s try the Deno app. Start by opening a command line you are familiar with, and then type the following command on the command line:

 $ deno run https://deno.land/std/examples/welcome.ts
 
Download https://deno.land/std/examples/welcome.ts
Warning Implicitly using latest version (0.68.0) for https://deno.land/std/examples/welcome.ts
Download https://deno.land/[email protected]/examples/welcome.ts
Check https://deno.land/[email protected]/examples/welcome.ts
Welcome to Deno 🦕
Copy the code

By observing the above output, we can know when running deno run https://deno.land/std/examples/welcome.ts after the command, Deno will be downloaded from https://deno.land/std/examples/welcome.ts URL welcome. The ts file, the file content is:

The console. The log (" Welcome to Deno 🦕);Copy the code

After the file is successfully downloaded, Deno compiles the welcome.ts file, that is, the welcome.ts.js file. Note that if you rerun the above command from the command line, the generated file in the cache will be executed and the welcome.ts file will not be downloaded from the web again.

$deno run https://deno.land/std/examples/welcome.ts Welcome to deno 🦕Copy the code

How do you prove that when you run the above command again, Deno will preferentially execute the compiled JavaScript files in the cache? The deno info command is used to display information about cache or source files:

$ deno info
DENO_DIR location: "/Users/sunilwang/.deno"
Remote modules cache: "/Users/sunilwang/.deno/deps"
TypeScript compiler cache: "/Users/sunilwang/.deno/gen"
Copy the code
$ tree $HOME/. Deno/Users/sunilwang /. Deno ├ ─ ─ deps │ └ ─ ─ HTTPS │ └ ─ ─ deno. Land │ ├ ─ ─ 1 a52c1fa5e4c9dc57f6866469b3f52feb606c441668dab162bf6424a87e87678 │ └ ─ ─ 1 a52c1fa5e4c9dc57f6866469b3f52feb606c441668dab162bf6424a87e87678. Metadata. Json └ ─ ─ gen └ ─ ─ HTTPS └ ─ ─ deno. Land ├ ─ ─ 1 a52c1fa5e4c9dc57f6866469b3f52feb606c441668dab162bf6424a87e87678. Buildinfo ├ ─ ─ 1 a52c1fa5e4c9dc57f6866469b3f52feb606c441668dab162bf6424a87e87678. Js └ ─ ─ 1a52c1fa5e4c9dc57f6866469b3f52feb606c441668dab162bf6424a87e87678.metaCopy the code

In the output above, we see the TypeScript compiler cache line, which is clearly the directory that the TypeScript compiler caches. After entering the directory, we search through the layers. Found 1 a52c1fa5e4c9dc57f6866469b3f52feb606c441668dab162bf6424a87e87678. Js compiled the cache file.

When we open the file in the directory, we can see the following:

"use strict";
console.log("Welcome to Deno 🦕");
//# sourceMappingURL=data:application/json; base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiaHR0cHM6Ly9kZW5vLmxhbmQvc3RkQDAuNjguMC9leGFtc Gxlcy93ZWxjb21lLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLENBQUMsR0FBRyxDQUFDLG9CQUFvQixDQUFDLENBQUMifQ==%
Copy the code

Now, how do you force a cache refresh, or recompile TypeScript code? When running the deno run command, we need to add the –reload flag to tell deno that the specified file needs to be refreshed:

 $ deno run --reload https://deno.land/std/examples/welcome.ts
 
Download https://deno.land/std/examples/welcome.ts
Warning Implicitly using latest version (0.68. 0) for https://deno.land/std/examples/welcome.ts
Download https:/ / deno. Land/[email protected] / examples/welcome. The ts
Check https:/ / deno. Land/[email protected] / examples/welcome. The ts
Welcome to Deno 🦕
Copy the code

In addition to the –reload flag, the Deno run command supports many other flags, and interested readers can run the Deno run –help command to see more information.

The module specification

Deno fully follows the ES Module browser implementation, so Deno is the same:

/ / support
import * as fs from "https://deno.land/std/fs/mod.ts";
import { deepCopy } from "./deepCopy.js";
import foo from "/foo.ts";

/ / does not support
import foo from "foo.ts";
import bar from "./bar"; // The extension must be specified
Copy the code

One of the biggest differences we found with the ES Module in WebPack or TS is:

  • You can reference online resources directly with import URLS;

  • The extension and file name of the resource cannot be omitted.

permissions

By default, Deno is secure. So the Deno module has no access to files, networks, or environments unless you authorize it. You must authorize the denO process in the command line to access security-sensitive functions.

In the following example, mod.ts is granted only read-only permission to the file system. It cannot write to it or perform any other security-sensitive operations.

$ deno run --allow-read mod.ts
Copy the code

Permissions list

The following permissions are available:

  • -a, –allow-all Allows all permissions, which disables all security restrictions.

  • –allow-env allows environment access, such as reading and setting environment variables.

  • — Allow-hrtime allows high precision time measurement, which can be used in timing attacks and feature recognition.

  • –allow-net= Allow network access. You can specify a series of comma-separated domain names to provide a whitelist of domain names.

  • –allow-plugin allows plug-in loading. Please note: this is an unstable feature.

  • –allow-read= Allow to read the file system. You can specify a series of comma-separated directories or files to provide a file system whitelist.

  • –allow-run Allows the child process to run. Please note that child processes do not run in a sandbox and therefore do not have the same security restrictions as denO processes, so use with caution.

  • –allow-write= Allows writing to the file system. You can specify a series of comma-separated directories or files to provide a file system whitelist.

Permission whitelist

Deno also allows you to use whitelists to control the granularity of permissions.

This is an example of whitelisting file system access to allow access only to the /usr directory, but it will fail when trying to access the /etc directory.

$ deno run --allow-read=/usr https://deno.land/std/examples/cat.ts /etc/passwd

error: Uncaught PermissionDenied: read access to "/etc/passwd". run again with the --allow-read flag at unwrapResponse (rt/10_dispatch_json.js:24:13) at sendAsync (rt/10_dispatch_json.js:75:12) at async Object.open (rt/30_files.js:45:17) at async https://deno.land/[email protected]/examples/cat.ts:4:16Copy the code

Change to the /etc directory, give the correct permissions, and try again:

$ deno run --allow-read=/etc https://deno.land/std/examples/cat.ts /etc/passwd
Copy the code

–allow-write, too, represents write permission.

Network access

// fetch.ts
const result = await fetch("https://deno.land/");
Copy the code

Here is an example of setting a host or URL whitelist:

$ deno run --allow-net=github.com,deno.land fetch.ts
Copy the code

The process will fail if fetch. Ts attempts to establish a network connection with another domain.

Allow access to any address:

$ deno run --allow-net fetch.ts
Copy the code

TCP

Now that we’ve shown you how to run the official Welcome example, let’s show you how to create a simple TCP Echo server using Deno.

/ / official sample code: https://deno.land/std/examples/echo_server.ts

const hostname = "0.0.0.0";
const port = 8080;
const listener = Deno.listen({ hostname, port });

console.log(`Listening on ${hostname}:${port}`);

for await (const conn of listener) {
  Deno.copy(conn, conn);
}
Copy the code

Like me, many readers will run the following command directly from the command line:

$ deno run  https://deno.land/std/examples/echo_server.ts

error: Uncaught PermissionDenied: network access to "0.0.0.0:8080". run again with the --allow-net flag at unwrapResponse (rt/10_dispatch_json.js:24:13) at sendSync (rt/10_dispatch_json.js:51:12) at opListen (rt/30_net.js:33:12) at Object.listen (rt/30_net.js:204:17) at https://deno.land/[email protected]/examples/echo_server.ts:4:23Copy the code

From the error message, Deno tells us that we need to set the –allow-net flag to allow network access. Why is that? This is because Deno is a JavaScript/TypeScript runtime that uses a secure environment to execute code by default. Let’s add the –allow-net flag and run the echo_server.ts file again:

$deno run - allow -.net https://deno.land/std/examples/echo_server.ts Listening on 0.0.0.0:8080Copy the code

After the server runs successfully, we use the nc command to test the function of the server:

$ nc localhost 8080
hell semlinker
hell semlinker
Copy the code

HTTP

A good tip: during actual development, you can get the required version of the standard library from the deno.land/ STD address. In this example, we explicitly specify the version, but you can also specify no version, such as: deno.land/ STD/HTTP /se… .

In the above code, we import the serve function from the Deno standard library HTTP module, and then use this function to quickly create an HTTP server. The function is defined as follows:

// http_server.ts
import { serve } from "https://deno.land/std/http/server.ts";
const s = serve({ port: 8000 });

console.log("http://localhost:8000/");

for await (const req of s) {
  req.respond({ body: "Hello World\n" });
}
Copy the code

After creating the HTTP server, let’s start the server. Open the command line and enter the following command:

$ deno run --allow-net ./http_server.ts           

Download https://deno.land/std/http/server.ts
Warning Implicitly using latest version (0.68.0) forhttps://deno.land/std/http/server.ts Download Download at https://deno.land/[email protected]/http/server.ts https://deno.land/[email protected]/encoding/utf8.ts Download Download at https://deno.land/[email protected]/io/bufio.ts https://deno.land/[email protected]/_util/assert.ts Download Download at https://deno.land/[email protected]/async/mod.ts https://deno.land/[email protected]/http/_io.ts Download Download at https://deno.land/[email protected]/textproto/mod.ts https://deno.land/[email protected]/http/http_status.ts Download Download at https://deno.land/[email protected]/async/deferred.ts https://deno.land/[email protected]/async/delay.ts Download Download at https://deno.land/[email protected]/async/mux_async_iterator.ts https://deno.land/[email protected]/async/pool.ts Download https://deno.land/[email protected]/bytes/mod.ts Check file:///Users/sunilwang/github/deno_test/http_server.ts http://localhost:8000/Copy the code

Then open your browser, type http://localhost:8080/ in the address bar, and you will see the following in the current page:

Hello World
Copy the code

HTTP middleware framework Oak

Oak is a project inspired by Koa, a popular Node.js middleware framework that provides HTTP services. We will use Oak and Deno to build a Hello Word applet.

We need to create two files in our project library, serve.ts and routes.ts. One is for applications and the other is for routing services.

The contents of the serve.ts file are as follows: Take a look at how we introduced the Application module from Oak in the serve.ts file.

// serve.ts
import { Application, Context } from 'https://deno.land/x/oak/mod.ts'
import router from './router.ts'

const app = new Application()
const PORT = 8080

// Logger
app.use(async (ctx: Context, next: Function) = > {await next()
  const rt = ctx.response.headers.get('X-Response-Time')
  console.log(`${ctx.request.method} ${ctx.request.url} - ${rt}`)})// Timing
app.use(async (ctx: Context, next: Function) = > {const start = Date.now()
  await next()
  const ms = Date.now() - start
  ctx.response.headers.set('X-Response-Time'.`${ms}ms`)
})

app.use(router.routes())
app.use(router.allowedMethods())
/ / 404
app.use((ctx: Context) = > {
  ctx.response.status = 404;
  ctx.response.body = { msg: "Not Found" };
})
console.log(`Listening on port ${PORT}, http://localhost:${PORT}`)

await app.listen({ port: PORT })
Copy the code

Oak was clearly inspired by Koa, and the routing middleware was inspired by the KOA-Router library. Oak will be easy to pick up if you’ve used Koa before. Let’s look at the following routes.ts

// routes.ts
import { Router, RouterContext } from 'https://deno.land/x/oak/mod.ts'

const router = new Router()

router.get('/'.(context: RouterContext) = > {
  context.response.body = 'Hello World! '
})

router.get('/router'.(context: RouterContext) = > {
  context.response.body = 'Hello Router! '
})

router.get('/router/:id'.(context: RouterContext) = > {
  context.response.body = `Hello Router, Id:${context.params.id}! `
})

export default router
Copy the code

After creating the Oak service, let’s start the server. Open the command line and enter the following command:

 $ deno run --allow-net ./serve.ts
 
Check file:///Users/sunilwang/github/deno_test/serve.ts
Listening on port 8080, http://localhost:8080
Copy the code

Open your browser and type in the address bar

  • http://localhost:8080/
  • http://localhost:8080/router
  • http://localhost:8080/router/123
  • http://localhost:8080/404

You will then see the following in the current page:

GET http://localhost:8080/ - 3ms
GET http://localhost:8080/router - 1ms
GET http://localhost:8080/router/123 - 0ms
GET http://localhost:8080/404 - 0ms
Copy the code

Possible problems

In the development process, the problem of DNS resolving domain name error is often encountered. The js dependency package cannot be downloaded

Let’s complete the following steps:

  • Let’s find the problem first

  • Is the domain name accessible?

  • Resolve the IP address of the domain name (www.ipaddress.com/). Can ping through without using OpenSSL or Shadowsocks

  • Modifying the Hosts File

    • win: (C:\Windows\System32\drivers\etc)
    • mac (/etc/hosts)
  • Let’s run the application again

conclusion

Deno is an interesting little tool, but it is not the next generation of Node.js. It will only be valuable to learn if it is used in a large number of projects with high traffic.

Node.js will continue to thrive, just as JavaScript writers didn’t like JS because of some early design flaws, but due to the emergence of JavaScript to fill in the gaps in browser scripts and the prosperity of the ecosystem, JS is still popular today.

I look forward to new developments for Deno and the continued prosperity of Node.js.

Finally, send your own collection of Deno resources full spectrum: github.com/hylerrix/aw…

reference

  • Deno community: deno.js.cn
  • Deno Chinese website: denolang.cn
  • Deno Manual: denolang.cn/manual/intr…
  • www.cnblogs.com/coderhf/p/1…