Next.js vs Remix - 开发者的困境

开发 前端
Next.js 是最流行的用于服务器端渲染的 React 框架之一。它已经存在相当长的时间了,并且提供了开发者所需的所有功能,提供了出色的开发体验。

React 生态系统是一个繁荣的景观,充满了承诺革新网络开发的框架。今天,我们将深入探讨两个流行的竞争者:Next.js 和 Remix。

Next.js 是最流行的用于服务器端渲染的 React 框架之一。它已经存在相当长的时间了,并且提供了开发者所需的所有功能,提供了出色的开发体验。

Remix 是一个较新的参与者,由 React Router 的创始人创建。它倡导全栈开发方法,并引入了几个创新特性。随着 Remix 在 2022 年的开源推出,开发者开始思考哪个框架更适合他们的应用。两者都拥有令人印象深刻的特性和充满激情的社区,但哪一个应该成为我们下一个项目的首选呢?

让我们分析它们的优势和劣势,以帮助我们选择优胜者。

1. 路由

Next.js

Next.js 有两种不同的路由器:App Router 和 Pages Router。App Router 是一个较新的路由器,允许我们使用 React 的最新功能,比如 Server Components 和 Streaming。Pages Router 是原始的 Next.js 路由器,它允许我们构建服务器端渲染的 React 应用程序,并继续支持用于较旧的 Next.js 应用程序。

对于应用程序路由,Next.js 13 使用基于目录的路由,其中任何在 /app 下的文件称为 page.tsx 的文件都会被构建为路由。应用目录中的文件夹可以包含用于布局的 layout.tsx,用于公开访问该路由的 page.tsx,用于定义加载状态的 loading.tsx,以及用于错误处理的 error.tsx。要创建嵌套路由,我们可以相互嵌套文件夹。

图片图片

路由

来源:Next.js 文档

文件夹结构

来源:Next.js 文档来源:Next.js 文档

Remix

Remix v2 使用基于平面文件的路由系统。在我们的 /app/routes 文件夹中,我们可以通过添加新组件来创建新路由。使用文件名中的句点分隔符(.)来创建嵌套路由。例如,如果我们想在 Remix 应用中创建一个 /concerts/trending 路由,我们会添加一个名为 concerts.trending.tsx 的新文件。

来源:Next.js 文档来源:Next.js 文档

视角

现在,如果我们比较这两个框架的路由机制,它们都选择了基于文件系统的路由几乎相同的方向,感觉这是正确的方式前进。

Remix 似乎更直观,我们可以通过查看文件/布局来了解它表示的路由。但根据 Next.js,将相关的路由文件放在一个文件夹中也是有道理的,这有助于为每个路由段定义我们的加载/错误状态。

2.数据获取

Next.js

Next.js 提供了几种数据获取方法:

  • getServerSideProps:在每个请求期间在服务器上获取数据。这用于服务器端渲染(SSR),在客户端请求页面时获取数据。
  • getStaticProps:在构建时获取数据,生成带有预渲染内容的静态 HTML 页面。
  • getInitialProps:在服务器和客户端上都运行,用于初始渲染和客户端填充数据。这是一个遗留的 API。
  • fetch:Next.js 扩展了本地的 fetch Web API,允许我们配置每个在服务器上的 fetch 请求的缓存和重新验证行为。fetch 与 async/await 可以在 Server Component* Route Handlers 和 Server Actions 中使用。
async function getUsers() {
  const res = await fetch('https://jsonplaceholder.typicode.com/users')
  if (!res.ok) {
    throw new Error('Failed to fetch data')
  }
  return res.json()
}

export default async function Page() {
  const users = await getUsers()
  return (
    <div>
      <h1>Users</h1>
      {users.map((user) => (
        <div key={user.id}>{user.name}</div>
      ))}
    </div>
  );
}

Remix

在 Remix 中,数据是在加载器中获取的。每个路由可以定义一个加载器函数,在渲染时为路由提供相关数据。useLoaderData 将加载器的数据提供给组件。加载器仅在服务器上运行。

import { useLoaderData } from "@remix-run/react";

export const loader = async () => {
  const users = await getUsers();
  return json({ users });
};

export default function Page() {
  const users = useLoaderData<typeof loader>();
  return (
    <div>
      <h1>Users</h1>
      {users.map((user) => (
        <div key={user.id}>{user.name}</div>
      ))}
    </div>
  );
}

视角

