跳到主要内容
Announcing native npm support on Deno Deploy

宣布 Deno Deploy 原生支持 npm

Deno Deploy 让构建和托管任何 JavaScript 应用程序、函数或 API 服务器变得轻松容易。使用 Deno 简单而强大的 API,编程变得更快更简单——Web 标准 APINode.js 内置模块,以及转化为一流 JavaScript API 的基本云服务,例如 Deno KV现已公开测试版)。您的应用程序在全球 35 个区域靠近您的用户运行,确保最低的延迟和高可用性。

今天,我们很高兴地宣布 Deno Deploy 现在原生支持通过 npm: 说明符运行 npm 模块。这意味着您现在可以使用 npm 模块在边缘托管 Node.js 应用程序,而无需构建步骤。

以下是在 Deno Deploy 上运行 Express 应用程序的示例

// Import express and instantiate it
import express from "npm:express@4";
const app = express();

// Register a route
app.get("/", (req, res) => {
  res.send("Hello World!");
});

// Run the server!
app.listen(3000);

在 Playground 中亲自尝试 →

Deno Deploy 是第一个原生支持 Node.js 内置模块和 npm 模块的基于隔离的无服务器平台。这为 JavaScript 开发人员开启了一个全新的可能性世界——现在即使是您的 Node.js 应用程序也可以在全球范围内托管,并具有最低的延迟、高可用性和即时部署

导入和使用超过 200 万个 npm 模块与 Deno 的其余部分无缝集成:一流的 TypeScript 支持内置工具(如格式化程序、linter 和测试运行器)以及Deno 语言服务器,它在您的 IDE 中提供丰富的编辑器体验。

无需捆绑步骤

Deno 中的 NPM 和 Node 支持是原生的——没有发生转译、捆绑步骤或 polyfill 注入。Deno Deploy 原生理解 Node.js API,并且本质上知道如何加载和执行 NPM 模块。

这为您带来了两个主要好处:更好的开发者体验更好的兼容性

我们为 Deno Deploy 的短反馈循环和即时部署而自豪。这也扩展到 npm 支持。您可以使用 npm: 说明符在本地进行开发,并通过我们无缝的 GitHub 集成部署到 Deno Deploy,从 git push 到实时站点只需几秒钟。

因为我们不转译、捆绑和 polyfill 您的代码或您导入的任何 npm 模块,所以没有像这样的步骤来引入问题。这意味着在本地工作的代码将在 Deno Deploy 上工作,反之亦然。

由于没有捆绑或源映射,如果出现任何问题,您的 Deno Deploy 堆栈跟踪和日志会显示与您在本地看到的文件名和行号相匹配的文件名和行号——不再需要在难以理解的缩小和捆绑的代码中挖掘。

示例和用例

以下是您可以使用 Deno Deploy 上的 npm 包构建的一些示例。

Fastify

Fastify 是在 Node.js 中构建 API 服务器和 Web 应用程序的流行解决方案。借助 Deno Deploy 上的 npm 说明符支持,它现在也可以在边缘运行的 Web 应用程序中使用。

在 Playground 中亲自尝试 →

// Import the framework and instantiate it
import Fastify from "npm:fastify@4";
const fastify = Fastify();

// Declare a route
fastify.get("/", async function handler(request, reply) {
  return "Hello World!";
});

// Run the server!
await fastify.listen({ hostname: "localhost", port: 3000 });

Deno.serve + OpenAI

NPM 支持不限于 Web 框架。您可以使用它通过从 NPM 导入包来增强任何现有的 Deno 应用程序。例如,您可以使用 OpenAI SDK 通过最先进的 AI 完成来增强您的应用程序。

在 Playground 中亲自尝试 →

import OpenAI from "npm:openai@4";

const openai = new OpenAI({ apiKey: Deno.env.get("OPENAI_API_KEY") });

Deno.serve(async (req: Request) => {
  const completion = await openai.chat.completions.create({
    model: "gpt-3.5-turbo",
    messages: [{ role: "user", content: "Tell me a programmer joke" }],
  });
  const joke = completion.choices[0].message.content;
  return new Response(joke);
});

加密 API

加密和解密是 npm 上最受欢迎的模块类别之一。这是一个使用 crypto-js 的示例,它是 npm 上的顶级软件包之一。

