作者 | Aral Roca
譯者 | 王強
策劃 | 蔡芳芳
前言上週我發表了幾篇文章,介紹了 Deno 以及如何使用 Deno 和 Preact 建立一個聊天應用。文章釋出後收到了很多詢問,大多數問題關心的是:如何使用新的 Deno 生態系統來做那些我們原來用 Node 做的事情。我試著收集了一些 Node 中最常用的主題,並找出了它們在 Deno 中的替代方案。首先我想明確一點,在 Deno 中我們可以使用許多現有的 Node.js 模組。由於許多模組都是可重用的,因此用不著為所有的事情都尋找替代選項。你可以訪問 pika.dev 查詢可以在 Deno 中使用的模組。
Deno相關知識優質文章:
本文最初發佈於 Aral Roca 個人網站,經原作者授權由 InfoQ 中文站翻譯並分享。
Electron在 Node.js 中,我們可以使用 Electron 建立桌面應用程式。Electron 使用 Chromium 作為介面來執行 Web 環境。但是,我們可以在 Deno 中使用 Electron 嗎?或者有其他選擇嗎?
現在,Electron 是完全不能用在 Deno 下的,我們必須尋找替代方案。由於 Deno 是用 Rust 開發的,因此我們可以使用 web-view rust bindings 在 Deno 中執行桌面應用程式。
這樣,我們就可以使用原生 OS webview 來執行任意數量的 Web 檢視了。
倉庫:
https://github.com/eliassjogreen/deno_webview
import { WebView } from "http://127.0.0.1/vhost/conf/img_echo.php?w=640&h=427&src=https://deno.land/x/webview/mod.ts";const sharedOptions = { width: 400, height: 200, resizable: true, debug: true, frameless: false,};const webview1 = new WebView({ title: "Multiple deno_webview example", url: `data:text/html, <html> <body> <h1>1</h1> </body> </html> `, ...sharedOptions,});const webview2 = new WebView({ title: "Multiple deno_webview example", url: `data:text/html, <html> <body> <h1>2</h1> </body> </html> `, ...sharedOptions,});await Promise.all([webview1.run(), webview2.run()]);
Forever/PM2
Forever 和 PM2 是用來確保作為守護程式的指定指令碼可以持續執行的 CLI 工具。與 Forever 不同,PM2 功能更完善,還可以用作負載均衡器。兩者在 Node 中都很好用,但是我們可以在 Deno 中使用它們嗎?
Forever 只適用於 Node,因此在 Deno 中是用不了的。但我們可以使用 PM2 執行費 Node 指令碼,因此可以將其用於 Deno。
建立一個 app.sh 檔案
#!/bin/bashdeno run -A myCode.ts
然後
Express/KoaExpress 和 Koa 都是最出名的 Node 框架。它們擁有強大的路由系統和 HTTP helpers(重定向,快取等),因而廣受歡迎。我們可以在 Deno 中使用它們嗎?答案是否定的,但是也有一些替代方法。
Http(標準庫)
Deno 自己的標準庫就能提供 Express 或 Koa 提供的許多功能了:
https://deno.land/std/http/
import { ServerRequest } from "https://deno.land/std/http/server.ts";import { getCookies } from "https://deno.land/std/http/cookie.ts";let request = new ServerRequest();request.headers = new Headers();request.headers.set("Cookie", "full=of; tasty=chocolate");const cookies = getCookies(request);console.log("cookies:", cookies);
但是,它宣告路由的方法看起來不怎麼好用,因此我們來看看更多替代方案。
Oak(第三方庫)受 Koa 啟發的 Oak 是目前最優雅的解決方案之一:
https://github.com/oakserver/oak
import { Application, } from "https://deno.land/x/oak/mod.ts";const app = new Application();app.use((ctx) => { ctx.response.body = "Hello World!";});await app.listen({ port: 8000 });
Abc(第三方庫)
類似 Oak:
https://deno.land/x/abc
import { Application } from "https://deno.land/x/abc/mod.ts";const app = new Application();app.static("/static", "assets");app.get("/hello", (c) => "Hello!") .start({ port: 8080 });
Deno-Express(第三方庫)也許是最接近 Express 框架的替代方案:
https://github.com/NMathar/deno-express
import * as exp from "https://raw.githubusercontent.com/NMathar/deno-express/master/mod.ts";const port = 3000;const app = new exp.App();app.use(exp.static_("./public"));app.use(exp.bodyParser.json());app.get("/api/todos", async (req, res) => { await res.json([{ name: "Buy some milk" }]);});const server = await app.listen(port);console.log(`app listening on port ${server.port}`);
MongoDBMongoDB 是一個擁有強大可擴充套件性和靈活性的文件資料庫。它在 JavaScript 生態系統中應用廣泛,很多技術棧(如 MEAN 或 MERN)都會使用它,因此它非常受歡迎。
我們可以將 MongoDB 用在 Deno 生態中,可以使用以下驅動程式:
https://github.com/manyuanrong/deno_mongo
與 MongoDB 一樣,PostgresSQL 也有一個驅動程式:
https://github.com/buildondata/deno-postgres
與 MongoDB 和 PostgresSQL 一樣,MySQL/MariaDB 也有一個驅動程式:
https://github.com/manyuanrong/deno_mysql
Redis 是最出名的快取資料庫,它也有 Deno 的驅動程式:
https://github.com/keroxp/deno-redis
Nodemon 被用來在開發環境中監視檔案的任何更改,發現更改後會自動重新啟動伺服器。它顯著提升了 Node 的開發體驗,開發人員無需再手動停止和重啟伺服器以檢視應用更改。它可以在 Deno 中使用嗎?
抱歉,你不能,但是也有另一種選擇:Denon,Denon 的用法和使用 deno run 執行指令碼一樣。
https://github.com/eliassjogreen/denon
在 Node.js 生態系統中,測試執行器有很多選項可用。但官方並沒有提供一種測試 Node.js 程式碼的方法。
在 Deno 中有一種官方方法,你可以使用 testing 標準庫:
https://deno.land/std/testing
import { assertStrictEq } from 'https://deno.land/std/testing/asserts.ts'Deno.test('My first test', async () => { assertStrictEq(true, false)})
要執行測試:
Deno 的優勢之一是我們可以搭配使用 ES 模組與 TypeScript,而無需諸如 Webpack、Parcel 或 Rollup 之類的打包器。
但你可能想要知道:如果給定了一棵檔案樹,我們是否可以製作一個包,將所有內容放到一個檔案中以在 Web 環境中執行呢?
答案是肯定的。我們可以使用 Deno 的 CLI 做到這一點。這樣就無需第三方打包器了。
➜ deno bundle myLib.ts myLib.bundle.js
現在可以將其載入到瀏覽器中:
其實它也能用在 Deno 上,但這沒什麼意義,因為 Deno 有自己的格式化程式。
你可以使用以下命令格式化檔案:
在 Deno 中,package.json 不復存在。而我非常想念的一個特性是在 package.json 中宣告的指令碼。
一個簡單的解決方案是使用一個 makefile,並用 make 執行它。但如果你懷念 npm 語法,那麼 Deno 也有一個 npm 樣式的指令碼執行器:
https://github.com/umbopepato/velociraptor
你可以使用指令碼定義檔案:
# scripts.yamlscripts: start: deno run --allow-net server.ts test: deno test --allow-net server_test.ts
這樣執行:
➜ vr run <SCRIPT>
另一個替代品是 denox,與 Velociraptor 非常相似。
Nvm 是一個 CLI,用來管理多個活動 Node 版本,以便根據專案需求輕鬆升級或降級版本。
在 Deno 中 nvm 的等效方案是 dvm:
https://github.com/axetroy/dvm
➜ dvm use 1.0.0
Npx近年來 Npx 非常流行,因為它可以直接執行 npm 軟體包,而無需安裝它們。現在,由於 Deno 是一個獨立的生態系統,所以 npm 中的許多專案都不可用了。那麼,我們能不能不用 deno install https://url-of-module.ts 安裝 Deno 模組,就直接使用它們呢?
答案是可以的,就和我們執行專案的方法一樣,只不過用的是模組而非檔案的 URL:
➜ deno run https://deno.land/std/examples/welcome.ts
如你所見,我們不僅需要記住模組的名稱,而且還要記住整個 URL,所以用起來很麻煩。另一方面,它提供了更大的靈活性,因為我們可以執行任何檔案,而不僅僅是在 package.json 中指定為二進位制檔案的檔案(如 npx)。
要在 Docker 內部執行 Deno,我們可以建立以下 Dockerfile:
FROM hayd/alpine-deno:1.0.0EXPOSE 1993 # Port.WORKDIR /appUSER denoCOPY deps.ts .RUN deno cache deps.ts # Cache the depsADD . .RUN deno cache main.ts # main entrypoint.CMD ["--allow-net", "main.ts"]
構建 + 執行:
➜ docker build -t app . && docker run -it --init -p 1993:1993 app
倉庫:https://github.com/hayd/deno-docker
要將 Deno 用作一個 lambda,可以使用 Deno 標準庫中的這個模組:
https://deno.land/x/lambda
import { APIGatewayProxyEvent, APIGatewayProxyResult, Context} from "https://deno.land/x/lambda/mod.ts";export async function handler( event: APIGatewayProxyEvent, context: Context): Promise<APIGatewayProxyResult> { return { body: `Welcome to deno ${Deno.version.deno} `, headers: { "content-type": "text/html;charset=utf8" }, statusCode: 200 };}
有趣的參考:
Vercel 中的 Deno:https://github.com/lucacasonato/now-denoAWS 中的 Deno:https://blog.begin.com/deno-runtime-support-for-architect-805fcbaa82c3總結
想要了解可以用在 Deno 中的所有庫:
作者 | Aral Roca
譯者 | 王強
策劃 | 蔡芳芳