deno + mongodb 實戰踩坑記


自從 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 的是 oakabc,這里我們選擇使用 abc。

另外,因為使用 mongodb , 所以還需要引入 mongo

結束語

好啦,對於 deno 初體驗就寫到這啦, 具體的代碼這里不打算貼出來了,有興趣的可以前往 github 查看:

有問題的可以一起交流學習哈~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM