宣布 Deno Deploy 原生支持 npm
Deno Deploy 让构建和托管任何 JavaScript 应用、函数或 API 服务器变得轻而易举。Deno 简洁强大的 API 让编程更快、更简单——包括Web 标准 API、Node.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);
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 应用程序。
// 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 补全功能。
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 上最热门的包之一。
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 内置模块,例如 fs
、path
和 http
。您可以像在 Node.js 中一样,通过 node:
指定符直接导入它们。
任何依赖这些 API 的 npm 包都将在 Deno Deploy 上运行。例如,内部使用 http
的 aws-sdk
包就可以正常运行。
/** @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_process
和 vm
。
如果您在使用 Deno Deploy 上的特定 npm 模块时遇到任何问题,请在此处提交问题。
下一步
有了 npm 支持和开放 Beta 版的 Deno KV,您的 JavaScript 应用程序可以访问超过两百万个模块,解锁更多功能,提供高效直观的开发体验(例如一行代码连接到全球分布式数据库),并提供与您的 Git 工作流无缝衔接的快速全球部署流程。与此同时,为您的最终用户提供最低延迟和高可用性。
我们正在努力添加重要实用功能,以进一步简化复杂且可用于生产的应用程序的构建和托管。我们将有许多令人兴奋的公告,敬请期待!
不要错过任何更新!关注我们的 Twitter,加入我们的 Discord,并订阅我们的 YouTube 频道。