你可能已经听过很多关于 Remix 这个最新框架的宣传。令人惊讶的是,它早在 2019 年就已启动,但最初仅作为订阅式付费框架提供。2021 年,创始人筹集了种子资金,并开源了该框架,允许用户免费开始使用 Remix。闸门打开了,每个人似乎都在谈论它,无论好坏。让我们深入研究 Remix 的一些基础知识。
Remix 是一个优先考虑服务器端(边缘)的 JavaScript 框架。它目前使用 React 作为前端,并优先在边缘进行服务器端渲染应用程序。平台可以获取服务器端代码并将其作为无服务器或边缘函数运行,这比传统服务器更便宜,并且更靠近您的用户。Remix 创始人喜欢称其为“中心堆栈”框架,因为它会根据运行它的平台调整服务器和客户端之间进行的请求和响应。
由于 Remix 需要服务器,让我们讨论一下如何部署它。Remix 本身不提供服务器——你需要自己提供服务器——允许它在任何 Node.js 或 Deno 环境中运行,包括 Netlify Edge 和 DigitalOcean 的 App Platform。Remix 本身是一个编译器,一个将平台请求转换为其运行平台的程序。此过程使用 esbuild 为服务器请求创建处理程序。它使用的 HTTP 处理程序基于 Web Fetch API,并通过调整它们以适应将要部署到的平台而在服务器上运行。
Remix 堆栈是预先配置了一些常用工具的项目。Remix 团队维护着三个官方堆栈,它们都以音乐类型命名。此外,还有许多社区 Remix 堆栈,包括 Netlify 模板团队创建的 K-Pop 堆栈。此堆栈功能强大,包括 Supabase 数据库和身份验证、Tailwind 用于样式设置、Cypress 端到端测试、Prettier 代码格式化、ESLint 代码检查和 TypeScript 静态类型检查。查看 Tara Manicsic 关于部署 K-Pop 堆栈的帖子。
即使 Remix 需要服务器,它仍然可以通过缓存路由来利用 Jamstack 的优势。静态站点或静态站点生成 (SSG) 是指您的所有内容都在构建时渲染,并在下一次重建之前保持静态。内容是预生成的,可以放在 CDN 上。这为最终用户提供了许多好处和快速的站点加载速度。但是,Remix 不像其他流行的 React 框架(包括 Next.js 和 Gatsby)那样进行典型的 SSG。为了获得 SSG 的一些好处,您可以使用 Remix headers 函数中的原生 Cache-Control HTTP 头来缓存特定路由,或者直接在 root.tsx 文件中缓存。
<code>[[headers]] for = "/build/*" [headers.values] "Cache-Control" = "public, max-age=31536000, s-maxage=31536000"</code>
然后在您需要的地方添加您的 headers 函数。这将缓存一小时:
<code>export function headers() { return { "Cache-Control": "public, s-maxage=360", }; };</code>
许多框架都依赖于基于文件系统的路由。这是一种使用指定文件夹来定义应用程序路由的技术。它们通常具有用于声明动态路由和端点的特殊语法。目前 Remix 与其他流行框架之间最大的区别在于能够使用嵌套路由。
每个 Remix 应用程序都从 root.tsx 文件开始。这是渲染整个应用程序基础的地方。您会在这里找到一些常见的 HTML 布局,例如 标签、
标签,然后是
标签以及渲染应用程序所需的组件。这里要指出的一点是
<script></script>
组件启用了网站上的 JavaScript;有些东西无需它也能工作,但并非所有东西都能工作。root.tsx 文件充当 routes 目录中所有内容的父布局,routes 中的所有内容都在 root.tsx 中 <outlet></outlet>
组件所在的位置进行渲染。这是 Remix 中嵌套路由的基础。#### 嵌套路由
Remix 不仅由 React Router 团队的一些成员创建,它还使用 React Router。事实上,他们正在将 Remix 的一些优点带回 React Router。Next.js 和 SvelteKit 的维护人员目前正在努力解决的一个复杂问题是嵌套路由。
嵌套路由与传统路由不同。传统路由会将用户带到新页面,而每个嵌套路由都是同一页面的一个单独部分。它允许通过将业务逻辑仅与需要它的文件相关联来分离关注点。Remix 能够处理仅限于嵌套路由所在页面部分的错误。页面上的其他路由仍然可用,并且损坏的路由可以提供与错误相关的上下文,而不会导致整个页面崩溃。
当 app/routes 中的根文件与将在基本文件中加载的文件目录同名时,Remix 会执行此操作。根文件通过使用 <outlet></outlet>
组件来告诉 Remix 在哪里加载其他路由,从而成为目录中文件的布局。
<outlet></outlet>
组件是 Remix 的一个信号,指示它应该在哪里为嵌套路由渲染内容。它放在 app/routes 目录根目录下的文件中,其名称与嵌套路由相同。以下代码位于 app/routes/about.tsx 文件中,并包含 app/routes/about 文件夹内文件的 outlet:
<code>import { Outlet } from "@remix-run/react"; export default function About() { return ( <div> <h1>I am the parent layout. I will be on any page inside of my named directory.</h1> {/* All of my children, the files in the named directory, will go here. */} <outlet></outlet> </div> ) }</code>
app/routes/ 目录中的任何文件都成为其名称 URL 的路由。还可以添加包含 index.tsx 文件的目录。
<code>app/ ├── routes/ │ │ │ └── blog | | ├── index.tsx ## The /blog route │ └── about.tsx ## The /about route │ ├── index.tsx ## The / or home route └── root.tsx</code>
如果路由的名称与目录相同,则命名文件将成为目录内文件的布局文件,并且布局文件需要一个 Outlet 组件来放置嵌套路由。
<code>app/ ├── routes/ │ │ │ └── about │ │ ├── index.tsx │ ├── about.tsx ## this is a layout for /about/index.tsx │ ├── index.tsx └── root.tsx</code>
还可以通过在布局文件名前添加双下划线 (__) 来创建布局。
<code>app/ ├── routes/ │ │ │ └── about │ │ ├── index.tsx │ ├── index.tsx │ ├── about.tsx │ ├── __blog.tsx ## this is also a layout └── root.tsx</code>
https://www.php.cn/link/232a03118725240918c5a4a0ab33e9b3 仍然会渲染 app/routes/about.tsx 文件,但也会在 app/routes/about.tsx 的标记中 <outlet></outlet>
组件所在的位置渲染 app/routes/about/index.tsx 中的内容。
动态路由是根据 url 中的信息而变化的路由。这可能是博客文章的名称或客户 ID,但无论是什么,添加到路由前面的 $ 语法都会向 Remix 发出信号,表明它是动态的。除了 $ 前缀外,名称无关紧要。
<code>app/ ├── routes/ │ │ │ └── about │ │ ├── $id.tsx │ │ ├── index.tsx │ ├── about.tsx ## this is a layout for /about/index.tsx │ ├── index.tsx └── root.tsx</code>
由于 Remix 在服务器上渲染所有数据,因此在 Remix 中看不到很多已成为 React 应用程序标准的内容,例如 useState() 和 useEffect() 钩子。由于数据已在服务器上进行了评估,因此对客户端状态的需求减少了。
使用哪种类型的服务器来获取数据也无关紧要。由于 Remix 位于请求和响应之间并对其进行适当的转换,因此您可以使用标准 Web Fetch API。Remix 在一个仅在服务器上运行的 loader 函数中执行此操作,并使用 useLoaderData() 钩子在组件中渲染数据。这是一个使用 Cat as a Service API 渲染随机猫图像的示例。
<code>import { Outlet, useLoaderData } from '@remix-run/react' export async function loader() { const response = await fetch('https://cataas.com/cat') const data = await response.json() return { data } } export default function AboutLayout() { const cat = useLoaderData<typeof loader>() return ( <div> <img alt="A random cat." src="%7B%60https://cataas.com/cat/%24%7Bcat.id%7D%60%7D"> <outlet></outlet> </div> ) }</typeof></code>
在动态路由中,以 $ 为前缀的路由需要能够访问 URL 参数以处理应该渲染的数据。loader 函数可以通过 params 参数访问这些参数。
<code>import { useLoaderData } from '@remix-run/react' import type { LoaderArgs } from '@remix-run/node' export async function loader({ params }: LoaderArgs) { return { params } } export default function AboutLayout() { const { params } = useLoaderData<typeof loader>() return <p>The url parameter is {params.tag}.</p> }</typeof></code>
Remix 还有一些其他辅助函数,可以为路由模块 API 中的普通 HTML 元素和属性添加额外功能。每个路由都可以定义自己类型的这些函数。
Action 函数允许您使用标准 web FormData API 向表单操作添加额外功能。
<code>export async function action({ request }) { const body = await request.formData(); const todo = await fakeCreateTodo({ title: body.get("title"), }); return redirect(`/todos/${todo.id}`); }</code>
任何 HTTP 标准标头都可以放在 headers 函数中。因为每个路由都可以有一个标头,为了避免与嵌套路由冲突,最深的路由——或具有最多正斜杠 (/) 的 URL——获胜。您还可以获取传递的标头,actionHeaders、loaderHeaders 或 parentHeaders
<code>export function headers({ actionHeaders, loaderHeaders, parentHeaders, }) { return { "Cache-Control": loaderHeaders.get("Cache-Control"), }; }</code>
此函数将设置 HTML 文档的元标记。默认情况下,在 root.tsx 文件中设置了一个,但可以为每个路由更新它们。
<code>export function meta() { return { title: "Your page title", description: "A new description for each route.", }; };</code>
HTML link 元素位于 HTML 文档的 标签中,它们导入 CSS 等。links 函数(不要与
<link>
组件混淆)允许您仅在需要它们的路由中导入内容。因此,例如,CSS 文件可以进行范围限定,并且仅在需要这些特定文件的路由中导入。link 元素作为对象数组从 links() 函数返回,可以是 link API 的 HtmlLinkDescriptor 或可以预取页面数据的 PageLinkDescriptor。
<code>export function links() { return [ // add a favicon { rel: "icon", href: "/favicon.png", type: "image/png", }, // add an external stylesheet { rel: "stylesheet", href: "https://example.com/styles.css", crossOrigin: "true", }, // add a local stylesheet, { rel: "stylesheet", href: stylesHref }, // prefetch a page's data { page: "/about/community" } ] }</code>
Remix 提供了一个组件来在应用程序的不同路由之间跳转,称为 <link>
。要获得客户端路由,请使用 <link to="">
组件而不是 <a href="">Name</a>
。<link>
组件还带有一个 prefetch 属性,默认情况下接受 none,如果 Remix 检测到用户将鼠标悬停或聚焦链接,则打算预取数据,或者渲染将立即获取路由的数据,一旦链接被渲染。
<code>import { Link } from "@remix-run/react"; export default function Nav() { return ( <nav> <link to="/">Home <link to="/about">About <link prefetch="intent" to="/about/community">Community </nav> ); }</code>
现在您已经了解了 Remix 的基础知识,您准备好开始实际构建应用程序了吗?Remix 提供了一个笑话应用程序和一个博客教程来帮助您开始实施这些基本知识。您也可以从头开始创建一个全新的 Remix 应用程序。或者,如果您准备深入研究,请尝试使用 K-Pop 堆栈。我非常享受使用 Remix 的时光,并且喜欢它对 Web 标准的关注以及回归基础。现在轮到您开始创建了!
以上是混音的基础的详细内容。更多信息请关注PHP中文网其他相关文章!