整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

聊一聊 React 之 Next.js 11 的 一些新特性

本文中,我们将深入研究其中一些对用户和开发人员体验都产生影响的更新。让我们开始吧!

一致性

就其核心而言,一致性是一组原则或编码指南,它将一些决策责任从开发人员手中夺走。通过设置默认值和提供指导方针,更容易实现预期结果并防止常见错误。

根据Next.js 团队的说法,“一致性是一个系统,它提供精心设计的解决方案和规则以支持最佳加载和 Core Web Vitals”。

Next.js 11 中的新一致性原则可以分为三个方面:

1. 强默认值

框架必须在其核心建立某些设计模式,使开发人员难以做错事。

2. 可操作的规则

尽管有很强的默认设置,但有时开发人员有责任在两条潜在路径之间进行选择。一组可操作的规则将使应用程序更容易遵守强大的性能标准,同时仍然允许足够的自定义级别。

3. 创作时间

创作时间更重视功能开发周期而非生产后的性能。在代码提交之前必须考虑性能,而不是在产品发布后将其视为基于分析的指标。

强制执行创作时间原则的最简单方法之一是通过 linting 规则。因此,Next.js 11 开箱即用的支持 ESLint。

要获得这些功能的好处,您必须通过运行以下代码升级到 Next.js 的最新版本:

npm i next@latest react@latest react-dom@latest

通过运行以下代码启用 linting:

npx next lint 

一旦我们升级我们的版本并启用 ESLint,我们将开始收到警告,这些警告会促使我们朝着行业最佳实践的方向发展,帮助我们的应用程序遵守一致性准则。

脚本优化

许多网站都包含第三方脚本以启用分析和广告。

加载脚本的顺序对页面性能有巨大影响,尤其是在处理网页上的多个外部脚本时。如果管理不当,脚本会严重降低用户体验。

Next.js 引入了一个脚本组件,它的strategy属性可以处理很多这些问题。

让我们来测试一下!一个明显的变化是我们不再需要在标签中包装原生 HTML 脚本next/head标签:

import Head from 'next/head'
function Home() {
 return (
    <>
      <Head>
        <script async src="https://polyfill.io/v3/polyfill.min.js?features=WebAnimations" />
      </Head>
    </>
  )
} 

相反,我们可以直接使用原生 HTML 脚本标签,如下所示:

import Script from 'next/script'
function Home() {
  return (
    <>
      <Script src="https://polyfill.io/v3/polyfill.min.js?features=WebAnimations" />
    </>
  )
} 

在这个例子中,我们建议使用该beforeInteractive策略加载我们的 polyfill 。让我们改变策略,看看它如何影响加载脚本!

beforeInteractive

脚本在服务器端被注入到 HTML 中,并在捆绑的 JavaScript 运行之前在浏览器上运行。使用下面的代码块,我们看到获取 polyfill 的网络调用是在网络选项卡中的其他所有内容之前进行的:

