跳至主要内容
Deno 2 终于来了 🎉️
了解更多
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 到上线只需几秒钟。

由于我们不会转译、捆绑和填充您的代码或您导入的任何 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 模块时遇到任何问题,请在此处打开一个问题

接下来会发生什么

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

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

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