在 Playground 中亲自尝试 →

import CryptoJS from "npm:crypto-js@4";

Deno.serve((_req: Request) => {
  // Encrypt
  const ciphertext = CryptoJS.AES.encrypt("my message", "secret key 123")
    .toString();

  // Decrypt
  const bytes = CryptoJS.AES.decrypt(ciphertext, "secret key 123");
  const originalText = bytes.toString(CryptoJS.enc.Utf8);

  return new Response(originalText);
});

兼容性

Deno Deploy 支持所有 47 个 Node.js 内置模块,例如 fspathhttp。您可以像在 Node.js 中一样,直接通过 node: 说明符导入它们。

任何依赖这些 API 的 npm 包都可以在 Deno Deploy 上工作。例如,aws-sdk 包在内部使用 http,它可以正常工作

在 Playground 中亲自尝试 →

/** @jsx jsx */
/** @jsxFrag Fragment */
import { Hono } from "https://deno.land/x/[email protected]/mod.ts";
import { Fragment, jsx } from "https://deno.land/x/[email protected]/middleware.ts";
import { DynamoDBClient } from "npm:@aws-sdk/client-dynamodb@3";
import {
  DynamoDBDocumentClient,
  ExecuteStatementCommand,
} from "npm:@aws-sdk/lib-dynamodb";
import { fromEnv } from "npm:@aws-sdk/credential-providers@3";

// Init DynamoDB client
const client = new DynamoDBClient({
  region: "us-east-2",
  credentials: fromEnv(),
});
const docClient = DynamoDBDocumentClient.from(client);

// Init Hono app
const app = new Hono();

// List TODOs
app.get("/", async (c) => {
  const command = new ExecuteStatementCommand({
    Statement: "SELECT * FROM Todos WHERE complete = ?",
    Parameters: [false],
    ConsistentRead: true,
  });

  const response = await docClient.send(command);
  console.log(response);
  return c.html(
    <html>
      <body style={{ margin: "10px auto", maxWidth: "400px" }}>
        <h1>TODOs</h1>
        <form action="/" method="POST">
          <input type="text" name="text" />
          <button
            type="submit"
            style={{
              display: "inline-block",
              marginLeft: "5px",
            }}
          >
            Add Item
          </button>
        </form>
        {response.Items.map((item) => {
          return (
            <div style={{ margin: "5px 0" }}>
              {item.text}
            </div>
          );
        })}
      </body>
    </html>,
  );
});

// Add a TODO item
app.post("/", async (c) => {
  const body = await c.req.parseBody();

  const command = new ExecuteStatementCommand({
    Statement: `INSERT INTO Todos value {'text':?, 'complete':?}`,
    Parameters: [body.text, false],
  });

  try {
    const response = await docClient.send(command);
    console.log(response);
  } catch (e) {
    console.error(e);
  }
  return c.redirect("/");
});

Deno.serve(app.fetch);

虽然我们目前的 Node.js 兼容性非常好,但仍有一些 Node.js API 不受支持,或者尚未与 Node.js 实现完全兼容。

还有一些 npm 包在 Deno Deploy 上无法工作。任何依赖 NodeAPI(Node 的本机插件层)的包都无法与 Deno Deploy 等无服务器系统一起使用,因为存在沙箱限制。相同的安全沙箱也阻止了一些 Node.js API 工作,例如 child_processvm

如果您在 Deno Deploy 上使用特定的 npm 模块时遇到任何问题,请在此处打开一个 issue

下一步是什么

借助 npm 支持和公开测试版中的 Deno KV,您的 JavaScript 应用程序可以访问超过 200 万个模块并解锁更多功能,提供高效且直观的开发体验(例如,在一行代码中连接到全球分布式数据库),并提供快速的全球部署流程,该流程可以直接连接到您的 git 工作流程。所有这一切都为您的最终用户提供最低的延迟和高可用性。

我们正在努力添加重要的实用功能,以进一步简化构建和托管复杂的、可用于生产的应用程序。我们有很多激动人心的公告即将发布,敬请关注!

不要错过任何更新!关注我们的 Twitter加入我们的 Discord,并订阅我们的 YouTube 频道