跳到主要内容
Deno 2.4 已发布,带来 deno bundle、字节/文本导入、OTel 稳定版等功能
了解更多
Announcing native npm support on Deno Deploy

宣布 Deno Deploy 原生支持 npm

Deno Deploy 让构建和托管任何 JavaScript 应用、函数或 API 服务器变得轻而易举。Deno 简洁强大的 API 让编程更快、更简单——包括Web 标准 APINode.js 内置模块,以及转化为一流 JavaScript API 的基本云服务,例如Deno KV现已开放 Beta 版)。您的应用程序在全球 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 和测试运行器),以及提供丰富 IDE 编辑体验的Deno 语言服务器

无需打包步骤

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

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

我们对 Deno Deploy 的短反馈周期和即时部署引以为豪。这也延伸到了 npm 支持。您可以使用 npm: 指定符在本地开发,并通过我们无缝的 GitHub 集成部署到 Deno Deploy,从 git push 到站点上线只需几秒钟。

因为我们不对您的代码或您导入的任何 npm 模块进行转译、打包和 polyfill,所以不会出现这些步骤引入的问题。这意味着在本地运行的代码将在 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 上运行。例如,内部使用 httpaws-sdk 包就可以正常运行。

在 Playground 中亲自尝试 →

/** @jsx jsx */
/** @jsxFrag Fragment */
import { Hono } from "https://deno.land/x/hono@v3.5.8/mod.ts";
import { Fragment, jsx } from "https://deno.land/x/hono@v3.5.8/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 支持和开放 Beta 版的 Deno KV,您的 JavaScript 应用程序可以访问超过两百万个模块,解锁更多功能,提供高效直观的开发体验(例如一行代码连接到全球分布式数据库),并提供与您的 Git 工作流无缝衔接的快速全球部署流程。与此同时,为您的最终用户提供最低延迟和高可用性。

我们正在努力添加重要实用功能,以进一步简化复杂且可用于生产的应用程序的构建和托管。我们将有许多令人兴奋的公告,敬请期待!

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