Deno初體驗

Posted on Sat, Aug 15, 2020 科技趣聞 NodeJS/Deno

封面來自官方嘅Deno 1.0文章:Deno 1.0

前言

Node.JS嘅作者嘅新玩具 以Rust寫成嘅 Deno終於迎來1.0版本,亦意味着Deno開始進入Stable,開始可以有啲嘢可以玩下,可以係自己機安裝compiled executable bin。所以今日主要簡單試下Deno一啲嘅入門嘢。

特點

係 Deno1.0嘅官方文章 上面,有介紹Deno嘅部分特點,包括:

以單純Output Hello, world. 嘅程序而言,Deno 能以最高嘅1.3ms嘅延遲 每秒處理2萬5千個request。而Node.JS雖然可以處理3萬4千個requests,但延遲可以高達2 - 300 ms。

安裝

Deno本身係無dept嘅執行檔,可以使用官方嘅安裝script安裝:

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

之後係~/.bashrc or ~/.zshrc之類嘅地方加入:

export DENO_INSTALL="/home/user/.deno"
export PATH="$DENO_INSTALL/bin:$PATH"

而 .deno 嘅安裝路徑要視乎你執行時嘅當前user作更改,之後儲存好,離開並重開terminal,查看版本可以鍵入 :

deno --version
deno 1.0.0
v8 8.4.300
typescript 3.9.2

執行TypeScript

Deno本身可以直接係內部compile並執行TypeScript。但,Deno不止可以執行本地嘅ts文件,亦可以執行遠端嘅ts文件。

例如以官方爲例:

deno run https://deno.land/std/examples/welcome.ts

而該文件只有一句:

console.log("Welcome to Deno 🦕");

而執行結果係:

➜  ~    deno run https://deno.land/std/examples/welcome.ts
Download https://deno.land/std/examples/welcome.ts
Warning Implicitly using master branch https://deno.land/std/examples/welcome.ts
Compile https://deno.land/std/examples/welcome.ts
Welcome to Deno 🦕

Formatting

呢個比較簡單,Deno內置Formatting工具,可以一行command幫你整理好個ts file。

例如我哋輸入下內容:

console.log(0); console.log(1); console.log(2);

執行:

 deno fmt main.ts

會變成:

console.log(0);
console.log(1);
console.log(2);

Import and standard Modules

係Node.JS當中,packages很依賴npm嘅package manager,而係Deno當中,並沒有一個類似NPM嘅centralize嘅package manager,取而代之嘅係類似go-lang嘅import from URL嘅玩法。

而Deno亦提供咗一堆Standard Modules,可以參見: https://deno.land/std/

而我哋可以用當中生成uuid嘅uuid,我哋可以寫個ts,包括以下內容:``typescriptimport { v4 } from “https://deno.land/std/uuid/mod.ts“;console.info(v4.generate())


之後以Deno command執行:
``bash
deno run main.ts

輸出:``bash➜ DenoTest deno run main.tsCompile /Deno_Projects/DenoTest/main.tsDownload https://deno.land/std/uuid/mod.tsDownload https://deno.land/std/uuid/v1.tsDownload https://deno.land/std/uuid/v4.tsDownload https://deno.land/std/uuid/_common.ts8d8afa8d-b719-4227-806d-8b86bbb81455


如果想用舊版本可以係repo後面加上@ tagging返個version:
```typescript
import { v4 }from "https://deno.land/[email protected]/uuid/mod.ts";
console.info(v4.generate())

執行結果:

➜  DenoTest deno run main.ts
Compile file:///run/media/len/EvolDisk/Developments/Deno_Projects/DenoTest/main.ts
Download https://deno.land/[email protected]/uuid/mod.ts
Download https://deno.land/[email protected]/uuid/v4.ts
1257f8fe-d82d-4b3b-ae3e-a6fd766d4ff4

甚至乎可以從Pika.dev之類嘅CDNimport標準嘅ECMAScript Modules:

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

權限

Node.JS預設係全權限,除非系統本身阻止,否則Node.JS能access所有resources。但在Deno入面,區分爲四大範疇嘅權限,分別係執行環境嘅i/o、網絡、file system以及子進程嘅執行權限。

例如你可以係 /tmp 下面隨便寫個text file並確認內容:

➜  ~ echo hello,world. >> /tmp/test_file
➜  ~ cat /tmp/test_file
hello,world.

透過透過readFile()試圖讀取內容並印係log度:

console.log(await Deno.readFile('/tmp/test_file'));

但顯示以下錯誤:

➜  DenoTest deno run main.ts
error: Uncaught PermissionDenied: read access to "/Deno_Projects/DenoTest/input.txt", run again with the --allow-read flag
    at unwrapResponse ($deno$/ops/dispatch_json.ts:43:11)
    at Object.sendAsync ($deno$/ops/dispatch_json.ts:98:10)
    at async Object.open ($deno$/files.ts:37:15)
    at async Object.readFile ($deno$/read_file.ts:13:16)
    at async  /Deno_Projects/DenoTest/main.ts:6:29

加入權限允許並執行:

deno run --allow-read /tmp/test_file main.ts

輸出:

➜  DenoTest deno run --allow-read /tmp/test_file main.ts
hello,world.

而網絡亦同理,我copy咗個官方提供嘅sample:

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" });
}

執行:

➜  DenoTest deno run main.ts
Compile /Deno_Projects/DenoTest/main.ts
error: Uncaught PermissionDenied: network access to "0.0.0.0:8000", run again with the --allow-net flag
    at unwrapResponse ($deno$/ops/dispatch_json.ts:43:11)
    at Object.sendSync ($deno$/ops/dispatch_json.ts:72:10)
    at Object.listen ($deno$/ops/net.ts:51:10)
    at listen ($deno$/net.ts:152:22)
    at serve (https://deno.land/[email protected]/http/server.ts:261:20)
    at /Deno_Projects/DenoTest/main.ts:2:11
➜  DenoTest

呢個時候就要加入allow flag:

 deno run --allow-net="0.0.0.0:8000" main.ts

輸出:

➜  DenoTest deno run --allow-net="0.0.0.0:8000" main.ts
http://localhost:8000/

而前往 http://localhost:8000/ 就會見到輸出嘅句子。

Hello World

tsconfig

由於tsc隱藏係Deno當中,而Deno實際執行的是JS,所以其實當然可以係透過tsconfig.json 黎改變compile option。建立tsconfig.json:

tsc --init

之後可以修改您需要嘅內容,之後可以執行:

deno run -c tsconfig.json main.ts
➜  DenoTest
deno run -c tsconfig.json main.ts
Compile /Deno_Projects/DenoTest/main.ts
Unsupported compiler optionsin
”/Deno_Projects/DenoTest/tsconfig.json"
  The following options were ignored:
    target, module, forceConsistentCasingInFileNames
test output

結語

其實會睇到,Deno以TypeScript爲core,亦意味着Deno預設就可以有TypeScript各種現代嘅功能,之餘,亦緊貼EMCA標準,亦有比較緊嘅權限管理,明顯地能有效處理到Node.JS with JavaScript歷史遺留嘅各種我唔想list出來嘅問題。而當然,Deno嘅特色亦唔止咁少,有篇比較詳盡嘅介紹可以參考:Deno 1.0: What you need to know

參考

Deno Offcial WebSiteDeno SamplesDeno Standard ModulesDeno Manual