

从 Node 到 Deno
source link: http://mp.weixin.qq.com/s?__biz=MzI3NzIzMDY0NA%3D%3D&%3Bmid=2247488849&%3Bidx=1&%3Bsn=2ac98b43b391c21f9a274bac252499c4
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

每日前端夜话 第338篇
翻译: 疯狂的技术宅
作者:Aral Roca
来源:aralroca
正文共:8941 字
预计阅读时间:15 分钟
我收集了一些 Node 中最常用的主题,并寻找 Deno 的替代方案。首先我想说明,许多当前的 Node.js 模块都可以都可以用在 Deno 中。由于许多模块都是可重用的,所以没有必要为所有方法去寻找替代方案。你可以访问 pika.dev 查找可以在 Deno 中使用的模块。
本文将涵盖以下内容:
Electron
通过 Node.js,我们可以使用 Electron 创建桌面程序。Electron 使用 Chromium 作为接口来运行 Web 环境。但是 Electron 可以在 Deno 中使用吗?有其他选择吗?

好吧,现在 Electron 还不能在 Deno 下执行,必须寻找替代方案。由于 Deno 是用 Rust 写的,所以可以用 web-view rust 绑定 (https://github.com/Boscop/web-view) 在 Deno 中运行桌面程序。
这样,我们可以使用本机操作系统的 webview 视图来运行任意 webview。
Repo: https://github.com/eliassjogreen/deno_webview
1import { WebView } from "https://deno.land/x/webview/mod.ts"; 2 3const sharedOptions = { 4 width: 400, 5 height: 200, 6 resizable: true, 7 debug: true, 8 frameless: false, 9}; 10 11const webview1 = new WebView({ 12 title: "Multiple deno_webview example", 13 url: `data:text/html, 14 <html> 15 <body> 16 <h1>1</h1> 17 </body> 18 </html> 19 `, 20 ...sharedOptions, 21}); 22 23const webview2 = new WebView({ 24 title: "Multiple deno_webview example", 25 url: `data:text/html, 26 <html> 27 <body> 28 <h1>2</h1> 29 </body> 30 </html> 31 `, 32 ...sharedOptions, 33}); 34 35await Promise.all([webview1.run(), webview2.run()]);

Forever / PM2
Forever 和 PM2是 CLI 工具,可以使给定脚本作为守护程序连续运行。与 Forever 不同,PM2 更完整,还可以用作负载均衡器。两者在 Node.js 中都非常有用,但是我们可以在 Deno 中使用吗?
Forever 仅能用于 Node,不过我们可以借助 PM2 运行非 Node.js 脚本,所以可以将其用于 Deno。

创建一个 app.sh
文件
1#!/bin/bash 2deno run -A myCode.ts
然后
1➜ pm2 start ./app.sh

Express / Koa
Express 和 Koa 是最知名的 Node 框架。他们以其强大的路由系统和 HTTP 辅助器(重定向、缓存等)而闻名。可以在 Deno中使用它们吗?答案是否…但是有一些替代方法。

Http(标准库)
Deno 自己的标准库已经能够满足 Express 或 Koa 提供的许多功能。https://deno.land/std/http/。
1import { ServerRequest } from "https://deno.land/std/http/server.ts"; 2import { getCookies } from "https://deno.land/std/http/cookie.ts"; 3 4let request = new ServerRequest(); 5request.headers = new Headers(); 6request.headers.set("Cookie", "full=of; tasty=chocolate"); 7 8const cookies = getCookies(request); 9console.log("cookies:", cookies);
但是声明路由的方法并没有什么吸引力,所以让我们看看更多的替代方案。
Oak (第三方库)
受 Koa 启发,这是目前最优雅的解决方案之一。
-
https://github.com/oakserver/oak
1import { Application, } from "https://deno.land/x/oak/mod.ts"; 2 3const app = new Application(); 4 5app.use((ctx) => { 6 ctx.response.body = "Hello World!"; 7}); 8 9await app.listen({ port: 8000 });
Abc(第三方库)
类似于 Oak
-
https://deno.land/x/abc。
1import { Application } from "https://deno.land/x/abc/mod.ts"; 2 3const app = new Application(); 4 5app.static("/static", "assets"); 6 7app.get("/hello", (c) => "Hello!") 8 .start({ port: 8080 });
Deno-express(第三方库)
也许是和 Express Framework 最相似的替代方案。
-
https://github.com/NMathar/deno-express。
1import * as exp from "https://raw.githubusercontent.com/NMathar/deno-express/master/mod.ts"; 2 3const port = 3000; 4const app = new exp.App(); 5 6app.use(exp.static_("./public")); 7app.use(exp.bodyParser.json()); 8 9app.get("/api/todos", async (req, res) => { 10 await res.json([{ name: "Buy some milk" }]); 11}); 12 13const server = await app.listen(port); 14console.log(`app listening on port ${server.port}`);
MongoDB
MongoDB 是有着巨大的可扩展性和灵活性的文档型数据库。在 JavaScript 生态中已被广泛使用,使用它的许多技术栈(如 MEAN 或 MERN)都非常受欢迎。

所以可以将 MongoDB 与 Deno 结合使用。可以使用这个驱动程序:
-
https://github.com/manyuanrong/deno_mongo。
1import { init, MongoClient } from "https://deno.land/x/[email protected]/mod.ts"; 2 3// Initialize the plugin 4await init(); 5 6const client = new MongoClient(); 7client.connectWithUri("mongodb://localhost:27017"); 8 9const db = client.database("test"); 10const users = db.collection("users"); 11 12// insert 13const insertId = await users.insertOne({ 14 username: "user1", 15 password: "pass1" 16}); 17 18// findOne 19const user1 = await users.findOne({ _id: insertId }); 20 21// find 22const users = await users.find({ username: { $ne: null } }); 23 24// aggregation 25const docs = await users.aggregation([ 26 { $match: { username: "many" } }, 27 { $group: { _id: "$username", total: { $sum: 1 } } } 28]); 29 30// updateOne 31const { matchedCount, modifiedCount, upsertedId } = await users.updateOne( 32 username: { $ne: null }, 33 { $set: { username: "USERNAME" } } 34); 35 36// deleteOne 37const deleteCount = await users.deleteOne({ _id: insertId });
PostgresSQL

像 MongoDB 一样,也有 PostgresSQL 的驱动:https://github.com/buildondata/deno-postgres。
1import { Client } from "https://deno.land/x/postgres/mod.ts"; 2 3const client = new Client({ 4 user: "user", 5 database: "test", 6 hostname: "localhost", 7 port: 5432 8}); 9await client.connect(); 10const result = await client.query("SELECT * FROM people;"); 11console.log(result.rows); 12await client.end();
MySQL / MariaDB

与 MongoDB 和 PostgresSQL 一样,还有 MySQL/MariaDB 的驱动程序。
-
https://github.com/manyuanrong/deno_mysql
1import { Client } from "https://deno.land/x/mysql/mod.ts"; 2 3const client = await new Client().connect({ 4 hostname: "127.0.0.1", 5 username: "root", 6 db: "dbname", 7 poolSize: 3, // connection limit 8 password: "password", 9}); 10 11let result = await client.execute(`INSERT INTO users(name) values(?)`, [ 12 "aralroca", 13]); 14console.log(result); 15// { affectedRows: 1, lastInsertId: 1 }
Redis

Redis 是最著名的缓存数据库,也有 Deno 驱动程序。
-
https://github.com/keroxp/deno-redis
1import { connect } from "https://denopkg.com/keroxp/deno-redis/mod.ts"; 2 3const redis = await connect({ 4 hostname: "127.0.0.1", 5 port: 6379 6}); 7const ok = await redis.set("example", "this is an example"); 8const example = await redis.get("example");
Nodemon

Nodemon 用于在开发环境中用于监视文件中的更改,并自动重新启动服务器。这使 Node 开发更加有趣,而无需手动重启服务器来查看应用的更改。它可以用在 Deno 中吗?
抱歉,不可以…但是有另外一种选择:Denon。
-
https://github.com/eliassjogreen/denon
可以像使用 deno run
一样用 Denon 来执行脚本。
1➜ denon server.ts
Jest, Jasmine, Ava…

在 Node.js 生态中,有许多测试用的工具。但是官方并没有提供测试 Node.js 代码的方法。
在 Deno中,有一种官方的方法,可以用测试标准库。
-
https://deno.land/std/testing
1import { assertStrictEq } from 'https://deno.land/std/testing/asserts.ts' 2 3Deno.test('My first test', async () => { 4 assertStrictEq(true, false) 5})
这样运行测试:
1➜ deno test
Webpack, Parcel, Rollup…

Deno 的一个优势是无需打包器(例如 Webpack、 Parcel 或 Rollup)就可以使 ESmodules 与 TypeScript 在一起工作。
但是如果给定一个文件树,我们是否可以打成一个包,把所有内容放到一个文件中并在网络上运行它呢?
当然可以。可以用 Deno 的 CLI 做到这一点,不需要第三方打包程序。
1➜ deno bundle myLib.ts myLib.bundle.js
然后就可以加载到浏览器中了:
1<script type="module"> 2 import * as myLib from "myLib.bundle.js"; 3</script>
Prettier

在过去的几年中,Prettier 在 JavaScript 生态系统中已广为人知,正是因为有它,你不必再去担心格式化文件的麻烦。
实际上它仍然可以在 Deno 上使用,但是这失去了意义,因为 Deno 有自己的格式化程序。
可以用以下命令格式化文件:
1➜ deno fmt
NPM Scripts

在 Deno 中, package.json
不再存在。我很怀念在 package.json
中声明的脚本。
一个简单的解决方案是用 makefile
,并使用 make
命令执行。但是,如果你想念 npm 语法,那么 Deno 有一个 npm 风格的脚本运行器:
-
https://github.com/umbopepato/velociraptor
你可以用脚本去定义文件:
1# scripts.yaml 2scripts: 3 start: deno run --allow-net server.ts 4 test: deno test --allow-net server_test.ts
执行:
1➜ vr run <SCRIPT> 2
另一种选择是 denox (https://github.com/BentoumiTech/denox) ,与 Velociraptor 非常相似。
Nvm

Nvm (https://github.com/nvm-sh/nvm) 是一个用于管理多个活动 Node 版本的 CLI,可以根据你的项目轻松升级或降级版本。
在 Deno 中 nvm
的替代物是 dvm
。
-
https://github.com/axetroy/dvm
1➜ dvm use 1.0.0
Npx
Npx 近年来非常流行,可以直接调用 npm 包内的模块。由于 Deno 是一个独立的生态,所以不存在 npm 中的那些重多项目。那么我们不用 deno install https://url-of-module.ts
而用 Deno 执行来执行它们呢?
以与运行项目相同的方式,而不是文件,放置模块的 URL:
1➜ deno run https://deno.land/std/examples/welcome.ts
如你所见,我们不仅需要记住模块的名称,还要记住整个 URL,这样用起来很困难。但是另一方面,它提供了更多的灵活性,因为我们可以运行任何文件,而不仅仅是像 npx
这样在 package.json
中指定的文件。
在Docker 中运行

要在 Docker 中运行Deno,可以这样创建 Dockerfile:
1FROM hayd/alpine-deno:1.0.0 2 3EXPOSE 1993 # Port. 4 5WORKDIR /app 6 7USER deno 8 9COPY deps.ts . 10RUN deno cache deps.ts # Cache the deps 11 12ADD . . 13RUN deno cache main.ts # main entrypoint. 14 15CMD ["--allow-net", "main.ts"]
这样构建并运行:
1➜ docker build -t app . && docker run -it --init -p 1993:1993 app
Repo: https://github.com/hayd/deno-docker
用于亚马逊 lambda 运算

要将 Deno 用于 AWS lambda,可以用 Deno STD 库中的模块。
-
https://deno.land/x/lambda。
1import { 2 APIGatewayProxyEvent, 3 APIGatewayProxyResult, 4 Context 5} from "https://deno.land/x/lambda/mod.ts"; 6 7export async function handler( 8 event: APIGatewayProxyEvent, 9 context: Context 10): Promise<APIGatewayProxyResult> { 11 return { 12 body: `Welcome to deno ${Deno.version.deno} `, 13 headers: { "content-type": "text/html;charset=utf8" }, 14 statusCode: 200 15 }; 16}
有趣的参考:
-
把 Deno 用在 Vercel 中:https://github.com/lucacasonato/now-deno
-
AWS 中的 Deno:https://blog.begin.com/deno-runtime-support-for-architect-805fcbaa82c3
结束语
我确定肯定会遗漏了一些 Node 主题以及它们对应的 Deno 替代方案,如果你有补充请在下面留言。
探索所有可以用在 Deno 中的库:
-
https://deno.land/std
-
https://deno.land/x
-
https://www.pika.dev/
原文链接
https://aralroca.com/blog/from-node-to-deno
2020年
京程一灯课程体系上新,这是我们第一次将全部课程列表对外开放。
愿你有个好前程,愿你月薪30K。我们是认真的 !
点击文末 阅读全文 查看细节。
长按二维码,加大鹏老师微信好友
拉你加入前端技术交流群
唠一唠怎样才能拿高薪
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK