受副热带高压的影响
2024年12月23日,手把手教你从Node.js快速迁移到Deno2020-06-01 15:22·Echa攻城狮作者 | Aral Roca译者 | 王强策划 | 蔡芳芳转发链接:https://mp.weixin./s/8P9_XOJQik3X7JOX7VGyjw前言上周我发表了几篇文章,介绍了 Deno 以及如何使用 Deno 和 Preact 创建一个聊天应用。文章发布后收到了很多询问,大多数问题关心的是:如何使用新的 Deno 生态系统来做那些我们原来用 Node 做的事情。我试着收集了一些 Node 中最常用的主题,并找出了它们在 Deno 中的替代方案。首先我想明确一点,在 Deno 中我们可以使用许多现有的 Node.js 模块。由于许多模块都是可重用的,因此用不着为所有的事情都寻找替代选项。你可以访问 pika.dev 查找可以在 Deno 中使用的模块。Deno相关知识优质文章:「干货」通俗易懂的Deno 入门教程「干货」了不起的 Deno 实战教程「干货」Deno TCP Echo Server 是怎么运行的?「实践」Deno bytes 模块全解析手把手教你Node.js和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_webviewimport { 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,
1
`, ...sharedOptions,});const webview2 = new WebView({ title: "Multiple deno_webview example", url: `data:text/html,
2
`, ...sharedOptions,});await Promise.all([webview1.run(), webview2.run()]);Forever/PM2Forever 和 PM2 是用来确保作为守护程序的指定脚本可以持续运行的 CLI 工具。与 Forever 不同,PM2 功能更完善,还可以用作负载均衡器。两者在 Node 中都很好用,但是我们可以在 Deno 中使用它们吗?Forever 只适用于 Node,因此在 Deno 中是用不了的。但我们可以使用 PM2 运行费 Node 脚本,因此可以将其用于 Deno。创建一个 app.sh 文件#!/bin/bashdeno run -A myCode.ts然后? pm2 start ./app.shExpress/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/oakimport { 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/abcimport { 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-expressimport * 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_mongoimport { 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-postgresimport { 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_mysqlimport { 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 }RedisRedis 是最出名的缓存数据库,它也有 Deno 的驱动程序:https://github.com/keroxp/deno-redisimport { 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");NodemonNodemon 被用来在开发环境中监视文件的任何更改,发现更改后会自动重新启动服务器。它显著提升了 Node 的开发体验,开发人员无需再手动停止和重启服务器以查看应用更改。它可以在 Deno 中使用吗?抱歉,你不能,但是也有另一种选择:Denon,Denon 的用法和使用 deno run 执行脚本一样。https://github.com/eliassjogreen/denon? denon server.tsJest、Jasmine、Ava……在 Node.js 生态系统中,测试运行器有很多选项可用。但官方并没有提供一种测试 Node.js 代码的方法。在 Deno 中有一种官方方法,你可以使用 testing 标准库:https://deno.land/std/testingimport { assertStrictEq } from 'https://deno.land/std/testing/asserts.ts'Deno.test('My first test', async () => { assertStrictEq(true, false)})要运行测试:? deno testWebpack、Parcel、Rollup……Deno 的优势之一是我们可以搭配使用 ES 模块与 TypeScript,而无需诸如 Webpack、Parcel 或 Rollup 之类的打包器。但你可能想要知道:如果给定了一棵文件树,我们是否可以制作一个包,将所有内容放到一个文件中以在 Web 环境中运行呢?答案是肯定的。我们可以使用 Deno 的 CLI 做到这一点。这样就无需第三方打包器了。? deno bundle myLib.ts myLib.bundle.js现在可以将其加载到浏览器中:Prettier在过去的几年中,Prettier 在 JavaScript 生态系统中大受欢迎,因为有了它,你就不用再操心格式化文件的事情了。其实它也能用在 Deno 上,但这没什么意义,因为 Deno 有自己的格式化程序。你可以使用以下命令格式化文件:? deno fmtNPM 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