从 Node 到 Deno

2025-05-24

从 Node 到 Deno

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

上周我发表了一篇关于 Deno 的文章,介绍了如何使用 Deno 和 Preact 创建聊天应用。从那时起,许多疑问就出现了。其中大部分是关于如何在新的 Deno 生态系统中做我们在 Node 中做过的事情。

我尝试收集 Node 中一些最常用的主题,并寻找 Deno 的替代方案。首先,我想明确一点,我们可以使用许多现有的 Node.js 模块。没有必要为所有模块都寻找替代方案,因为许多模块都是可复用的。您可以访问pika.dev来查找可在 Deno 中使用的模块。话虽如此,让我们从以下列表开始:

我们将介绍以下内容:

电子

使用 Node.js,我们可以使用Electron创建桌面应用程序。Electron 使用 Chromium 作为接口来运行 Web 环境。但是,我们可以将 Electron 与 Deno 一起使用吗?还有其他选择吗?

电子标志

嗯,目前 Electron 还远远无法在 Deno 下运行。我们必须寻找替代方案。由于 Deno 是用 Rust 编写的,我们可以使用Web-View Rust 绑定在 Deno 中运行桌面应用程序。

这样,我们就可以使用原生操作系统 webview 来运行任意数量的 webview。

仓库https://github.com/eliassjogreen/deno_webview

import { WebView } from "https://deno.land/x/webview/mod.ts";

const contentType = 'text/html'
const sharedOptions = {
  width: 400,
  height: 200,
  resizable: true,
  debug: true,
  frameless: false,
};

const webview1 = new WebView({
  title: "Multiple deno_webview example",
  url: `data:${contentType},
    <html>
    <body>
      <h1>1</h1>
    </body>
    </html>
    `,
  ...sharedOptions,
});

const webview2 = new WebView({
  title: "Multiple deno_webview example",
  url: `data:${contentType},
    <html>
    <body>
      <h1>2</h1>
    </body>
    </html>
    `,
  ...sharedOptions,
});

await Promise.all([webview1.run(), webview2.run()]);
Enter fullscreen mode Exit fullscreen mode

Deno 桌面应用程序

永远/PM2

ForeverPM2都是 CLI 工具,用于确保给定脚本作为守护进程持续运行。与 Forever 不同,PM2 功能更完善,并且还可以用作负载均衡器。两者在 Node 中都非常有用,但我们可以在 Deno 中使用它们吗?

Forever 仅适用于 Node,因此无法使用。另一方面,使用 PM2 我们可以使用解释器。

PM2 徽标

➜ pm2 start app.ts --interpreter="deno" --interpreter-args="run --allow-net" 
Enter fullscreen mode Exit fullscreen mode

快递/ Koa

ExpressKoa是最著名的 Node 框架。它们以其强大的路由系统和 HTTP 辅助功能(重定向、缓存等)而闻名。我们可以在 Deno 中使用它们吗?答案是不能……但也有一些替代方案。



Express 和 Koa 徽标

Http(标准库)

Deno 自身的 STD 库已经涵盖了 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);
Enter fullscreen mode Exit fullscreen mode

但是,声明路由的方式不太吸引人。所以,让我们看看其他一些替代方案。

Oak(第三方库)

目前最优雅的解决方案之一,深受 Koa 启发。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 });
Enter fullscreen mode Exit fullscreen mode

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 });
Enter fullscreen mode Exit fullscreen mode

Deno-express(第三方库)

