2017 年 9 月,Cloudflare推出了 Cloudflare Workers,让 JavaScript 能够在他们的边缘网络上运行。这意味着您的代码将在全球一百多个地点的整个边缘网络上部署,大约需要 30 秒。这项技术使您能够专注于编写贴近用户(无论他们身在何处,延迟约为 50 毫秒)的应用程序。
Worker 的运行时与 Node.js 或浏览器不同,它使用 Google Chrome 开发的 JavaScript 引擎 V8 执行代码。到目前为止,您可以在其平台上运行的只是在到达服务器之前在边缘运行的小脚本,以提高性能或根据请求头添加一些逻辑,例如。
2020 年 11 月,在开发 Nuxt 3 时,我们大胆尝试在边缘运行时/V8 隔离环境上运行生产环境中的 Nuxt。
当使用 CloudFlare Workers 等平台时,它能够在全球范围内以约 50 毫秒的速度服务器渲染页面,而无需处理服务器、负载均衡器和缓存,费用约为每百万次请求 0.3 美元。截至今天,新的平台正在出现,如 Deno Deploy,允许在 V8 隔离环境上运行应用程序。
为了使 Nuxt 在 Worker 中运行,我们不得不重写 Nuxt 的一些部分,使其能够环境无关(在 Node.js、浏览器或 V8 中运行)。
我们从服务器开始,创建了unjs/h3:一个为高性能和可移植性而构建的最小 HTTP 框架。它取代了我们在 Nuxt 2 中使用的Connect,但与其兼容,因此您可以继续使用 Connect/Express 中间件。在 Worker 中,对于每个传入请求,它启动生产环境中的 Nuxt,将请求发送给它并返回响应。
在 Nuxt 2 中,在内存中启动生产服务器(也称为冷启动)的持续时间约为 300 毫秒,因为我们必须加载服务器和应用程序的所有依赖项才能处理请求。
通过在 h3 上工作,我们决定对附加到服务器的每个处理程序进行代码分割,并仅在请求时才延迟加载它们。当您启动 Nuxt 3 时,我们只将 h3 和相应的处理程序加载到内存中。当请求到来时,我们加载与路由对应的处理程序并执行它。
通过采用这种方法,我们将冷启动时间从约 300 毫秒缩短到约 2 毫秒。
我们面临的另一个挑战是在边缘运行 Nuxt:生产打包大小。这包括服务器、Vue 应用程序和 Node.js 依赖项的总和。Cloudflare Workers 目前对 Worker 大小有 1MB(免费计划)和 5MB(每月 5 美元计划)的限制。
为了实现这一点,我们创建了unjs/nitro,我们的服务器引擎。当运行 nuxt build 命令时,它会打包您的整个项目并将所有依赖项包含到最终输出中。它使用Rollup等等vercel/nft来仅跟踪 node_modules 中使用的代码,以删除不必要的代码。一个基本的 Nuxt 3 应用程序生成的总输出大小约为 700KB gzip。
最后,为了在开发环境(Node.js)和 Cloudflare 生产环境(边缘运行时)之间提供相同的开发体验,我们创建了unjs/unenv:一个通过模拟或为已知依赖项添加 polyfills 将 JavaScript 代码转换为可在任何地方运行(平台无关)的库。
在 Nuxt,我们相信您应该有选择最适合您的托管提供商的自由。
这就是为什么您可以在
上部署具有边缘渲染的 Nuxt 应用程序。我们还支持许多其他部署提供商,包括静态托管或传统的 Node.js 无服务器和服务器主机。
现在 Nuxt 已经在边缘运行时上运行,我们可以做的不仅仅是渲染一个 Vue 应用程序。多亏了服务器目录,创建一个 API 路由只需要一个 TypeScript 文件。
要添加 /api/hello 路由,请创建一个 server/api/hello.ts 文件
export default defineEventHandler((event) => {
return {
hello: 'world'
}
})
您现在可以在页面和组件中通用地调用此 API
<script setup>
const { data } = await useFetch('/api/hello')
</script>
<template>
<pre>{{ data }}</pre>
</template>
当我们创建 useFetch 和 $fetch 时需要注意的一个重要事项是,在服务器端渲染期间,如果您调用 API 路由,它将模拟请求并直接调用函数代码:避免 HTTP 请求并减少页面渲染时间。
在开发体验方面,您会注意到,当创建服务器文件时,Nuxt 服务器会持续运行,而无需重新构建 Vue 应用程序。这是因为 Nuxt 3 在创建 API 和服务器路由时支持热模块替换 (HMR)。
此外,通过利用 drizzle-orm 等对象关系映射 (ORM),开发人员可以连接边缘和无服务器数据库,例如drizzle-orm,开发人员可以连接边缘和无服务器数据库,例如D1, Turso, Neon, Planetscale等等。
我创建了Atidone,一个开源演示,展示了一个具有身份验证和数据库的全栈应用程序在边缘运行。源代码可在 GitHub 上以 MIT 许可证获取,地址为atinux/atidone.
我们对边缘渲染及其带来的可能性感到兴奋。Nuxt 团队迫不及待地想看到您在此基础上构建什么!
欢迎加入我们的Discord 服务器或在 Twitter 上提及@nuxt_js分享您的作品。