初探 Deno

Hello World

每个语言第一次使用自然是 Hello World 来测试环境是否配置完成

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

使用 deno run main.ts 即可执行该脚本(存放在main.ts中)

这里有一点需要注意:
如果文件后缀名是js,程序会直接执行;而如果后缀名是ts,则会首先将其编译成js
体现在执行过程中,会多一行

Compile file:///home/ohyee/projects/temp/main.ts

在这里,ts将会被编译成js

访问和权限

如果我们要访问一个页面的内容,应该使用类似下面的代码

console.log("Welcome to Deno 🦕");
const res = await fetch("https://www.oyohyee.com");
console.log(await res.text())
const res2 = await fetch("https://github.com");
console.log(await res2.text())

但是在执行时,会提示这样的错误

Welcome to Deno 🦕
error: Uncaught PermissionDenied: network access to "https://www.oyohyee.com/", run again with the --allow-net flag
    at unwrapResponse ($deno$/ops/dispatch_json.ts:43:11)
    at Object.sendAsync ($deno$/ops/dispatch_json.ts:98:10)
    at async fetch ($deno$/web/fetch.ts:591:27)
    at async file:///home/ohyee/projects/temp/main.ts:8:13

在 Deno 中,为了确保安全,执行一些敏感内容必须由执行者给予相应的权限

涉及的权限如下:

名称 权限参数 解释
all --allow-all 允许所有权限
run --allow-run 允许运行子进程
read --allow-read 允许读入文件
write --allow-write 允许写出文件
net --allow-net 允许访问网络
env --allow-env 允许读写环境变量
plugin --allow-plugin 允许加载插件
hrtime --allow-hrtime 允许高精度时间

lib.deno.ns.d.ts#1687-1694

  export type PermissionName =
    | "run"
    | "read"
    | "write"
    | "net"
    | "env"
    | "plugin"
    | "hrtime";

同时,也可以限定只对部分内容开放权限

如上面的内容,应该使用下面的代码执行

deno run --allow-net=www.oyohyee.com deno.ts

这样,第一条请求可以成功执行,但是第二条请求则会报错

在这一部分,需要注意的是:

  • 允许参数应该放在run后面,要执行的文件前面
  • 允许特殊域名的网络权限时,必须要求 host 完全相同(如要访问www.oyohyee.com,必须允许www.oyohyee.com而非oyohyee.com

引入

由于 Deno 中同时可以直接运行tsjs,因此如果要引入文件,必须要明确说明到底是引入的什么文件
因此与 NodeJS 引入的语法不同,Deno 中必须注明后缀名

import { sum } from './sum.ts'
console.log(sum(1,2))

对于js文件,则可以使用d.ts文件来声明文件,下面分别是在引入时指定和导出时指定的两种语法

// @deno-types="./foo.d.ts"
import * as foo from "./foo.js";

/// <reference types="./foo.d.ts" />
export const foo = "foo";

在 Deno 中,也可以直接运行 WebAssembly

const wasmCode = new Uint8Array([
  0, 97, 115, 109, 1, 0, 0, 0, 1, 133, 128, 128, 128, 0, 1, 96, 0, 1, 127,
  3, 130, 128, 128, 128, 0, 1, 0, 4, 132, 128, 128, 128, 0, 1, 112, 0, 0,
  5, 131, 128, 128, 128, 0, 1, 0, 1, 6, 129, 128, 128, 128, 0, 0, 7, 145,
  128, 128, 128, 0, 2, 6, 109, 101, 109, 111, 114, 121, 2, 0, 4, 109, 97,
  105, 110, 0, 0, 10, 138, 128, 128, 128, 0, 1, 132, 128, 128, 128, 0, 0,
  65, 42, 11
]);
const wasmModule = new WebAssembly.Module(wasmCode);
const wasmInstance = new WebAssembly.Instance(wasmModule);
console.log(wasmInstance.exports.main().toString());

打包

Deno 的程序是可以被打包成单个 js 文件的
使用下面的命令即可

deno bundle main.ts

原则上来说,如果不使用 Deno 作用域下的函数,并且浏览器符合新版本的规范,Deno 文件应该是可以直接在浏览器运行的