<Script src="https://polyfill.io/v3/polyfill.min.js?features=WebAnimations" 
`strategy="beforeInteractive" /> 

afterInteractive

如果我们将策略更改为afterInteractive,脚本将在页面变为交互式后执行。网络请求位于网络选项卡中的页面底部,它优先考虑更重要的任务。

lazyOnload

将策略更改为lazyOnload告诉 Next.js 在空闲时间加载脚本。获取 polyfill 的网络请求进一步向下移动到页面底部;没有其他延迟加载的脚本,如下面的屏幕截图所示。

onLoad 属性

除了上面的自定义之外,如果我们想在脚本加载后执行一些代码,我们可以使用onLoad脚本标签的prop。该onLoad属性可确保上面的脚本加载,使功能使用脚本的功能和变量没有崩溃:

<Script
  id="my-script"
src="https://polyfill.io/v3/polyfill.min.js?features=WebAnimations"
  onLoad={() => {
    // this executes after the script is loaded
  }}
/> 

图像改进

Next.js 11 包括对next/image组件的增强,例如减少布局偏移,为最终用户提供更流畅的体验。

静态图像的尺寸检测

以前,要使用Image组件渲染图像,必须使用heightwidth道具。这些道具允许 Next.js 识别图像的大小并渲染占位符,防止布局偏移和混乱的用户界面:

<Image
  alt="Fixing"
  src="/fixing.png"
  layout="intrinsic"
  width={700}
  height={475}
/> 

Next.js 11 提供了对srcprop 的支持,可以使用import关键字来应用。如果以这种方式导入源,则不需要单独指定heightwidth道具:

import source from '../public/fixing.png'
<Image
  alt="Fixing"
  src={source}
  layout="intrinsic"
/> 

图像占位符

在 Next.js 11 中,该next/image组件支持一个新的占位符属性,该属性设置valueblur较慢的连接。该next/image组件将在加载原始图像时显示模糊的低分辨率图像:

<Image
  alt="Fixing"
  src={source}
  layout="intrinsic"
  placeholder="blur"
/> 

在最终加载原始图像之前,模糊图像将显示两到三秒钟。

此外,Next.js 11 提供了通过Image标签提供自定义占位符的选项,可以使用blurDataURLprop 显示。提供给此道具的值可以使用诸如blurha.sh 之类的应用程序生成。

Webpack 5 默认支持

Webpack 5 支持在 10.2 版中宣布,适用于所有文件中没有自定义 webpack 配置的 Next.js 项目next.config.js。自定义 webpack 配置如下所示:

module.exports = {
  webpack: (config, { buildId, dev, isServer, defaultLoaders, webpack }) => {
    return config; // return the modified config
  },
} 

从版本 11 开始,无论自定义配置如何,webpack 5 都是所有 Next.js 应用程序的默认构建工具。webpack 5 附带的所有以下优化将可用于新建项目。

改进的磁盘缓存

我们知道我们可以使用命令触发构建next build。但是,如果我们为项目触发的两个连续构建之间几乎没有变化怎么办?

Webpack 5 只允许有条件地重新编译已更改的文件。性能得到了提高,因为我们不会冗余处理尚未更改的块。

改进的快速刷新

有了 webpack 5,Next.js 11 将快速刷新识别为一项特殊任务,并以更高的优先级执行它,从而在每次保存任何代码更改时都能更快地刷新。

长期 asset 缓存

使用 webpack 5,build命令的构建过程是确定性的。如果代码段没有更改,则后续构建时生成的哈希不会更改,这意味着在浏览器中散列的文件可以在更长的时间内重复使用。

改进的 tree shaking

Webpack 5 提供了tree shaking commonJS模块的功能,从包中删除未使用的代码。

从 Create React App 迁移

由于社区的要求,Vercel 团队推出了该@next/codemod工具,该工具支持 React 和 Next.js 项目之间的兼容性。

我们可以运行该工具,为它提供一个使用 Create React App 脚本生成的项目,并将其转换为 Next.js 项目。让我们试试吧!

首先,使用以下命令创建一个 React 应用程序:

npx create-react-app cra-demo 

现在,我们已经初始化了一个新的 React 项目,我们可以使用以下命令运行我们的项目:

npm run start 

你会看到熟悉的 React 屏幕:

接下来,运行脚本以从 Create React App 迁移到 Next.js 项目:

npx @next/codemod cra-to-next cra-demo 

我们可以看到脚本对存储库进行了一些更改以将其移植到 Next.js。这些变化包括:

  • 对脚本的更改 package.json
  • 添加pages文件夹,这是 Next.js 存储库的主要功能
  • 更改通过创建_app.js文件导入 CSS 的方式
  • 创建next.config.js文件并填充它

Babel优化

Next.js 11 为 webpack 提供了全新的Babel 加载器实现,其中包括一个内存配置缓存层,通过 10.1 和 10.2 版本的改进进一步缩短了启动时间。

Next.js Live

Vercel 的团队使用了多种下一代前端技术,如 serviceWorker、WebAssembly 和 ES 模块,以在浏览器内部提供协作环境。使用 Next.js Live 功能,开发人员和设计人员只需共享 URL 即可协作。Live 功能目前正在抢先体验下运行。

结论

很明显,这些升级构成了有史以来最突出的 Next.js 版本之一!

对内核进行了一些更改以减少启动时间,例如 Babel 优化,以及促使开发人员采用经过验证的解决方案的一致性建议。其他改进是加载图像和脚本,使用户体验无缝。此外,我们现在可以使用 Live 功能改进协作。

由于这些以及更多原因,Next.js 11 版本看起来很有希望并且值得升级。试一试,让我们知道你在评论中的想法!

istory API

HTML5 History API无疑是现代网站的发展方向,因为它完成了手头的任务,同时还提供了额外的功能。您可以根据需求使用history.pushState()history.replaceState()在浏览器中修改URL:

// 当前 URL: https://my-website.com/page_a

// 修改后的URL
const nextURL = 'https://my-website.com/page_b';	
const nextTitle = 'My new page title';
const nextState = { additionalInformation: 'Updated the URL with JS' };

// 这将在浏览器的历史记录中创建一个新条目,而无需重新加载
window.history.pushState(nextState, nextTitle, nextURL);

// 这将替换浏览器历史记录中的当前条目,而无需重新加载
window.history.replaceState(nextState, nextTitle, nextURL);

两个方法的参数相同,允许您传递自定义的可序列化状态对象作为第一个参数、自定义标题(尽管大多数浏览器会忽略此参数)以及要在浏览器历史记录中添加/替换的URL。请记住,History API只允许相同的源URL,因此您无法导航到完全不同的网站


Location API

旧的Location API不是该作业的最佳方案,因为它会重新加载页面,但是它仍然允许您修改当前URL,并且在使用旧浏览器时可能会很有用。您可以使用window.location.hreflocation.assign()location.replace()修改URL:

// 当前 URL: https://my-website.com/page_a

// 修改后的URL
const nextURL = 'https://my-website.com/page_b';

// 这将在浏览器的历史记录中创建一个新条目,然后重新加载
window.location.href = nextURL;

// 这将替换浏览器历史记录中的当前条目,然后重新加载
window.location.assign(nextURL);

// 这将替换浏览器历史记录中的当前条目,然后重新加载
window.location.replace(nextURL);

如上所述,这三个选项都将导致页面重新加载,这可能是不希望的。此外,与使用History API不同,您只能设置URL,而不需要任何附加参数。最后,Location API不会限制您使用相同的源URL,但使用不同的源URL,这可能会导致安全问题。

日分享最新,最流行的软件开发知识与最新行业趋势,希望大家能够一键三连,多多支持,跪求关注,点赞,留言。

如今,当我们想要基于 React 创建一个新的 Web 项目时,我们有许多不同的框架选择。

如今,当我们想要基于 React 创建一个新的 Web 项目时,我们有许多不同的框架选择。作为一名开发人员,您会发现自己很难知道应该选择哪一种,或者哪一种最适合您的需求。

您可能知道最常用的框架之一是Next.js,Netflix、Twitch 或 Uber 等公司通常使用它。它被认为是增长最快的 React 框架之一。

其他人很难与 Next.js 竞争,因为它涵盖了三种不同的页面渲染策略,但自 2021 年 11 月以来,我们似乎有了一个新的、新鲜的、强大的框架,称为Remix。

对不起盖茨比,我没有忘记你,我喜欢你在生成静态站点时的工作方式。

为什么需要 Next.js 或 Remix 而不是普通的 React
也许你没有;这取决于。重点是了解 React 应用程序如何工作,您可能会发现哪些问题以及 Next.js 或 Remix 等框架如何解决这些问题。

关于 React 的要点是您可以制作单页应用程序 (SPA),其中仅使用一个 HTML 文件来呈现所有网页,并且路由保留在客户端。但这到底是什么意思呢?

当发出初始请求时,浏览器会立即收到一个包含所有应用程序的 HTML 框页面。
没有预渲染的内容。
当用户导航触发时,JavaScript 仅替换那些与请求的路由相关的组件和内容,但 HTML 文件保持不变。
简而言之,浏览器负责管理应加载哪个 JavaScript 文件以呈现当前页面。换句话说,客户端呈现 (CSR)。

CSR 可以非常花哨并且有助于创建不需要关心 SEO、缓存或缓慢的初始渲染的应用程序。

SSlow Initial Render——当用户第一次登陆时,可能需要很长时间才能加载第一个内容页面。这意味着让他们得到一个空白页面,直到 JavaScript 加载并呈现所有内容。
SEO——因为内容只有一个 HTML 页面,所以很难让搜索引擎和社交媒体机器人对内容进行索引。
缓存问题——HTML 结构无法缓存,因为它在第一次渲染时不可用。
在这一点上,您可能认为 SPA 是魔鬼,但想想这么多公司使用的所有内部应用程序或他们销售的应用程序产品。

当您想利用 SPA 的工作方式而又不失去我之前提到的三点时,Next.js或Remix就会出现。优点是网站可以在发送到客户端之前在服务器端呈现。

SSR vs SSG vs ISR
我已经解释了 CSR 的含义和工作原理,现在轮到我来谈谈其他花哨的页面呈现策略。

Next.js是一个强大的选项,因为它提供了三个开箱即用的不同选项,而Remix完全依赖于 SSR(目前)。但这些策略究竟是如何运作的呢?

服务器端渲染 (SSR)
当一个页面被请求时,它在发送到客户端之前在服务器上完全呈现。对于那些拥有大量动态数据和内容的网站来说,这是一个很好的选择。

静态站点生成 (SSG)
该策略在构建期间按路由生成所有页面。出现提示时,只会将请求的页面发送给客户端。也就是说,这构建了一个典型的静态网站。

对于那些几乎没有或没有动态数据且页面不多的静态网站来说,它可能是一个合适的选择。数据中的每个更改都会触发所有页面的重新生成。

增量静态再生 (ISR)
Next.js 提供了这个概念,是 SSR 和 SSG 的混合体。

它类似于 SSG,但您可以设置一个间隔时间,让您知道何时应该重新生成您的页面。适用于那些具有动态内容的静态站点。

Next.js 的强项在于它允许您在每个页面上的这三个选项之间切换,因此您可以让每个选项遵循不同的策略。

所以也许你会问自己,“如果 Next.js 只适用于 SSR,我为什么要用 Remix 替换它”。答案很简单,如今,应用程序和网站往往具有动态数据,并且很少有适合 SSG 或 ISR 场景的示例。

考虑到这一点,Remix 提供了一个较低级别的 API。例如,它公开了 Request 对象,因此您可以在呈现页面之前轻松修改标头,而在 Next.js 中,您需要中间件来实现它。

路由
这两个框架都使用基于文件的路由系统来呈现页面。

每个页面都保留在不同的文件中。
每个页面都与基于其文件名的路由相关联。
最后,每个页面都会呈现一个 React 组件。
混音中的路由
您将在 中添加每个路由/app/routes,并且在其中创建的每个文件或文件夹都将被视为一个路由。

混音路由 1
此外,您会发现一个文件,/app/root.jsx,其中是“根路由”,是整个应用程序的布局。它包含 <html>、<head> 和 <body> 标签,以及其他与 Remix 相关的内容。

Next.js 中的路由
您将在 中添加每条路线/pages,它的工作方式与 Remix 完全相同。

nextjs 路由 1
在这种情况下,您可能有也可能没有pages/_app.jsand pages/_document.js。其中App用于初始化页面,文档包含标签。

Next.js 默认使用它们,无需额外配置。但是,如果您需要自定义它们,您可以创建这两个文件,以这种方式覆盖默认文件。

索引路线
他们都使用相同的系统来呈现容器路线。

Next.js 示例:

pages/index.js=> /(根页面)
pages/posts/index.js或者pages/posts.js=>/posts
混音示例:

routes/index.js=> /(根页面)
routes/posts/index.js或者routes/posts.js=>/posts
嵌套路由
Remix 建立在 React Router 之上,由同一个团队开发,所以你可以想象在嵌套路由方面谁是赢家。
其背后的想法是创建一个活动路由来挂载包含多个嵌套路由的布局,以便每个路由管理自己的内容。

如果我必须用 React 语言来解释它,我会告诉你想象每个嵌套路由都是一个组件,并且根据 URL 路径,它们可以被挂载和卸载。

为实现这一点,Remix 使用了<Outlet />React-router 组件。它用在父路由上,告诉它们只要被触发就渲染子路由元素。
请记住,所有这些嵌套路由都已预加载到服务器上,因此几乎每个加载状态都可以删除。听起来不像是 SSR 和 SPA 的混合体?

另一方面,Next.js 确实支持嵌套路由,但它们作为单独的页面工作。如果您想实现类似于 Remix 所做的事情,您可能应该自定义您的_app.js.

两者的示例:

routes/posts/news/index.js=>/posts/news
动态路线
它们通过基于动态的 URL 参数呈现不同的内容来工作,但它使用单个路由文件。
在这种情况下,两个框架都支持此功能,但使用不同的命名约定。

Next.js 示例:

pages/posts/[postId].js=>/posts/some-post-slug
pages/products/[category]/[productId].js=>/products/keyboards/some-keyboard-slug或/products/headphones/some-headphone-slug
它有自己的钩子,useRouter将为您提供那些动态参数(postId、类别、productId)的当前值。

混音示例:

/app/routes/posts/$postId.js=>/posts/some-post-slug
/app/routes/products/$category/$productId.js=>/products/keyboards/some-keyboard-slug或/products/headphones/some-headphone-slug
您可以使用useParamReact Router hook 来访问这些动态参数。

需要加载文件的路由怎么办?
想象一下,您需要您的网站包含典型文件robots.txt和sitemap.xml文件。

在 Next.js 和 Remix 中,您都可以将它们添加到 /public 目录。但是 Remix 可以让你通过路由系统实现它,只需创建一个/app/routes/[sitemap.xml].js或/app/routes/[robots.txt].js

数据加载
这两个框架都是服务器端的,因此每个框架都有不同的系统来获取数据和手动调用 API。

对于 Next.js,您可以在两个选项中进行选择,具体取决于您要构建的页面类型。

getStaticProps(SSG,如果设置了重新验证间隔,则为 ISR)——它在构建时获取数据并将其数据作为页面的组件属性提供。
export async function getStaticProps( {params} ) {
const productList = await getProductList()

return {
props: {
productList,
slug: params.slug
}
}
}


getServerSideProps (SSR) — 它在运行时在服务器端获取数据,并将返回的数据作为页面的组件道具提供。
export async function getStaticProps( {params} ) {
const productList = await getProductList()

return {
props: {
productList,
slug: params.slug
}
}
}


/**
* Here you would have your own getStaticProps/getServerSideProps functions
* depending on what system you choose.
**/

const PageName = (props)=> {
const { productList } = props
// Here you could render the requested data
return (<div>
<pre> {JSON.stringify(productList, null, 4)} </pre>
</div>)
}


Remix 使用不同的方式加载数据;

它为您提供了一个loader在每个路由文件上使用的函数,该文件将在运行时在服务器端运行。
在页面组件本身上,您将能够使用useLoaderData挂钩来收集这些数据。
/**
* Here you would have your own getStaticProps/getServerSideProps functions
* depending on what system you choose.
**/
export const async loader = ( {params} ) => {
const productList = await getProductList()
return {
productList,
slug: params.slug
}
};

export default function PageName() {
const { productList } = useLoaderData();

// Here you could render the requested data
return (<div>
<pre> {JSON.stringify(productList, null, 4)} </pre>
</div>)
}


数据突变
Next.js 没有内置的方式来执行突变,你必须手动进行。
另一方面,Remix 创建了一个表单组件,并像使用浏览器的本机 HTML 表单元素一样使用它。如果您不输入任何操作 URL,它将对表单使用相同的路由。

如果方法是GET,loader将触发导出函数,如果方法是POST,action将触发定义在组件中的导出函数。

此外,您可以使用提供的 useTransition 挂钩根据请求状态管理应用程序的行为,而无需像往常一样手动管理它。

export const loader = async ({ params }) => {
// Each time this page receive a GET Request, this loader will be executed
const userData = await getSomeUserData(params.slug)

return {
userData // it contains the User Name
}
}

export const action = async ({ request }) => {
// Each time this page receive a POST Request, this loader will be executed
const form = await request.formData()
const content = form.get('content')

return redirect('/')
}

export default function App() {
const { name } = useLoaderData();

return (
<div>
<div>{`Hello there ${name}`}</div>

<Form method="POST">
<label htmlFor="content">
Content: <textarea name="content" />
</label>

<input type="submit" value="Add New" />
</Form>
</div>
)
}


造型
Next.js 带有开箱即用的内置 CSS 支持,因此您可以直接将其导入到 /pages/_app.js 所需的任何 style.css 文件中。

您还可以添加其他 CSS 框架,使用一些配置或插件很容易实现。

linksRemix 更喜欢通过提供组件和导出功能来专注于对 Web 标准更加友好的解决方案。

import styles from "./styles/app.css";

export function links() {
return [
{ rel: "stylesheet", href: styles },
{ rel: "stylesheet", href: 'https://.....' },
];
}

export default function App() {
return (
<html lang="en">
<head>
<Links />
</head>
<body>
<Outlet />
</body>
</html>
);
}


您可能认为仅仅加载一个样式表有点过分了,但是如果我告诉您可以在每个页面上单独使用它,让您仅在需要时加载特定样式/字体怎么办?

另外,在这里你可以使用其他的 CSS 框架,只需很少的配置,比如 Tailwindcss。

图像优化
Next.js 在这里获胜,因为它有自己的内置组件next/image,可以实现图像优化、延迟加载、大小控制和集成加载器。不幸的是,目前 Remix 没有任何图像优化支持。

搜索引擎优化
在本文的开头,我告诉过您这些框架背后的要点之一是解决 SPA 的 SEO 问题。

它们都有自己的内置机制来动态管理每个页面上应该使用哪些元数据,例如关键字、标题、描述等。

next/head在 Next.js 中,您可以通过将其导入页面/路由来使用其内置组件。

import Head from 'next/head'

export default function PostPage() {
return (
<div>
<Head>
<title>Post Page Title</title>
<meta name="description" content="Post Page Description" />
</Head>
<p>
All the metadata inside Head component will be injected into the
documents head
</p>
</div>
)
}


另一方面,Remix 为我们提供了一个meta导出函数,可以接收页面的请求数据以及 URL 参数。

export const meta = ({ data, params }) => {
charset: "utf-8",
viewport: "width=device-width,initial-scale=1",
title: `Post | ${data.title}`,
description: data.description,
};

export default function PostPage() {
return (
<div>
<p>
All the metadata returned on meta function will be injected into the
documents head
</p>
</div>
)
}


错误处理
Next.js 使您可以在捕获某些错误时定义自定义页面,例如 400 或 500 错误。但是除了路由或状态错误之外的任何其他错误都会导致页面中断。

Remix 让您尽情发挥想象力,这样您就可以覆盖和自定义您想要的每个错误。他们添加了错误边界,这是一种处理错误的独特概念——在 React v16 中引入。

您可以通过在您的甚至每个页面上使用CatchBoundary, 和ErrorBoundary导出的函数轻松地覆盖这些错误。root.tsx让我们添加一些视觉示例。

// Here you will catch any controlled error and will tell the framework what information should be shown
const CatchBoundary = () => {
let caught = useCatch();

switch (caught.status) {
case 401:
// Document is a custom React Component which contains <html>, <head>,<body>, etc
return (
<Document title={`${caught.status} ${caught.statusText}`}>
<h1>
{caught.status} {caught.statusText}
</h1>
</Document>
);

case 404:
return <PageNotFoundComponent />; // Yes, you can also use a React Component
default:
throw new Error(
`Unexpected caught response with status: ${caught.status}`
);
}
};

// Here you will have a more generic advise for when an uncontrolled error has been triggered
const ErrorBoundary = ( { error } ) => {
return (
<Document title="Uh-oh!">
<h1>App Error</h1>
<pre>{error.message}</pre>
<p>
Replace this UI with what you want users to see when your app throws
uncaught errors.
</p>
</Document>
);
};

export const loader: LoaderFunction = async ({ params }) => {
const post = await getPost(params.slug);

if (!post) {
throw new Response("Not Found", {
status: 404,
});
}

return json({ post });
};

export default function PostPage() {
const { post } = useLoaderData();
return (
<div>
<pre>
{JSON.stringify(post, null, 4)}
</pre>
</div>
)
}


部署
Next.js 很容易部署在任何支持 Node.js 的服务器上。它还集成了无服务器部署到 Vercel 的功能,Netlify 有自己的适配器,因此您可以轻松部署应用程序。

Remix 基于 Web Fetch API 而不是 Node.js 构建,因此它可以在 Vercel、Netlify、Architect(Node.js 服务器)以及 Cloudflare 等非 Node.js 环境中运行。

它还会在您开始项目时为您提供开箱即用的适配器,因此如果您知道要将项目部署到哪里,就可以直奔主题。

Remix 最重要的事情之一是它不再使用 Webpack。相反,它使用 Esbuild,它在捆绑和部署方面速度极快。

其他提及
每当您想选择 Next.js 或 Remix 时,还有其他要点需要考虑,但我想收集那些在我看来作为开发人员在开发项目时具有更大影响的因素。
但如果您想了解更多,这里有一些我在本文中没有谈到的事情的回顾。

实时重新加载。Next.js 使用热模块重新加载 (HMR) 并默认启用,而在 Remix 上,您必须在 root.tsx 上添加一个组件以强制您的应用程序在代码更改时重新加载。
Remix 支持 Cookie、会话和身份验证,而 Next.js 不支持——您必须使用外部库。
Next.js 内置了对字体和脚本优化的支持,而 Remix 则没有。
两者都让您开箱即用地使用 Typescript。
Remix 无需执行 JavaScript 即可完成其大部分功能,而 Next.js 则不会。
Remix 可以在嵌套路由中包含独立路由
两者都可以使用 Tailwindcss 快速工作,并有自己的指南来实现它。
Next.js 内置了对国际化路由的支持。
Next.js 对 AMP 具有开箱即用的支持,而 Remix 则没有。