deno+mongo实战踩坑记
自从 deno 1.0 发布以来,有关 deno 的文章很多,大多数都是在讨论怎么安装 deno 、deno 有哪些特点 、deno 和 node 有哪些异同、deno是不是 node 的替代品等。咱们今天不讨论这些,毕竟 Talk is cheap. Show me the code! 亲自体验一把 deno 开发带来的快感、用 deno 搞一个“企业级”应用:deno-supermarket,难道不香吗?
deno 常见的一些坑
在实战之前,还是先来介绍几个我在刚接触 deno 时遇到的小坑。
权限标志符位置的问题
我们都知道, deno 默认是安全的,就是导致了默认情况下是不允许访问网络、读写文件等。比如有个名为 index.ts 的文件内容如下:
import { serve } from "https://deno.land/std@0.50.0/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" });
}
如果直接执行 deno run index.ts
, 会报错:
error: Uncaught PermissionDenied: network access to "0.0.0.0:8000", run again with the --allow-net flag
所以我们很自然的就会在启动命令的最后加上 --allow-net
,如下:
deno run index.ts --allow-net
但是,这样仍然会报错。查了资料才知道 ,--allow-net
、--allow-read
之类的标志是不可以放到文件名后面的,必须紧跟在 deno run
后面,比如,如下才是正确的:
deno run --alow-net index.ts
为什么调换了位置就不行呢? issue 上的回答是,如果 --allow-net
跟在文件名后面,是传给 js 脚本的,而不是传给 deno 的。想了解更多的,可以看这个 confused by order of cli option flags。反正,记住一点就行:权限标志一定要跟在 deno run
后面!
因为我们前端同学大多数平时很少写后台,不太清楚安全的重要性,为了避免遇到各种权限问题,我建议平时在写一些练手项目时,直接用 deno run -A
来启用全部的权限。(这只是方便调试,在生产环境中一定要慎用!)
不稳定的 API
因为实战过程中使用了 mongodb , 所以需要引入 Deno 的第三方模块 mongo,然而在启动项目会报错:
error: TS2339 [ERROR]: Property 'openPlugin' does not exist on type 'typeof Deno'.
查了一下,发现是因为 openPlugin
这个方法目前还不稳定。默认情况下,deno 只会提供稳定的 api。如果需要开启不稳定 api,可以添加 --stable
标志。比如:
deno run -A --unstable index.ts
可能有人会问,-A
和 --unstable
的位置调换会不会有问题。这个亲测过不会有问题。只要标志符在文件名称之前就行了。
还有个问题,到底哪些是稳定 API,哪些是不稳定 API 呢?其实 deno 官方文档已经帮我们分好类的了,入口地址分别是:
如果你怀疑 --unstable
的作用,可以使用下面的方法打印出 Deno
上的所有成员:
console.log(Object.keys(Deno).length)
使用 deno run --unstable index.ts
输出的结果是 117,使用 deno run index.ts
输出的结果是 88 。说明稳定的 api 有 88 个,不稳定的有 29 个。
deno 的一些使用技巧
从 node 切换到 deno, 我们的开发思维也要随之转变。所以,我们再来看看 deno 的一些和 node 不一样的开发技巧。
如何管理版本?
刚开始我也很疑惑:没有了 package.json
, 那怎么控制各依赖的版本呀?比如,我们有10个文件都依赖了 mongo@v0.0.6
, 那每个文件都使用以下代码进行引入:
import { init, MongoClient } from 'https://deno.land/x/mongo@v0.6.0/mod.ts'
可是有一天,我突然想把 0.6.0 升级到 0.7.0, 那怎么办呢?一个个文件的进行替换容易漏掉,当然也可以全局搜索批量替换 。但是这种效率都不是很高。
官方给出的推荐做法是,使用 deps.ts
文件来引入远程文件,并管理版本。(当然 ,文件名称不一定叫做 deps.ts
, 你也可以改成其他的名称)。具体做法就是,把所有用到的远程依赖,都在 deps.ts
中引入 ,并且通过 Re-export
手段导出各依赖,然后其他文件就可以从 deps.ts
中拿到所需要的依赖了。
回到刚才说10个文件都依赖到 mongo
的问题,如果改成 deps.ts
文件来统一管理是这样的:
export * from 'https://deno.land/x/mongo@v0.6.0/mod.ts'
然后那些需要用到 mongo 的文件,不要直接从远程引入,而是从 deps.ts
中引入,如下:
import { init, MongoClient } from '../pathTo/deps.ts';
如果需要升级的话,我们可以直接把 deps.ts
里面的 mongo 地址中的 0.6.0
改成 0.7.0
就行了。
另外,有一点和 npm 类似的是,如果没有指定版本号,即远程地址中没有指定版本,比如:
export * from 'https://deno.land/x/mongo/mod.ts'
就会默认安装最新版的依赖。
如何查找一些对我有用的 deno 库?
使用 node ,可以到 npm 上查找一些库。deno 也有类似的平台,目前分为两种库,一种是官方标准的,另外一种是第三方的。标准库可以到这里查找:Deno Standard Modules。第三方库可以到这里查找: Deno Third Party Modules
实战: 使用 deno 开发一个具备增删查改的商城系统
OK, 具备以上的知识点,现在可以实战了。首先,需要保证你的电脑安装了 deno 1.0 。另外,由于用到了 mongodb ,所以需要你的电脑也要安装 mongodb。
界面
先来看看我们的商城的界面:
麻雀虽小五脏俱全哈!具备添加商品、查询商品、删除商品、修改商品的功能。这是典型的 REST API 风格的系统 。
项目结构
然后再来看看项目结构:
- .deno_plugins: 这是 mongo 模块所下载的动态链接库,不用关注它。
- congig/db.ts: 这是连接 mongodb 的相关配置文件。目前写死的端口号是 27017 , 如果你的 mongodb 端口不是这个,可以在这个文件里面修改。
- controllers/goods.ts: 这是实现增删查改的逻辑代码
- public/index.html: 这是前端静态页面,跟 deno 无关的,我们只需要用 deno 来服务该目录就行。
- deps.ts: 用来管理远程依赖库,然后 Re-export 出去给其他文件使用。
- server.ts 入口文件,跟我们用 epress 或 koa 时的入口 文件 app.js 类似。
依赖模块的选择
因为该项目涉及到了前后端,如果使用 node 的话,一般会选择 express 或 koa。同样的,我们使用 deno 也要选择对应的框架 ,不然的话,http服务以及路由跳转等都不是那么容易处理的。deno 上的这类框架,比较多人 star 的是 oak 和 abc,这里我们选择使用 abc。
另外,因为使用 mongodb , 所以还需要引入 mongo
结束语
好啦,对于 deno 初体验就写到这啦, 具体的代码这里不打算贴出来了,有兴趣的可以前往 github 查看:
有问题的可以一起交流学习哈~
deno+mongo实战踩坑记的更多相关文章
- mongo java 踩坑记
为什么会有这么多坑 1. Java会把 id:String = "合法ObjectId" 好心好意的 转为 _id:ObjectId 类型. 2. 为了避免第1点, 我定义了 ...
- Vue + TypeScript + Element 搭建简洁时尚的博客网站及踩坑记
前言 本文讲解如何在 Vue 项目中使用 TypeScript 来搭建并开发项目,并在此过程中踩过的坑 . TypeScript 具有类型系统,且是 JavaScript 的超集,TypeScript ...
- Spark踩坑记——Spark Streaming+Kafka
[TOC] 前言 在WeTest舆情项目中,需要对每天千万级的游戏评论信息进行词频统计,在生产者一端,我们将数据按照每天的拉取时间存入了Kafka当中,而在消费者一端,我们利用了spark strea ...
- Spark踩坑记——数据库(Hbase+Mysql)
[TOC] 前言 在使用Spark Streaming的过程中对于计算产生结果的进行持久化时,我们往往需要操作数据库,去统计或者改变一些值.最近一个实时消费者处理任务,在使用spark streami ...
- 【踩坑记】从HybridApp到ReactNative
前言 随着移动互联网的兴起,Webapp开始大行其道.大概在15年下半年的时候我接触到了HybridApp.因为当时还没毕业嘛,所以并不清楚自己未来的方向,所以就投入了HybridApp的怀抱. Hy ...
- Spark踩坑记——共享变量
[TOC] 前言 Spark踩坑记--初试 Spark踩坑记--数据库(Hbase+Mysql) Spark踩坑记--Spark Streaming+kafka应用及调优 在前面总结的几篇spark踩 ...
- Spark踩坑记——从RDD看集群调度
[TOC] 前言 在Spark的使用中,性能的调优配置过程中,查阅了很多资料,之前自己总结过两篇小博文Spark踩坑记--初试和Spark踩坑记--数据库(Hbase+Mysql),第一篇概况的归纳了 ...
- djangorestframework+vue-cli+axios,为axios添加token作为headers踩坑记
情况是这样的,项目用的restful规范,后端用的django+djangorestframework,前端用的vue-cli框架+webpack,前端与后端交互用的axios,然后再用户登录之后,a ...
- HttpWebRequest 改为 HttpClient 踩坑记-请求头设置
HttpWebRequest 改为 HttpClient 踩坑记-请求头设置 Intro 这两天改了一个项目,原来的项目是.net framework 项目,里面处理 HTTP 请求使用的是 WebR ...
随机推荐
- python学习06循环
'''while''''''while 布尔表达式:冒号不能省略''''''1+2+3+...+10'''i=1sum1=0while i<=10: sum1+=i i+=1print(sum1 ...
- RedHat Linux server 6.5系统关机重启失败问题总结
今天晚上升级服务,由于服务器(red hat Linux server 6.5操作系统)没有正常关机,再重启的过程中遇到了如下问题: 1 服务器配置挺高的,认为启动过程有点慢是正常的,当时就没有上心, ...
- RequestDispatcher.forward() 方法和HttpServletResponse.sendRedirect()方法的区别
RequestDispatcher.forward() 方法和HttpServletResponse.sendRedirect()方法的区别 先贴一段代码 public void logon(Http ...
- 在独立的 Root 和 Home 硬盘驱动器上安装 Ubuntu
安装 Linux 系统时,可以有两种不同的方式.第一种方式是在一个超快的固态硬盘上进行安装,这样可以保证迅速开机和高速访问数据.第二种方式是在一个较慢但很强大的普通硬盘驱动器上安装,这样的硬盘转速快并 ...
- ACM-ICPC 2019 山东省省赛总结
五题手快拿银,不然拿铜,甚至不拿,从结果上来看拿了铜牌对第一年的我们来说算好的,也不算太好. 从拿奖后的第一天,我想写这篇博客,但是我忍了下来,那时候被喜悦冲昏了头脑,当 冷静下来,我开始打算写这篇博 ...
- 记一次真实的线上事故:一个update引发的惨案!
目录 前言 项目背景介绍 要命的update 结语 前言 从事互联网开发这几年,参与了许多项目的架构分析,数据库设计,改过的bug不计其数,写过的sql数以万计,从未出现重大纰漏,但常在河边走,哪 ...
- P1353 Running S
题意:https://www.luogu.com.cn/problem/P1353 奶牛们打算通过锻炼来培养自己的运动细胞,作为其中的一员,贝茜选择的运动方式是每天进行 n 分钟的晨跑.在每分钟的开始 ...
- WCF(一)
在学习WCF之前要知道几个术语: 一:终结点 终结点由3个要素组成:契约,绑定,地址. 1.契约:契约属于一个服务公开接口的一部分.一个服务的契约,定义了服务端公开的服务方法,使用的传输协议,可访问的 ...
- FOC 算法基础之欧拉公式
文章目录 欧拉公式 几何意义 复数平面 动态过程 加法 FOC电压矢量的推导 总结 参考 FOC中电压矢量合成的推导,对于欧拉公式的几何意义做了一个全面的回顾. 欧拉公式 欧拉是一个天才,欧拉公式甚至 ...
- Autohotkey心得
玩游戏,烧钱和作弊是永恒的话题,热键一定程度上和作弊相关.办公用数据库.编程.商业智能,一定程度上也是作弊,欺负没有相关信息技术的公司.个人. 避免和输入法产生冲突,少用Send,多用剪切板中转. E ...