Deno快速上手指北

Deno 是 V8 上的安全 TypeScript 运行时。

  • 无 package.json (去中心化)、npm,不追求兼容 Node

  • 采用Rust编写(最初使用Go)

  • 支持 TypeScript 开箱即用,使用 V8 6.8.275.3 引擎

  • Modern JS, ES Modules ,标准库 ,发生未捕捉错误时自动终止运行

  • 支持 top-level 的 await

  • 旨在兼容浏览器API

  • 可以作为库来引入,以轻松构建自己的 JavaScript runtime

  • 通过 URL 方式引入依赖而非通过本地模块,并在第一次运行的时候进行加载和缓存

  • 可以控制文件系统和网络访问权限以运行沙盒代码,默认访问只读文件系统可访问,无网络权限。V8 和 Golang 之间的访问只能通过 protobuf 中定义的序列化消息完成;

  • 支持执行wasm二进制文件

安装

macOS 和 Linux 系统上使用 shell:

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

Windows 系统上使用 PowerShell:

1
wr https://deno.land/x/install/install.ps1 -useb | iex

国内用户推荐使用 denocn/deno_install 提供的安装器来安装。用法和官方一样。

macOS 和 Linux 系统上使用 shell:

1
curl -fsSL https://x.deno.js.cn/install.sh | sh\

Windows 系统上使用 PowerShell:

1
iwr https://x.deno.js.cn/install.ps1 -useb -outf install.ps1; .\install.ps1

Windows系统上iwr安装如果报错可以执行这个命令

1
2
Set-ExecutionPolicy RemoteSigned -scope CurrentUser
iwr https://x.deno.js.cn/install.ps1 -useb -outf install.ps1; .\install.ps1

测试:

1
2
3
4
PS C:\Users\demo> deno --version                                                                                       deno 1.1.1
deno 1.1.1
v8 8.5.104
typescript 3.9.2

参数

必须使用参数,显式打开权限才可以。

1
2
3
4
--allow-read:打开读权限,可以指定可读的目录,比如--allow-read=/temp。
--allow-write:打开写权限。
--allow-net=google.com:允许网络通信,可以指定可请求的域,比如--allow-net=google.com。
--allow-env:允许读取环境变量。

服务器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 引入url
import { Application } from "https://deno.land/x/oak/mod.ts";
import router from "./routes.ts";
const port = 5000;

// 初始化
const app = new Application();

app.use(router.routes());
app.use(router.allowedMethods());

console.log(`服务器正在${port}端口号运行...`);

// 监听端口
await app.listen({ port });
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import { Router } from "https://deno.land/x/oak/mod.ts";
import {
getProducts,
getProduct,
addProduct,
updateProduct,
deleteProduct,
} from "./controllers/products.ts";

const router = new Router();

router.get("/api/v1/products", getProducts)
.get("/api/v1/products/:id", getProduct)
.post("/api/v1/products", addProduct)
.put("/api/v1/products/:id", updateProduct)
.delete("/api/v1/products/:id", deleteProduct);

export default router;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import { Product } from "../types.ts";
import { v4 } from "https://deno.land/std/uuid/mod.ts";

let products: Product[] = [
{
id: "1",
name: "产品一",
description: "我是产品一",
price: 29.99,
},
{
id: "2",
name: "产品二",
description: "我是产品二",
price: 39.99,
},
{
id: "3",
name: "产品三",
description: "我是产品三",
price: 59.99,
},
];

// @desc 获取所有产品
// @route GET /api/v1/products
const getProducts = ({ response }: { response: any }) => {
response.body = {
success: true,
data: products,
};
};

// @desc 获取单个产品
// @route GET /api/v1/products/:id
const getProduct = (
{ params, response }: { params: { id: string }; response: any },
) => {
const product: Product | undefined = products.find((p) => p.id === params.id);

if (product) {
response.status = 200;
response.body = {
success: true,
data: product,
};
} else {
response.status = 404;
response.body = {
success: false,
msg: "抱歉,没有这个产品",
};
}
};

// @desc 添加单个产品
// @route POST /api/v1/products
const addProduct = async (
{ request, response }: { request: any; response: any },
) => {
const body = await request.body();

if (!request.hasBody) {
response.status = 400;
response.body = {
success: false,
msg: "没有数据",
};
} else {
const product: Product = body.value;
product.id = v4.generate();
response.status = 201;
response.body = {
success: true,
data: product,
};
}
};

// @desc 更新单个产品
// @route PUT /api/v1/products/:id
const updateProduct = async (
{ params, request, response }: {
params: { id: string };
request: any;
response: any;
},
) => {
const product: Product | undefined = products.find((p) => p.id === params.id);

if (product) {
const body = await request.body();
const updateData: { name?: string; description?: string; price?: number } =
body.value;

products = products.map((p) =>
p.id === params.id ? { ...p, ...updateData } : p
);

response.status = 200;
response.body = {
success: true,
data: products,
};
} else {
response.status = 404;
response.body = {
success: false,
msg: "抱歉,没有这个产品",
};
}
};

// @desc 删除单个产品
// @route DELETE /api/v1/products/:id
const deleteProduct = (
{ params, response }: { params: { id: string }; response: any },
) => {
products = products.filter((p) => p.id !== params.id);
response.body = {
success: true,
msg: "产品已经删除",
};
};

export { getProducts, getProduct, addProduct, updateProduct, deleteProduct };

启动Server

1
2
PS C:\Users\demo\Desktop\ms-deno-rest-api-lesson-1> deno  run --allow-net server.ts
服务器正在5000端口号运行...