可能是与 Express Framework 最相似的替代品。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}`);
Enter fullscreen mode Exit fullscreen mode

MongoDB

MongoDB是一个具有极高可扩展性和灵活性的文档数据库。它在 JavaScript 生态系统中被广泛使用,许多技术栈(例如 MEAN 和 MERN)都使用它。它非常受欢迎。



MongoDB 徽标

是的,我们可以将 MongoDB 与 Deno 结合使用。为此,我们可以使用此驱动程序:https://github.com/manyuanrong/deno_mongo

import { init, MongoClient } from "https://deno.land/x/mongo@v0.6.0/mod.ts";

// Initialize the plugin
await init();

const client = new MongoClient();
client.connectWithUri("mongodb://localhost:27017");

const db = client.database("test");
const users = db.collection("users");

// insert
const insertId = await users.insertOne({
  username: "user1",
  password: "pass1"
});

// findOne
const user1 = await users.findOne({ _id: insertId });

// find
const users = await users.find({ username: { $ne: null } });

// aggregation
const docs = await users.aggregation([
  { $match: { username: "many" } },
  { $group: { _id: "$username", total: { $sum: 1 } } }
]);

// updateOne
const { matchedCount, modifiedCount, upsertedId } = await users.updateOne(
  username: { $ne: null },
  { $set: { username: "USERNAME" } }
);

// deleteOne
const deleteCount = await users.deleteOne({ _id: insertId });
Enter fullscreen mode Exit fullscreen mode

PostgresSQL

PostgresSQL 徽标

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

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();
Enter fullscreen mode Exit fullscreen mode

MySQL/MariaDB

MySQL 和 MariaDB 徽标

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

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 }
Enter fullscreen mode Exit fullscreen mode

Redis

Redis 徽标

Redis是最著名的缓存数据库,它也有适用于 Deno 的驱动程序。

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");
Enter fullscreen mode Exit fullscreen mode

Nodemon

Nodemon 徽标

Nodemon在开发环境中用于监控文件的任何更改,并自动重启服务器。这使得 Node 开发更加轻松愉快,无需手动停止并重启服务器即可查看应用的更改。它可以在 Deno 中使用吗?

抱歉,你不能......但仍然有一个替代方案:Denon。

deno run我们可以像执行脚本一样使用 Denon 。

➜ denon server.ts
Enter fullscreen mode Exit fullscreen mode

杰斯特、茉莉、艾娃……

Jasmine、Jest、Ava、Mocha 徽标

Node.js 生态系统中有很多测试运行器可供选择。然而,目前还没有统一的官方方法来测试 Node.js 代码。

在 Deno 中,有一个官方的方法,你可以使用测试标准库。

import { assertStrictEq } from 'https://deno.land/std/testing/asserts.ts'

Deno.test('My first test', async () => {
  assertStrictEq(true, false)
})
Enter fullscreen mode Exit fullscreen mode

运行测试:

➜  deno test
Enter fullscreen mode Exit fullscreen mode

Webpack、Parcel、Rollup……

Webpack、Parcel、Rollup 徽标

Deno 的优势之一是我们可以将 ES 模块与 TypeScript 一起使用,而无需使用WebpackParcelRollup等捆绑器。

但是,您可能想知道,如果给定一个文件树,我们是否可以将所有内容捆绑到一个文件中,以便在 Web 上运行它。

是的,有可能。我们可以用 Deno 的 CLI 来实现。因此,不需要第三方打包工具。

➜ deno bundle myLib.ts myLib.bundle.js
Enter fullscreen mode Exit fullscreen mode

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

<script type="module">
  import * as myLib from "myLib.bundle.js";
</script>
Enter fullscreen mode Exit fullscreen mode

Prettier

更漂亮的标志

在过去的几年里,Prettier在 JavaScript 生态系统中变得相当知名,因为有了它,您不必担心格式化文件。

事实是,它仍然可以在 Deno 上使用,但失去了意义,因为 Deno 有自己的格式化程序。

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

➜  deno fmt
Enter fullscreen mode Exit fullscreen mode

NPM 脚本

Npm 脚本徽标

有了 Deno, 就package.json不复存在了。我真正怀念的事情之一就是在 中声明的脚本package.json

一个简单的解决方案是使用makefile并用 执行它make。但是,如果你不懂 npm 语法,那么有一个适用于 Deno 的 npm 样式的脚本运行器:

您可以使用脚本定义一个文件:

# scripts.yaml
scripts:
  start: deno run --allow-net server.ts
  test: deno test --allow-net server_test.ts
Enter fullscreen mode Exit fullscreen mode

执行:

➜  vr run <SCRIPT>
Enter fullscreen mode Exit fullscreen mode

另一种替代品是denox,与 Velociraptor 非常相似。

没关系

版本语义

Nvm是一个用于管理多个活动 Node 版本的 CLI,可以根据您的项目轻松升级或降级版本。

nvmDeno 中的等价物dvm

➜  dvm use 1.0.0
Enter fullscreen mode Exit fullscreen mode

NPX

近年来,Npxdeno install https://url-of-module.ts非常流行,它可以用来执行 npm 包而无需安装它们。现在,由于 Deno 是一个独立的生态系统,许多项目将不再存在于 npm 中。那么,我们该如何才能在无需安装的情况下执行 Deno 模块呢?

与我们运行项目的方式相同,我们放置的是模块的 URL,而不是文件:

➜  deno run https://deno.land/std/examples/welcome.ts
Enter fullscreen mode Exit fullscreen mode

如你所见,我们不仅要记住模块的名称,还要记住整个 URL,这让它使用起来有点困难。另一方面,它提供了更大的灵活性,因为我们可以运行任何文件,而不仅仅是像在 like 中指定的二进制package.json文件npx

在 Docker 上运行

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"]
Enter fullscreen mode Exit fullscreen mode

构建并运行它:

➜  docker build -t app . && docker run -it --init -p 1993:1993 app
Enter fullscreen mode Exit fullscreen mode

仓库:https://github.com/hayd/deno-docker

作为 lambda 运行

Lambda 符号

要将 Deno 用作 lambda,Deno STD 库中有一个模块。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
  };
}
Enter fullscreen mode Exit fullscreen mode

有趣的参考:

结论

我肯定我忘记了一些 Node 主题及其 Deno 替代方案,如果您有任何遗漏,需要我解释,请告诉我。希望本文能帮助您打破 Deno 的僵局。

要探索可以与 Deno 一起使用的所有库:

文章来源:https://dev.to/aralroca/from-node-to-deno-5gpn
PREV
学习 Deno:聊天应用
NEXT
我是如何用最酷的技术构建我的全栈投资组合网站的