吾观尔等皆是插标卖首之徒 發表於 2020-5-21 18:57:00

deno + mongodb 实战踩坑记

<p>自从 deno 1.0 发布以来,有关 deno 的文章很多,大多数都是在讨论怎么安装 deno 、deno 有哪些特点 、deno 和 node 有哪些异同、deno是不是 node 的替代品等。咱们今天不讨论这些,毕竟 Talk is cheap. Show me the code! 亲自体验一把 deno 开发带来的快感、用 deno 搞一个“企业级”应用:deno-supermarket,难道不香吗?</p>
<h2 id="deno-常见的一些坑">deno 常见的一些坑</h2>
<p>在实战之前,还是先来介绍几个我在刚接触 deno 时遇到的小坑。</p>
<h3 id="权限标志符位置的问题">权限标志符位置的问题</h3>
<p>我们都知道, deno 默认是安全的,就是导致了默认情况下是不允许访问网络、读写文件等。比如有个名为 index.ts 的文件内容如下:</p>
<pre><code>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" });
}
</code></pre>
<p>如果直接执行 <code>deno run index.ts</code>, 会报错:</p>
<pre><code>error: Uncaught PermissionDenied: network access to "0.0.0.0:8000", run again with the --allow-net flag
</code></pre>
<p>所以我们很自然的就会在启动命令的最后加上 <code>--allow-net</code> ,如下:</p>
<pre><code>deno run index.ts --allow-net
</code></pre>
<p>但是,这样仍然会报错。查了资料才知道 ,<code>--allow-net</code> 、<code>--allow-read</code> 之类的标志是不可以放到文件名后面的,必须紧跟在 <code>denorun</code> 后面,比如,如下才是正确的:</p>
<pre><code>deno run --alow-net index.ts
</code></pre>
<p>为什么调换了位置就不行呢? issue 上的回答是,如果 <code>--allow-net</code> 跟在文件名后面,是传给 js脚本的,而不是传给 deno 的。想了解更多的,可以看这个 confused by order of cli option flags。反正,记住一点就行:权限标志一定要跟在 <code>deno run </code> 后面!</p>
<p>因为我们前端同学大多数平时很少写后台,不太清楚安全的重要性,为了避免遇到各种权限问题,我建议平时在写一些练手项目时,直接用 <code>deno run-A</code> 来启用全部的权限。(这只是方便调试,在生产环境中一定要慎用!)</p>
<h3 id="不稳定的-api">不稳定的 API</h3>
<p>因为实战过程中使用了 mongodb , 所以需要引入 Deno 的第三方模块 mongo,然而在启动项目会报错:</p>
<pre><code>error: TS2339 : Property 'openPlugin' does not exist on type 'typeof Deno'.
</code></pre>
<p>查了一下,发现是因为 <code>openPlugin</code> 这个方法目前还不稳定。默认情况下,deno 只会提供稳定的 api。如果需要开启不稳定 api,可以添加 <code>--stable</code> 标志。比如:</p>
<pre><code>deno run -A --unstable index.ts
</code></pre>
<p>可能有人会问,<code>-A</code> 和 <code>--unstable</code> 的位置调换会不会有问题。这个亲测过不会有问题。只要标志符在文件名称之前就行了。</p>
<p>还有个问题,到底哪些是稳定 API,哪些是不稳定 API 呢?其实 deno 官方文档已经帮我们分好类的了,入口地址分别是:</p>
<ul>
<li>稳定的 api 文档</li>
<li>不稳定的 api 文档</li>
</ul>
<p>如果你怀疑 <code>--unstable</code> 的作用,可以使用下面的方法打印出 <code>Deno</code> 上的所有成员:</p>
<pre><code>console.log(Object.keys(Deno).length)
</code></pre>
<p>使用 <code>deno run --unstable index.ts</code> 输出的结果是 117,使用 <code>deno run index.ts</code> 输出的结果是 88 。说明稳定的 api 有 88 个,不稳定的有 29 个。</p>
<h2 id="deno-的一些使用技巧">deno 的一些使用技巧</h2>
<p>从 node 切换到 deno, 我们的开发思维也要随之转变。所以,我们再来看看 deno 的一些和 node 不一样的开发技巧。</p>
<h3 id="如何管理版本">如何管理版本?</h3>
<p>刚开始我也很疑惑:没有了 <code>package.json</code>, 那怎么控制各依赖的版本呀?比如,我们有10个文件都依赖了 <code>mongo@v0.0.6</code>, 那每个文件都使用以下代码进行引入:</p>
<pre><code> import { init, MongoClient } from 'https://deno.land/x/mongo@v0.6.0/mod.ts'
</code></pre>
<p>可是有一天,我突然想把 0.6.0 升级到 0.7.0, 那怎么办呢?一个个文件的进行替换容易漏掉,当然也可以全局搜索批量替换 。但是这种效率都不是很高。</p>
<p>官方给出的推荐做法是,使用 <code>deps.ts</code> 文件来引入远程文件,并管理版本。(当然 ,文件名称不一定叫做 <code>deps.ts</code>, 你也可以改成其他的名称)。具体做法就是,把所有用到的远程依赖,都在 <code>deps.ts</code> 中引入 ,并且通过<code>Re-export</code> 手段导出各依赖,然后其他文件就可以从 <code>deps.ts</code> 中拿到所需要的依赖了。</p>
<p>回到刚才说10个文件都依赖到 <code>mongo</code> 的问题,如果改成 <code>deps.ts</code> 文件来统一管理是这样的:</p>
<pre><code>export * from 'https://deno.land/x/mongo@v0.6.0/mod.ts'
</code></pre>
<p>然后那些需要用到 mongo 的文件,不要直接从远程引入,而是从 <code>deps.ts</code> 中引入,如下:</p>
<pre><code>import { init, MongoClient } from '../pathTo/deps.ts';
</code></pre>
<p>如果需要升级的话,我们可以直接把 <code>deps.ts</code> 里面的 mongo 地址中的 <code>0.6.0</code> 改成 <code>0.7.0</code> 就行了。</p>
<p>另外,有一点和 npm 类似的是,如果没有指定版本号,即远程地址中没有指定版本,比如:</p>
<pre><code>export * from 'https://deno.land/x/mongo/mod.ts'
</code></pre>
<p>就会默认安装最新版的依赖。</p>
<h3 id="如何查找一些对我有用的-deno-库">如何查找一些对我有用的 deno 库?</h3>
<p>使用 node ,可以到 npm 上查找一些库。deno 也有类似的平台,目前分为两种库,一种是官方标准的,另外一种是第三方的。标准库可以到这里查找:Deno Standard Modules。第三方库可以到这里查找: Deno Third Party Modules</p>
<h2 id="实战-使用-deno-开发一个具备增删查改的商城系统">实战: 使用 deno 开发一个具备增删查改的商城系统</h2>
<p>OK, 具备以上的知识点,现在可以实战了。首先,需要保证你的电脑安装了 deno 1.0 。另外,由于用到了 mongodb ,所以需要你的电脑也要安装 mongodb。</p>
<h3 id="界面">界面</h3>
<p>先来看看我们的商城的界面:</p>
<p><img src="https://user-gold-cdn.xitu.io/2020/5/21/17236acf0d65ad5d?w=1187&amp;h=574&amp;f=png&amp;s=47484" alt="" loading="lazy"></p>
<p>麻雀虽小五脏俱全哈!具备添加商品、查询商品、删除商品、修改商品的功能。这是典型的 REST API 风格的系统 。</p>
<h3 id="项目结构">项目结构</h3>
<p>然后再来看看项目结构:</p>
<p><img src="https://user-gold-cdn.xitu.io/2020/5/21/17236ad3ea9efe6e?w=457&amp;h=349&amp;f=png&amp;s=17228" alt="" loading="lazy"></p>
<ul>
<li>.deno_plugins: 这是 mongo 模块所下载的动态链接库,不用关注它。</li>
<li>congig/db.ts: 这是连接 mongodb 的相关配置文件。目前写死的端口号是 27017 , 如果你的 mongodb 端口不是这个,可以在这个文件里面修改。</li>
<li>controllers/goods.ts: 这是实现增删查改的逻辑代码</li>
<li>public/index.html: 这是前端静态页面,跟 deno 无关的,我们只需要用 deno 来服务该目录就行。</li>
<li>deps.ts: 用来管理远程依赖库,然后 Re-export 出去给其他文件使用。</li>
<li>server.ts 入口文件,跟我们用 epress 或 koa 时的入口 文件 app.js 类似。</li>
</ul>
<h3 id="依赖模块的选择">依赖模块的选择</h3>
<p>因为该项目涉及到了前后端,如果使用 node 的话,一般会选择 express 或 koa。同样的,我们使用 deno 也要选择对应的框架 ,不然的话,http服务以及路由跳转等都不是那么容易处理的。deno 上的这类框架,比较多人 star 的是 oak 和 abc,这里我们选择使用 abc。</p>
<p>另外,因为使用 mongodb , 所以还需要引入 mongo</p>
<h2 id="结束语">结束语</h2>
<p>好啦,对于 deno 初体验就写到这啦, 具体的代码这里不打算贴出来了,有兴趣的可以前往 github 查看:</p>
<ul>
<li>deno-supermarket</li>
</ul>
<p>有问题的可以一起交流学习哈~</p><br><br>
来源:https://www.cnblogs.com/yugege/p/12932695.html
頁: [1]
查看完整版本: deno + mongodb 实战踩坑记