This article was originally published on the public account CoyPan as expected

Writing in the front

On May 13, 2020, Deno was finally released. Deno is a JavaScript and TypeScript runtime based on the V8 JavaScript engine and the Rust programming language. It was created by Ryan Dahl, the father of Node.js, with a focus on security and productivity.

Why Deno

Why make Deno when you already have Node.js? According to a talk Ryan Dahl gave in 2018, he made several “mistakes” when designing Node.js. These “mistakes” are:

  1. I didn’t insist on using Promise.

  2. Not enough security.

  3. The build system did not cut from GYP (Node-gyp) to GN.

  4. Continue to use GYP without providing a Foreign Function Interface (FFI) schema.

  5. Package. json (depends on NPM).

  6. You can require(‘module’) anywhere.

  7. Package. json provides the wrong module concept.

  8. Node_modules black holes.

  9. Require (‘module’) does not include the extension ‘.js’.

  10. Index.js is loaded by default.

So Ryan Dahl decided to develop a new JavaScript runtime. More than two years later, Deno was released. Official website address:

deno.land/

Deno early experience

Come and experience Deno.

The installation

Can be directly under macOS curl: curl – fsSL https://deno.land/x/install/install.sh | sh

For more installation methods, please go to the official website

Once the download is complete, add deno to the system environment variable. First of all,

> vi ~/.bash_profile
Copy the code

Next, add the following two lines:

export DENO_INSTALL="/Users/pankeyu/.deno"
export PATH="$DENO_INSTALL/bin:$PATH"
Copy the code

Finally, execute:

source ~/.bash_profile
Copy the code

Then, deno can be happily executed from the command line:

The command line

The deno command line is similar to node.

To execute the script, simply deno run ${script}. The script here can also be an online file.

To execute the code directly, deno eval “console.log(30933 + 404)”.

Deno supports the following commands:

bundle         Bundle module and dependencies into single file
cache          Cache the dependencies
completions    Generate shell completions
doc            Show documentation for a module
eval           Eval script
fmt            Format source files 
help           Prints this message or the help of the given subcommand(s)
info           Show info about cache or info related to source file
install        Install script as an executable
repl           Read Eval Print Loop
run            Run a program given a filename or url to the module
test           Run tests 
types          Print runtime TypeScript declarations
upgrade        Upgrade deno executable to given version
Copy the code

For more information, you can use deno Help.

Deno natively supports packaging, testing, and formatting, as shown in the bundle, test, and FMT commands above.

Create an HTTP server using deno

We use the official example:

// server.ts
import { serve } from "https://deno.land/[email protected]/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

Deno server.ts command line output:

As you can see, this is an error. This is deno security mechanism, need to add –allow-net parameter, can access the network.

Run the deno –allow-net server.ts command. The following output is displayed:

> deno --allow-net server.ts Compile file:///Users/pankeyu/Desktop/server.ts Download https://deno.land/[email protected]/http/server.ts Download Download at https://deno.land/[email protected]/encoding/utf8.ts https://deno.land/[email protected]/io/bufio.ts Download Download at https://deno.land/[email protected]/testing/asserts.ts https://deno.land/[email protected]/async/mod.ts Download Download at https://deno.land/[email protected]/http/_io.ts https://deno.land/[email protected]/io/util.ts Download Download at https://deno.land/[email protected]/path/mod.ts https://deno.land/[email protected]/path/win32.ts Download Download at https://deno.land/[email protected]/path/posix.ts https://deno.land/[email protected]/path/common.ts Download Download at https://deno.land/[email protected]/path/separator.ts https://deno.land/[email protected]/path/interface.ts Download Download at https://deno.land/[email protected]/path/glob.ts https://deno.land/[email protected]/path/_constants.ts Download Download at https://deno.land/[email protected]/path/_util.ts https://deno.land/[email protected]/fmt/colors.ts Download Download at https://deno.land/[email protected]/testing/diff.ts https://deno.land/[email protected]/path/_globrex.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]/textproto/mod.ts Download Download at https://deno.land/[email protected]/http/http_status.ts https://deno.land/[email protected]/bytes/mod.ts http://localhost:8000/Copy the code

Open your browser to http://localhost:8000/ and you’ll see Hello World output.

You may wonder why you add a –allow-net parameter. This is Deno’s security policy.

As you can see from the above example, when the script is started, deno downloads its dependencies locally in real time and executes the script logic after the download is complete. When we exit control+C and execute the script again, the command line outputs:

> deno --allow-net server.ts
http://localhost:8000/
Copy the code

There will be no dependency downloads this time.

Deno saves dependencies locally after the first download, and the dependency code itself is invisible to the user. This is completely different from node_modules for Node.js.

If we want to re-download the dependency, we need to execute the script with –reload: deno –allow-net –reload server.ts.

If we want to see the dependency tree of the script, we need to execute deno Info server.ts:

> deno info server.ts 
local: /Users/pankeyu/Desktop/server.ts
type: TypeScript compiled: /Users/pankeyu/Library/Caches/deno/gen/file/Users/pankeyu/Desktop/server.ts.js map: /Users/pankeyu/Library/Caches/deno/gen/file/Users/pankeyu/Desktop/server.ts.js.map deps: file:///Users/pankeyu/Desktop/server.ts └ ─ ┬ https://deno.land/[email protected]/http/server.ts ├ ─ ─ https://deno.land/[email protected]/encoding/utf8.ts ├ ─ ┬ https://deno.land/[email protected]/io/bufio.ts...Copy the code

The simple example above also illustrates the following points:

  1. Deno supports typescript natively. In fact, deno has a BUILT-IN TS engine that will parse TS code into JS code and hand it to V8 to run.
  2. Deno natively supports top-level-await.
  3. If the example script above is not added--allow-netThis flag will report an error. You can see deno’s security concerns.
