從 Node 到 Deno

做者:Aral Roca

翻譯:瘋狂的技術宅html

原文:https://aralroca.com/blog/fro...前端

未經容許嚴禁轉載node

我收集了一些 Node 中最經常使用的主題,並尋找 Deno 的替代方案。首先我想說明,許多當前的 Node.js 模塊均可以均可以用在 Deno 中。因爲許多模塊都是可重用的,因此沒有必要爲全部方法去尋找替代方案。你能夠訪問pika.dev 查找能夠在 Deno 中使用的模塊。mysql

本文將涵蓋如下內容:webpack

Electron

經過 Node.js,咱們可使用 Electron 建立桌面程序。 Electron 使用 Chromium 做爲接口來運行 Web 環境。可是 Electron 能夠在 Deno 中使用嗎?有其餘選擇嗎?git

Electron logo

好吧,如今 Electron 還不能在 Deno 下執行,必須尋找替代方案。因爲 Deno 是用 Rust 寫的,因此能夠用web-view rust 綁定 在 Deno 中運行桌面程序。程序員

這樣,咱們可使用本機操做系統的 webview 視圖來運行任意 webview。github

Repo: https://github.com/eliassjogr...web

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()]);

Deno desktop app

Forever / PM2

ForeverPM2是 CLI 工具,可使給定腳本做爲守護程序連續運行。與 Forever 不一樣,PM2 更完整,還能夠用做負載均衡器。二者在 Node.js 中都很是有用,可是咱們能夠在 Deno 中使用嗎?面試

Forever 僅能用於 Node,不過咱們能夠藉助 PM2 運行非 Node.js 腳本,因此能夠將其用於 Deno。

PM2 logo

建立一個 app.sh 文件

#!/bin/bash
deno run -A myCode.ts

而後

➜ pm2 start ./app.sh

用 PM2 運行 Deno

Express / Koa

ExpressKoa 是最知名的 Node 框架。他們以其強大的路由系統和 HTTP 輔助器(重定向、緩存等)而聞名。能夠在 Deno中使用它們嗎?答案是否...可是有一些替代方法。

Express and Koa logo

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 啓發,這是目前最優雅的解決方案之一。 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 Framework 最類似的替代方案。 https://github.com/NMathar/de...

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 logo

因此能夠將 MongoDB 與 Deno 結合使用。可使用這個驅動程序:https://github.com/manyuanron...

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 });

PostgresSQL

PostgresSQL logo

像 MongoDB 同樣,也有 PostgresSQL 的驅動:https://github.com/buildondat...

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

MySQL 和 MariaDB logo

與 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 }

Redis

Redis logo

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");

Nodemon

Nodemon logo

Nodemon 用於在開發環境中用於監視文件中的更改,並自動從新啓動服務器。這使 Node 開發更加有趣,而無需手動重啓服務器來查看應用的更改。它能夠用在 Deno 中嗎?

抱歉,不能夠...可是有另一種選擇:Denon。

能夠像使用 deno run 同樣用 Denon 來執行腳本。

➜ denon server.ts

Jest, Jasmine, Ava...

Jasmine, Jest, Ava, Mocha logos

在 Node.js 生態中,有許多測試用的工具。可是官方並無提供測試 Node.js 代碼的方法。

在 Deno中,有一種官方的方法,能夠用測試標準庫。

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

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

這樣運行測試:

➜  deno test

Webpack, Parcel, Rollup...

Webpack, Parcel, Rollup logos

Deno 的一個優點是無需打包器(例如 WebpackParcelRollup)就可使 ESmodules 與 TypeScript 在一塊兒工做。

可是若是給定一個文件樹,咱們是否能夠打成一個包,把全部內容放到一個文件中並在網絡上運行它呢?

固然能夠。能夠用 Deno 的 CLI 作到這一點,不須要第三方打包程序。

➜ deno bundle myLib.ts myLib.bundle.js

而後就能夠加載到瀏覽器中了:

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

Prettier

Prettier logo

在過去的幾年中,Prettier 在 JavaScript 生態系統中已廣爲人知,正是由於有它,你沒必要再去擔憂格式化文件的麻煩。

實際上它仍然能夠在 Deno 上使用,可是這失去了意義,由於 Deno 有本身的格式化程序。

能夠用如下命令格式化文件:

➜  deno fmt

NPM Scripts

Npm scripts logo

在 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

執行:

➜  vr run <SCRIPT>

另外一種選擇是 denox,與 Velociraptor 很是類似。

Nvm

Version semantics

Nvm 是一個用於管理多個活動 Node 版本的 CLI,能夠根據你的項目輕鬆升級或降級版本。

在 Deno 中 nvm 的替代物是 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,這樣用起來很困難。可是另外一方面,它提供了更多的靈活性,由於咱們能夠運行任何文件,而不只僅是像 npx 這樣在 package.json 中指定的文件。

在Docker 中運行

Docker logo

要在 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-...

用於亞馬遜 lambda 運算

Lambda symbol

要將 Deno 用於 AWS 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 中的庫:


本文首發微信公衆號:前端先鋒

歡迎掃描二維碼關注公衆號,天天都給你推送新鮮的前端技術文章

歡迎掃描二維碼關注公衆號,天天都給你推送新鮮的前端技術文章

歡迎繼續閱讀本專欄其它高贊文章:


相關文章
相關標籤/搜索