Next.js 似乎非常适合具有静态和动态内容混合的应用程序,其中灵活性和定制性被优先考虑。Remix 的数据获取方法允许更精细地控制数据加载和依赖关系。

3.数据变更

处理变更时,我们通常通过向后端服务器发送 API 请求,然后更新本地状态以反映更改。

这两个框架的目标是通过将变更处理直接集成到其核心功能中来彻底改变变更处理方式。

Next.js

在 Next.js 13.4 之前,创建并在服务器上执行操作的唯一方法是创建 API 路由并更新状态。

Next.js 13.4 引入了服务器动作以处理数据变更,以简化开发者体验并改善用户体验。

使用 API 路由

export default function Page() {
  async function onSubmit(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
 
    const formData = new FormData(event.currentTarget);
    const response = await fetch('/api/submit', {
      method: 'POST',
      body: formData,
    });
 
    // Handle response if necessary
    const data = await response.json();
    // ...
  }
 
  return (
    <form onSubmit={onSubmit}>
      <input type="text" name="name" />
      <button type="submit">Submit</button>
    </form>
  );
}

使用 server actions

export default function Page() {
  async function create(formData: FormData) {
    'use server';
    const id = await createItem(formData);
  }
 
  return (
    <form action={create}>
      <input type="text" name="name" />
      <button type="submit">Submit</button>
    </form>
  );
}

来自 Next.js 14 表单和变更的示例

Remix

Remix 自动将 UI 与持久服务器状态同步。这发生在三个步骤中:

  • 路由加载器向 UI 提供数据
  • 表单提交数据到路由动作,更新持久状态
  • 页面上的加载器数据自动重新验证

图片图片

Remix 鼓励将用户采取行动的每个部分都保持为 HTML 表单。每当用户触发表单提交时,它调用动作。一旦动作执行完毕,Remix 通过浏览器的 fetch 请求重新获取该路由的所有加载器,并刷新 UI,确保 UI 始终与数据库同步。这被称为 Remix 的“全栈数据流”。

export async function loader({
  request,
}: LoaderFunctionArgs) {
  const user = await getUser(request);
  return json({
    displayName: user.displayName,
    email: user.email,
  });
}

export default function Component() {
  const user = useLoaderData<typeof loader>();
  return (
    <Form method="post" action="/account">
      <h1>Settings for {user.displayName}</h1>

      <input
        name="displayName"
        defaultValue={user.displayName}
      />
      <input name="email" defaultValue={user.email} />

      <button type="submit">Save</button>
    </Form>
  );
}

export async function action({
  request,
}: ActionFunctionArgs) {
  const formData = await request.formData();
  const user = await getUser(request);

  await updateUser(user.id, {
    email: formData.get("email"),
    displayName: formData.get("displayName"),
  });

  return json({ ok: true });
}

这个示例来自 Remix 路由动作文档。

视角

  • Next.js server actions 与 React 生态系统和 React 的 API 相关联。而 Remix 是基于 Web 平台的功能实现的,并且与 Web 的工作方式密切相关。
  • Next.js 的动作是以组件为中心的。而 Remix 的动作是以路由为中心的,因此不像组件那样易于组合。
  • 在 Next.js 中,我们需要手动告诉路径重新验证,而 Remix 则进行自动重新验证。这些是 Next.js 和 Remix 的权衡,我们可以决定我们可以接受哪些,我们需要哪些,并相应地做出决定。

4.错误处理

Next.js and Remix 提供了在我们的 Web 应用程序中优雅处理错误的机制。

Next.js

每个路由段中都有一个独立的 error.js 文件,用于渲染该路由段的错误状态。error.js 文件约定允许我们通过自动将路由段及其嵌套子元素包装在 React 错误边界中,优雅地处理嵌套路由中的意外运行时错误。它处理在服务器端或浏览器中可能发生的意外错误以及如 404 等预期错误。

Remix

要渲染路由段的错误状态,我们可以导出 ErrorBoundary。它处理在服务器端或浏览器中可能发生的意外错误以及如 404 等预期错误。

5.社区支持

Next.js

Next.js 是一个经过良好建立的框架,拥有 11.8 万颗 GitHub stars(撰写时)。它拥有庞大的社区和生态系统,在寻找解决问题、插件或集成时具有重大优势。

Remix

Remix 在撰写时拥有约 2.66 万颗 GitHub stars ,并且社区正在不断壮大。

观点

