写点什么

从 Node 到 Deno

用户头像
寇云
关注
发布于: 2020 年 05 月 24 日
从 Node 到 Deno

原文地址: 《From Node to Deno

上周我发表了一篇关于 Deno 的文章: 如何用 Deno 和 Preact 创建一个聊天应用。很多疑问接踵而至。期中大部分都是如何用 Done 来做 Node 之前所做的事情。

所以我尝试整理一些 Node 常见问题的 Deno 替代方案。这非必要,很多模块可以重用。可以访问 pika.dev来寻找在 Deno 中使用的模块。

收集列表如何下:

  • Electron

  • Forever / PM2

  • Express / Koa

  • MongoDB

  • PostgresSQL

  • MySQL / MariaDB

  • Redis

  • Nodemon

  • Jest, Jasmine, Ava...

  • Webpack, Parcel, Rollup...

  • Prettier

  • NPM Scripts

  • Nvm

  • Npx

  • Run on a Docker

  • Run as a lambda

  • Conclusion

Electron

Electron 使用 Chromium 作为界面来运行 Web 环境。可以通过 Node.js + Electron 创建桌面应用程序。Deno 替代方案么?



现在 Electron 还远远不能在 Deno 下运行。我们必须寻找替代方案。因为 Deno 是用 Rust 制作的,所以我们可以使用 web-view rust bindings 来运行桌面应用。

这样一来,我们可以使用原生操作系统的 webview 来运行我们想要的 webview。

回购: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,所以使用它是不可行的。另一方面,用 PM2 我们可以运行非 Node 脚本,所以我们还是可以在 Deno 中使用它。



创建一个app.sh文件

#!/bin/bashdeno run -A myCode.ts
复制代码

 pm2 start ./app.sh
复制代码



Express / Koa

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



Http(标准库)

Deno 自己的 STD 库已经涵盖了ExpressKoa功能。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);
复制代码

但是,STD 库的方式并不是很吸引人。所以,我们再来看看一些备选方案。

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

Abc (第三方库)

类似于 Oakhttps://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(第三方 lib)

也许是最类似于 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}`);
复制代码

MongoDB

MongoDB 是一个文档数据库,具有巨大的可扩展性和灵活性。在 JavaScript 生态系统中已经被广泛使用,有很多像MEANMERN这样的堆栈都在使用它。它是非常受欢迎的。



我们可以使用 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 });
复制代码

PostgresSQL



与 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



MongoDBPostgresSQL一样,还有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。+

https://github.com/eliassjogreen/denon

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

➜ denon server.ts
复制代码

Jest, Jasmine, Ava...



Node.js的生态系统中,有很多替代性的测试方法。然而,目前还没有一种官方正式的方法来测试Node.js代码。

在 Deno 中,有一种官方方法,您可以使用测试std库。

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

Webpack, Parcel, Rollup...



Deno 的优势之一是我们可以将ESmodulesTypeScript一起使用,而无需诸如WebpackParcelRollup之类的工具。

然而,可能你会想,如果给定一个文件的树,我们是否可以打一个 js 包,把所有的东西都放在一个文件里,让它在 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 语法,有一个 npm 风格的脚本运行器,用于 Deno。

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 中,dvm相当于nvm

https://github.com/axetroy/dvm

➜  dvm use 1.0.0
复制代码

Npx

NPX在近几年非常流行,可以不用安装就可以执行 npm 包。现在很多项目都不会在 npm 中存在,因为 Deno 是一个独立的生态系统。那么,我们如何用 deno install https://url-of-module.ts,不用安装就能执行 Deno 模块呢?

就像我们运行项目一样,我们在运行项目时,我们把模块的URL代替了文件。

➜  deno run https://deno.land/std/examples/welcome.ts
复制代码

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

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

Repo: https://github.com/hayd/deno-docker

Run as a 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 };}
复制代码

参考

小结

我肯定我会忘记了一些 Node 主题以及它们的 Deno 替代方案,如果有什么遗漏的地方需要我解释,请告诉我。希望这篇文章能帮助你打破 Deno 的僵局。

要探索你可以使用 Deno 的所有库。


发布于: 2020 年 05 月 24 日阅读数: 95
用户头像

寇云

关注

前端工程师,远程工作者 2012.06.12 加入

还未添加个人简介

评论

发布
暂无评论
从 Node 到 Deno