HTTPS Server performance of deno

Deno is a suitable asynchronous server, 25K requests per second is sufficient for most purposes, and because of the widespread use of Promises, Deno needs better tail latency. The Deno HTTP server currently processes about 25, 000 requests per second with a maximum latency of 1.3 milliseconds, compared to 34, 000 requests per second with a maximum latency between 2 and 300 milliseconds for the Node program.

As such, the authors believe that Deno’s HTTP server has more performance advantages, and they hope to achieve this goal in future releases.

The HTTP Server performance of deno can be viewed here: deno.land/benchmarks

Dependencies and modules in denO

Node provides a number of built-in modules, such as:

const fs = require('fs');
const path = require('path'); .Copy the code

In deno, there are also a number of built-in modules, but they do not support Node in the same way, but hang on the deno global variable. Look at an example:

// denoFs.js
const readFile = Deno.readFile;
const serverBuffer = await readFile('./server.ts');
console.log(serverBuffer);
Copy the code

Execute the script:

> deno run --allow-read denoFs.js Uint8Array(213) [ 105, 109, 112, 111, 114, 116, 32, 123, 32, 115, 101, 114, 118, 101, 32, 125, 32, 102, 114, 111, 109, 32, 34, 104, 116, 116, 112, 115, 58, 47, 47, 100, 101, 110, 111, 46, 108, 97, 110, 100, 47, 115, 116, 100, 64, 48, 46, 53, 48, 46, 48, 47, 104, 116, 116, 112, 47, 115, 101, 114, 46, 116, 115, 34, 59, 10, 99, 111, 110, 115, 116, 32, 115, 32, 61, 32, 115, 101, 114, 118, 101, 40, 123, 32, 112, 111, 114, 116, 58, 32, 56, 48, 48, 48, 32, 125, 41, ... 113 more items ]Copy the code

The modularity of denO completely follows es Module. As you can see from the previous example, deno can import online resource bundles directly. For local resources, you can import them using the local path with the resource suffix (.ts,.js). Import is declaring dependencies.

// world.ts
export const world:string = 'world';

// hello.ts
import { world } from './world.ts';
console.log(`Hello ${world}`);
Copy the code

Deno run hello.ts

> deno run hello.ts
Compile file:///Users/pankeyu/Desktop/hello.ts
Hello world
Copy the code
Built-in tools for deno

As mentioned earlier, deno has native support for packaging, testing, formatting, and more. Let’s give it a try.

  • packaging

We use denofs.js above as an example.

> deno bundle denoFs.js denoFs.output.js
Bundling file:///Users/pankeyu/Desktop/deno/denoFs.js
Emitting bundle to "denoFs.output.js"
2482 bytes emmited.
Copy the code

The result is a denofs.output. js file that looks something like this, which can also be run directly by deno.

// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.

// This is a specialised implementation of a System module loader.

// @ts-nocheck
/* eslint-disable */
let System, __instantiateAsync, __instantiate;

(() = > {
  const r = new Map(a); System = { register(id, d, f) { r.set(id, { d, f,exp: {}}); }};async function dI(mid, src) {... }function gC(id, main) {... }function gE(exp) {... }function rF(main) {... }async function gExpA(id) {... }function gExp(id) {... } __instantiateAsync =async (m) => {
    ...
  };

  __instantiate = (m) = > {
    ...
  };
})();

"use strict";
const readFile = Deno.readFile;
const serverBuffer = await readFile("./server.ts");
console.log(serverBuffer);

__instantiate("denoFs");

Copy the code
  • test

We use world.ts above as an example.

// world.ts
export const world:string = 'world';
Copy the code

Deno starts from the current directory and reads the file named {*_,}test.{js,ts, JSX, TSX} as the test file. Let’s write the test case first:

// world.test.ts
import { world } from "./world.ts";
Deno.test("env", () = > {if(world ! = ='world') {
    throw Error("wrong!"); }});Copy the code

Run deno test:

Compile file:///Users/pankeyu/Desktop/deno/.deno.test.ts
running 1 tests
test env ... ok (4ms)

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out (4ms)
Copy the code
  • Formatting code

Suppose the code we want to format is:

// server.ts
import { serve } from "https://deno.land/[email protected]/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 executing deno FMT server.ts, the code is formatted:

// server.ts
import { serve } from "https://deno.land/[email protected]/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

conclusion

This exploration, combined with Ryan Dahl’s previous Nodejs “design error”, provides a bit of a summary of deno.

Deno has reimplemented the modularization mechanism, adopted a decentralized design, supported direct import of online resources, no longer dependent on NPM like Node, and got away from node_modules. Deno also provides a third party repository: deno.land/ STD /.

Deno’s built-in modules hang on global variables.

Deno has a built-in typescript parsing engine that supports typescript natively. Also, deno is embracing the W3C specification (deno supports FETCH).

4. Deno is secure by default. As you can see from the examples above, specific parameters are required to access the network, file system, etc.

5, denO native support packaging, testing, code formatting and other operations, to improve productivity.

Deno is a reinvention of the previous Nodejs development model, and its design concept is definitely a step forward compared to Node.js. In contrast to the previous node.js “design errors” mentioned by the author, deno solved each one.

Deno’s impressive decentralized module dependency may enable further development of technologies such as front-end CDN and automated deployment of production environments. However, deno still has a long way to go before it can achieve the stability and thriving ecosystem of Node.js.

Write in the back

This article provides an incomplete introduction to denO with an example. Ryan Dahl abandoned his tuba practice and started a trumpet practice. So, this time, do you think Deno will catch on?