如果应用程序不太复杂且不需要社区的太多帮助,则更喜欢 Remix。如果一个应用程序需要一个拥有更广泛功能范围和庞大用户社区的框架,那么 Next.js 是一个不错的选择。

6.学习曲线

Next.js

相对较难学习。它提供了很多选择,如果开发者没有正确使用,低级别控制可能会显得过度。

Remix

相对较简单。它提供了一种做事情的方式,并将很多内容抽象出来。

7.部署

Next.js

在 Vercel 之外部署 Next.js 可能会有挑战,Vercel 是一个出色的平台,但如果我们的基础设施在 AWS 上,则可能并不理想。将 Next.js 托管在我们的 AWS 账户中可以更轻松地与我们的后端集成,并且通常比在 Vercel 上更具成本效益。虽然 Next.js 没有原生支持使用无服务器方式自托管,但我们可以将其作为 Node 应用程序运行。但是,这种方法可能无法提供与使用 Vercel 相同的好处。

幸运的是,有一个新的开源 Next.js 无服务器适配器 - OpenNext。该适配器接收 Next.js 构建输出并将其转换为可部署到任何函数即服务(FaaS)平台的包,使部署更加灵活。

Kent Dodds 在他的博客中表达了对部署的担忧。

Remix

Remix 被设计用于部署在支持 JavaScript 执行的任何平台上。这在很大程度上是由于它专注于标准。

8.价格

Next.js

对许多人来说,Vercel 的定价似乎是一个大问题。这可能是一个重要的考虑因素。

Remix

由于 Remix 可以在支持 JavaScript 执行的任何平台上部署,因此我们可以根据自己的选择自由选择平台。

9. 与大品牌的合作

Next.js

Next.js 由 Vercel 维护。React 团队与 Next.js 团队密切合作,推出新功能,如 React Server Components。

Remix

Remix 在 2022 年与 Shopify 合作!在 Shopify 的支持下,Remix 获得了来自一个成熟的商业领导者的长期支持和支持。

10. 公司

Next.js

  • Netflix Jobs
  • TikTok
  • Notion
  • Loom

详细列表可见 https://nextjs.org/showcase。

Remix

  • NASA
  • Docker - Docker Scout 是一个统一的容器安全解决方案,旨在帮助开发人员快速识别并修复所有存储库中的漏洞。
  • Shopify
  • react-admin - 用于提供私有 npm 注册表和企业用户仪表板。

详细列表可见 https://remix.run/showcase。

那么,谁会获得冠军呢?

获胜者是…

平局!Next.js 和 Remix 在不同领域都表现出色。

然而,“最佳”框架取决于项目的独特需求:

对于:大型项目、功能丰富的框架、以及拥有广泛支持的快速胜利 - Next.js 可能是冠军。

对于:性能关键项目、流畅的用户体验、解决较不复杂的问题以及愿意探索现代方法 - Remix 可能是冠军。

记住:

这两个框架都拥有活跃的社区和不断增长的资源池。亲身实验至关重要。使用每个框架构建小型项目,以发现个人适合性。团队的技能和偏好很重要。选择与团队开发风格相符的框架。

本文翻译自 https://blog.saeloun.com/2024/02/21/next.js-vs-remix。

责任编辑:武晓燕 来源: 编程界
相关推荐

2024-03-04 07:33:39

RemixReact框架

2021-11-26 10:29:24

jsRemix开源

2022-02-22 20:48:48

RemixNext.js框架

2023-09-17 12:21:21

RemixNext.js

2021-11-29 09:12:44

Next.js Remix 开源

2023-11-07 11:47:59

2012-06-13 01:23:30

开发者程序员

2011-04-27 09:34:18

Android盈利困境Android

2013-01-17 13:06:47

移动开发者营销推广

2023-09-04 08:20:00

2022-08-22 08:05:17

Fresh框架Remix

2024-02-05 11:55:41

Next.js开发URL

2015-08-21 10:11:32

游戏开发者辛苦困境

2020-12-14 11:40:27

Next.js SSRReact

2024-03-29 08:32:01

Node.jsNext.js组件

2023-09-20 10:14:03

Next.js前端

2021-01-04 09:06:18

Next.js设计技巧

2023-11-16 07:43:26

Next.jsReact

2023-11-23 10:45:13

Next.js 14Supabase

2023-10-27 15:13:12

Next.jsRust
点赞
收藏

51CTO技术栈公众号