你们好,小弟飞狐。很久没来思否了,再来带来了的必定是干货。从Deno开始,飞狐带来的绝对到目前为止史无前例的Deno系列。话很少说,用技术说话。javascript
还记得 Github 上那个让人学不动的 Deno 么?就在2020年5月13日,Deno1.0正式发布。做为新晋网红运行时,Deno真的会替代 Node 吗?这个问题能够追溯到2018年,从Node之父 Ryan Dahl的演讲提及,Ryan在演讲中谈及对Node有十大不满之处,而且在演讲的最后公布了Deno项目。我在这里只列三大新特性。java
综上所述,你会发现,Deno真的是青出于蓝而胜于蓝。是否替代,只是时间问题而已。我也看到不少人在作deno和node的性能比较,但在目前我认为作这二者的性能比较彻底没有必要。node
咱们一开始甭管deno底层用的go仍是rust,为啥要从go换成rust、或者是deno的技术架构是咋样?这些目前都不要关心,咱们就把deno当成一个新的运行时,只作运行时。从零到一,经过搭建一套脚手架,再慢慢去深刻。Deno能够在Mac、Linux、Windows三大系统上运行。Deno也不须要其余依赖。经过以下方式安装:golang
curl -fsSL https://deno.land/x/install/install.sh | sh
iwr https://deno.land/x/install/install.ps1 -useb | iex
brew install deno
choco install deno
scoop install deno
第一个例子也是来自官方,每一行我都加了解释。以下:spring
// 建立文件 /server.ts // 不须要像node同样去npm,这里直接引入 import { serve } from "https://deno.land/std@0.63.0/http/server.ts"; // 构建服务,设置端口 const s = serve({ port: 8000 }); // 这里是直接返回 for await (const req of s) { req.respond({ body: "Hello World\\n" }); }
整个代码很是简单,语法也是ts,和node很是像。有node基础的同窗直接入手。typescript
运行命令:deno run --allow-net ./server.ts
,npm
而后在浏览器打开http://localhost:8000,就能够看到hello world了,以下图:浏览器
众所周知,node的框架比较成熟,国外的有nest.js、国内的有egg.js。而目前deno的生态其实并不成熟,框架也都是模仿其余框架,多的就不介绍了,这里我给你们推荐两个框架。以下:安全
推荐oak的缘由很简单,就是咱们整个脚手架搭建都是基于oak的。oak模仿的是node的框架koa,从名字也能够看出来。 而推荐alosaur的缘由就一点,可学性很强。有兴趣能够去看这个框架的源码,很是多值得借鉴的地方。飞狐教你们搭建脚手架,虽然不用这个框架,但不少底层实现也是借鉴的这个框架,好比注解路由。好啦,框架就介绍到这里啦,后面咱们再慢慢深刻。架构
话很少说,咱们先来个oak例子:
// 引入oak框架 import { Application } from "https://deno.land/x/oak/mod.ts"; // 初始化 const app = new Application(); // 跟koa同样,运行上下文 app.use((ctx) => { ctx.response.body = "Hello World!"; }); // 监听端口 await app.listen({ port: 8000 });
在运行的时候,可能会报错,以下:
是否是有点受挫。其实大可没必要,这个问题是deno版本迭代时std版本未更新至最新引发的。
注意,deno是新玩意儿,有很多坑,官方也在频繁迭代解决这些坑。 因此,理解万岁。最简单的解决办法只须要把oak的版本升级成最新就行了,以下面的例子。
路由部分oak跟koa不同的是,oak直接提供路由,只需引入便可。以下:
// 升级到oak的最新版本 import { Application, Router } from "https://deno.land/x/oak@v6.0.1/mod.ts"; // 这是官方的例子 const books = new Map<string, any>(); books.set("1", { id: "1", title: "听飞狐聊deno", author: "飞狐", }); // 建立路由 const router = new Router(); // 路由,和koa-router的用法同样 router .get("/", (context) => { context.response.body = "Hello world!"; }) .get("/book", (context) => { context.response.body = Array.from(books.values()); }) .get("/book/:id", (context) => { if (context.params && context.params.id && books.has(context.params.id)) { context.response.body = books.get(context.params.id); } }); const app = new Application(); // 应用路由 app.use(router.routes()); // 容许路中间件引入 app.use(router.allowedMethods()); await app.listen({ port: 8000 });
切记,必定要用最新的版本。一样的,输入命令运行。以下图(postman测试接口):
MVC模式你们都不陌生了,咱们这里仅仅作个简单的拆分,把路由和控制层独立出去。 建立一个controller文件夹,在该文件夹下建立一个bookController文件,以下:
// 建立bookController.ts, // 咱们把数据先移到这来再说 const books = new Map<string, any>(); books.set("1", { id: "1", title: "听飞狐聊deno", author: "飞狐", }); // 这里直接返回一个对象,把路由映射的方法也搬到这里 export default { getbook: ((context: any) => { context.response.body = Array.from(books.values()); }), getbookById: ((context: any) => { if (context.params && context.params.id && books.has(context.params.id)) { context.response.body = books.get(context.params.id); } }) }
再在根目录下建立router.ts,代码以下:
import { Router } from 'https://deno.land/x/oak@v6.0.1/mod.ts'; // 引入控制层的文件 import bookController from './controller/bookController.ts' const router = new Router(); router .get("/", (context) => { context.response.body = "Hello world!"; }) .get("/book", bookController.getbook) .get("/book/:id", bookController.getbookById) export default router
原来的入口文件server.ts,就变得十分简洁了,以下:
import { Application } from 'https://deno.land/x/oak@v6.0.1/mod.ts'; import router from './router.ts' const app = new Application(); app.use(router.routes()); app.use(router.allowedMethods()); await app.listen({ port: 8000 });
这样就很简洁了,也利于扩展。好比:
在这个基础上,在后面的篇章里咱们再继续深刻。今天的内容其实已经完成了。这里再介绍一下,为啥说这个系列是架构级思想呢?由于咱们在写代码的时候,就会基于一些特定的场景考虑,好比微服务等。就像golang里的go-micro,会集成grpc、etcd、gin等等同样。有兴趣我也能够写一套golang系列分享给你们,小弟我有太多想和你们伙儿分享的东东了,好比,TensorFlow.js、Julia量化交易等。呃~好像跑偏了,仍是拉回来先送你们一个结尾彩蛋,为下一篇打基础。
从如今起,后面的部分咱们要用类class的方式来写代码了,先从入口文件开始,改造以下:
// server.ts import { Application } from 'https://deno.land/x/oak@v6.0.1/mod.ts'; import router from './router.ts' const app = new Application(); class Server { constructor () { this.init() } async init () { app.use(router.routes()); app.use(router.allowedMethods()); this.listen() } async listen () { await app.listen({ port: 8000 }); } } new Server()
这里我不用注释了,单独讲解一下这个地方,主要三点:
回顾一下,这篇内容很浅显,主要是安装deno,简单实用oak框架,拆分路由而已。 下回咱们直接聊typescript装饰器模式,注解,而且实现注解路由。控制层也按照类class的写法,就跟Java的springmvc同样,以下图:
从上图能够看到,这样根本就不须要router文件啦。不论是node、deno仍是golang,飞狐真的很不喜欢一个单独的router文件去维护路由,太麻烦。因此每次搭架子的时候,我必定是先把路由给搞定了,省得麻烦。如今理解为啥下回直接开干注解路由了吧,deno的注解路由仍是很一波三折的,由于彻底照搬node会有些坑。期待吧,嘿嘿😜~