写点什么

手把手教你从 Node 快速迁移到 Deno

  • 2020-06-03
  • 本文字数:4903 字

    阅读完需:约 16 分钟

手把手教你从Node快速迁移到Deno

上周我发表了一篇文章,介绍了 Deno 以及如何使用 Deno 和 Preact 创建一个聊天应用。文章发布后收到了很多询问,大多数问题关心的是:如何使用新的 Deno 生态系统来做那些我们原来用 Node 做的事情。我试着收集了一些 Node 中最常用的主题,并找出了它们在 Deno 中的替代方案。

首先我想明确一点,在 Deno 中我们可以使用许多现有的 Node.js 模块。由于许多模块都是可重用的,因此用不着为所有的事情都寻找替代选项。你可以访问 pika.dev 查找可以在 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 "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
复制代码


然后


➜ pm2 <span>start</span> ./app.sh
复制代码


Express/Koa

Express 和 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}`);
复制代码

MongoDB

MongoDB 是一个拥有强大可扩展性和灵活性的文档数据库。它在 JavaScript 生态系统中应用广泛,很多技术栈(如 MEAN 或 MERN)都会使用它,因此它非常受欢迎。



我们可以将 MongoDB 用在 Deno 生态中,可以使用以下驱动程序:https://github.com/manyuanrong/deno_mongo


import { init, MongoClient } from "https://deno.land/x/mongo@v0.6.0/mod.ts";
// Initialize the pluginawait init();
const client = new MongoClient();client.connectWithUri("mongodb://localhost:27017");
const db = client.database("test");const users = db.collection("users");
// insertconst insertId = await users.insertOne({ username: "user1", password: "pass1"});
// findOneconst user1 = await users.findOne({ _id: insertId });
// findconst users = await users.find({ username: { $ne: null } });
// aggregationconst docs = await users.aggregation([ { $match: { username: "many" } }, { $group: { _id: "$username", total: { $sum: 1 } } }]);
// updateOneconst { matchedCount, modifiedCount, upsertedId } = await users.updateOne( username: { $ne: null }, { $set: { username: "USERNAME" } });
// deleteOneconst deleteCount = await users.deleteOne({ _id: insertId });
复制代码

PostgreSQL


与 MongoDB 一样,PostgresSQL 也有一个驱动程序:


https://github.com/buildondata/deno-postgres


import { Client } from "https://deno.land/x/postgres/mod.ts";
const client = new Client({ user: "user", database: "test", hostname: "localhost", port: 5432});await client.connect();const result = await client.query("SELECT * FROM people;");console.log(result.rows);await client.end();
复制代码

MySQL/MariaDB


与 MongoDB 和 PostgresSQL 一样,MySQL/MariaDB 也有一个驱动程序:


https://github.com/manyuanrong/deno_mysql


import { Client } from "https://deno.land/x/mysql/mod.ts";
const client = await new Client().connect({ hostname: "127.0.0.1", username: "root", db: "dbname", poolSize: 3, // connection limit password: "password",});
let result = await client.execute(`INSERT INTO users(name) values(?)`, [ "aralroca",]);console.log(result);// { affectedRows: 1, lastInsertId: 1 }
复制代码

Redis


Redis 是最出名的缓存数据库,它也有 Deno 的驱动程序:


https://github.com/keroxp/deno-redis


import { connect } from "https://denopkg.com/keroxp/deno-redis/mod.ts";
const redis = await connect({ hostname: "127.0.0.1", port: 6379});const ok = await redis.set("example", "this is an example");const example = await redis.get("example");
复制代码

Nodemon


Nodemon 被用来在开发环境中监视文件的任何更改,发现更改后会自动重新启动服务器。它显著提升了 Node 的开发体验,开发人员无需再手动停止和重启服务器以查看应用更改。它可以在 Deno 中使用吗?


抱歉,你不能,但是也有另一种选择:Denon,Denon 的用法和使用 deno run 执行脚本一样。


https://github.com/eliassjogreen/denon


➜ denon server.<span>ts</span>
复制代码

Jest、Jasmine、Ava……


在 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 <span>test</span>
复制代码

Webpack、Parcel、Rollup……


Deno 的优势之一是我们可以搭配使用 ES 模块与 TypeScript,而无需诸如 Webpack、Parcel 或 Rollup 之类的打包器。


但你可能想要知道:如果给定了一棵文件树,我们是否可以制作一个包,将所有内容放到一个文件中以在 Web 环境中运行呢?


答案是肯定的。我们可以使用 Deno 的 CLI 做到这一点。这样就无需第三方打包器了。


➜ deno bundle myLib.ts myLib.bundle.js
复制代码


现在可以将其加载到浏览器中:


<script type="module">  import * as myLib from "myLib.bundle.js";</script>
复制代码

Prettier


在过去的几年中,Prettier 在 JavaScript 生态系统中大受欢迎,因为有了它,你就不用再操心格式化文件的事情了。


其实它也能用在 Deno 上,但这没什么意义,因为 Deno 有自己的格式化程序。


你可以使用以下命令格式化文件:


➜ deno fmt

NPM Scripts


在 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


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 上运行


要在 Docker 内部运行 Deno,我们可以创建以下 Dockerfile:


FROM hayd/alpine-deno:1.0.0
EXPOSE 1993 # Port.
WORKDIR /app
USER deno
COPY deps.ts .RUN deno cache deps.ts # Cache the deps
ADD . .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

作为 lambda 运行


要将 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 };}
复制代码


有趣的参考:


总结

我肯定遗漏了一些 Node 主题以及它们的 Deno 替代方案,大家有兴趣的话可以在评论里补充。我希望本文能帮助你跨过 Deno 的入门门槛。


想要了解可以用在 Deno 中的所有库:



原文链接:


https://aralroca.com/blog/from-node-to-deno


2020-06-03 18:079601

评论 3 条评论

发布
用户头像
作者 Aral Roca 感谢译者
2020-06-09 03:17
回复
用户头像
各种标题党 一股头条自媒体的味道
2020-06-04 11:19
回复
用户头像
这叫快速迁移?明明是重写好吗
2020-06-04 09:06
回复
没有更多了
发现更多内容

桌面云电脑配置要求

青椒云云电脑

云电脑

HTX 与 Zebec  Protocol 展开深度合作,并将以质押者的身份参与 ZBC Staking

鳄鱼视界

经人行批准!华为旗下支付机构更名,进入负一屏“发现”页享华为支付

最新动态

Scrum敏捷项目管理关键

顿顿顿

敏捷开发 敏捷项目管理 scrum敏捷工具

1024程序员节(源聚一堂北京站)节目有奖征集!

开放原子开源基金会

教育行业如何选择云桌面解决方案?

青椒云云电脑

桌面云 云桌面

如何选择适合自己的音视频产品

X2Rtc

开源 音视频 RTC

Python 爬虫实战之爬拼多多商品并做数据分析

Noah

一键生成!盘点那些好用的3D建模AI生成工具!

Finovy Cloud

AI 3d建模

公司如何部署云桌面系统办公

青椒云云电脑

云桌面 云桌面解决方案 云桌面系统

企业如何部署云桌面?选私有云还是公有云

青椒云云电脑

云桌面

什么是云桌面服务?有什么价值

青椒云云电脑

云桌面

低代码加速软件开发进程

树上有只程序猿

低代码开发 JNPF

加入鲲鹏HPC训练营,一起引领高性能计算新潮流

科技热闻

百度世界2023 :小度发布全球首款大模型家庭智能机器人

科技热闻

前端开发工具有哪些?17款前端工程师必备工具推荐!

彭宏豪95

效率 前端开发 开发工具 前端工程师 办公软件

云技术分享 | 快速构建 CodeWhisperer 代码生成服务,让 AI 辅助编程

亚马逊云科技 (Amazon Web Services)

ide 生成式人工智能 CodeWhisperer

HTX 与 Zebec  Protocol 深度合作,并将以质押者的身份参与 ZBC Staking

股市老人

免费:实时 AI 编程助手 Amazon CodeWhisperer

亚马逊云科技 (Amazon Web Services)

人工智能 Python 3.12 java‘ 云上探索实验室

十几种排序算法的可视化效果,快来看看!

编程的平行世界

算法 可视化

九月 NFT 行业解读:熊市情绪仍占上风

Footprint Analytics

区块链 NFT 链游

AGI 黑客松收官,Zilliz 向量数据库助力34支参赛队伍角逐大模型时代的Killer App

Zilliz

黑客松 Zilliz AGI 向量数据库

手把手教你从Node快速迁移到Deno_开源_Aral Roca_InfoQ精选文章