CHANGELOG.md
本页内容

Remix 版本

本页面列出了 Remix 从 v2.0.0 开始的所有版本/版本说明。对于 v2 之前的版本,请参考 Github 版本页面

我们在这个文件中管理版本说明而不是 Github 版本页面的分页原因有两个

  • Github UI 中的分页意味着你无法轻松地搜索跨越大量版本的版本说明。
  • 分页的 Github 界面也会在列表视图中截断较长的版本说明,而不会有任何指示,你需要点击到详细视图才能看到完整的版本说明集。
目录

v2.14.0

日期:2024-11-08

次要更改

  • 弃用 SerializeFrom,支持泛型,因为它将在 React Router v7 中删除 (#10173)

  • @remix-run/eslint-config 中添加弃用警告 (#10174)

  • future.unstable_routeConfig 标志后面添加对 routes.ts 的支持,以帮助迁移到 React Router v7。 (#10107)

    基于配置的路由是 React Router v7 中的新默认值,通过应用目录中的 routes.ts 文件进行配置。Remix 中对 routes.ts 及其相关 API 的支持被设计为迁移路径,旨在帮助将 Remix 项目迁移到 React Router v7 时所需的更改次数降到最低。虽然在 @remix-run 范围内引入了一些新包,但这些新包的存在只是为了使 routes.ts 中的代码尽可能地与 React Router v7 中的等效代码相似。

    当启用 unstable_routeConfig 未来标志时,Remix 的内置文件系统路由将被禁用,您的项目将选择使用 React Router v7 的基于配置的路由。

    要在您的 vite.config.ts 文件中启用该标志:

    remix({
      future: {
        unstable_routeConfig: true,
      },
    });
    

    支持 Remix 内置文件系统路由的最小 routes.ts 文件如下所示:

    // app/routes.ts
    import { flatRoutes } from "@remix-run/fs-routes";
    import type { RouteConfig } from "@remix-run/route-config";
    
    export const routes: RouteConfig = flatRoutes();
    
  • 记录 v3 未来标志的弃用警告 (#10126)

    • json/defer 实用程序中添加 @deprecated 注释

补丁更改

  • 修复使用单次获取时 defaultShouldRevalidate 值 (#10139)
  • 更新对外部访问资源路由的警告,以涵盖 null 使用 (#10145)

更新的依赖项

按包分类的更改

完整变更日志: v2.13.1...v2.14.0

v2.13.1

日期: 2024-10-11

补丁更改

  • @remix-run/dev - 将 future.v3_optimizeDeps 恢复为 future.unstable_optimizeDeps,因为它不打算在 Remix v2 中稳定 (#10099)

完整变更日志: v2.13.0...v2.13.1

v2.13.0

日期: 2024-10-11

变更内容

稳定的 API

此版本稳定了一些“不稳定”的 API,为即将发布的 待定 React Router v7 做准备(有关更多信息,请参阅 这些 帖子

  • unstable_datadata(用于与单次获取一起使用)
  • unstable_flushSyncflushSync (useSubmitfetcher.loadfetcher.submit)
  • unstable_viewTransitionviewTransition (<Link><Form>useNavigateuseSubmit)
  • future.unstable_optimizeDepsfuture.v3_optimizeDeps (文档)
    • ⚠️ 此标志不打算在 Remix v2 中稳定,并在 2.13.1 中恢复为 future.unstable_optimizeDeps
  • future.unstable_lazyRouteDiscoveryfuture.v3_lazyRouteDiscovery (文档)
  • future.unstable_singleFetchfuture.v3_singleFetch (文档)

次要更改

  • 在 Remix 中稳定 React Router API (#9980)
    • 在内部采用稳定的 React Router API
      • 单次获取:unstable_dataStrategy -> dataStrategy
      • 延迟路由发现:unstable_patchRoutesOnNavigation -> patchRoutesOnNavigation
    • 稳定面向公众的 API
      • 单次获取:unstable_data() -> data()
      • unstable_viewTransition -> viewTransition (LinkFormnavigatesubmit)
      • unstable_flushSync> -> <Link viewTransition> (LinkFormnavigatesubmituseFetcher)
  • 稳定未来标志 (#10072#10092)
    • future.unstable_lazyRouteDiscovery -> future.v3_lazyRouteDiscovery
    • future.unstable_optimizeDeps -> future.v3_optimizeDeps
    • future.unstable_singleFetch -> future.v3_singleFetch

补丁更改

  • @remix-run/dev - 停止将 request.signal 作为 renderToReadableStreamsignal 传递以中止 cloudflare/deno 运行时的服务器渲染,因为到中止 request 的时候,中止渲染已经无用,因为 React 无法刷新未解析的边界 (#10047)
    • 这在一段时间内一直是错误的,但最近由于我们通过 remix vite:dev 运行时中止请求的方式出现 bug 而暴露出来,因为我们在成功渲染后错误地中止了请求 - 这导致我们中止了已完成的 React 渲染,并尝试关闭一个已经关闭的 ReadableStream
    • 这可能没有在任何生产场景中出现,因为 cloudflare/deno 生产运行时(正确地)不会在成功渲染时中止 request.signal
    • 内置的 entry.server 文件不再将 signal 传递给 renderToReadableStream,因为向默认行为添加基于超时的中止信号将构成重大更改
    • 用户可以通过自己的 entry.server 配置此中止行为(通过 remix reveal entry.server),并且模板 entry.server 文件已更新,其中包含新创建的 Remix 应用的示例方法
  • @remix-run/express - 修复中止 request.signal 的适配器逻辑,这样我们不会在成功请求的 close 事件中错误地中止 (#10046)
  • @remix-run/react - 修复在使用冒泡错误进行水合时布局路由中 clientLoader.hydrate 的 bug (#10063)

更新的依赖项

按包分类的更改

完整变更日志: v2.12.1...v2.13.0

v2.12.1

日期: 2024-09-19

补丁更改

  • @remix-run/dev - 在节点响应关闭时,在 vite dev 期间正确中止 request.signal (#9976)
  • @remix-run/dev - 使用 ?inline?inline-css?raw 的 CSS 导入不再在开发环境中被错误地注入到 SSR 中 (#9910)
  • @remix-run/server-runtime: 单次获取:当 loaderactionclientLoaderclientAction 返回裸对象、json(...)defer(...)unstable_data(...) 的混合时,修复类型。 (#9999)
  • @remix-run/node/@remix-run/cloudflare/@remix-run/deno - 单次获取:通过运行时包重新导出 interface Future,以便 pnpm 不抱怨 @remix-run/server-runtime 不是依赖项 (#9982)
    • 如果您已经选择使用单次获取,您可以在 vite.config.ts 中更改您的 单次获取类型增强,以增强 @remix-run/node(或 cloudflare/deno)而不是 @remix-run/server-runtime

按包分类的更改

完整变更日志: v2.12.0...v2.12.1

v2.12.0

日期: 2024-09-09

变更内容

用于自动依赖项优化的未来标志(不稳定)

您现在可以通过使用 future.unstable_optimizeDeps 未来标志选择在开发期间自动进行依赖项优化。有关详细信息,请查看 指南 > 依赖项优化 中的文档。对于以前解决此限制的用户,您不再需要显式地将路由添加到 Vite 的 optimizeDeps.entries 中,也不需要禁用 remix-dot-server 插件。

改进的单次获取类型安全性(不稳定)

  • 如果您之前已使用单次获取类型
    • tsconfig.json > compilerOptions > types 中删除 "@remix-run/react/future/single-fetch.d.ts" 覆盖
    • 从您的路由模块中删除 defineLoaderdefineActiondefineClientLoaderdefineClientAction 帮助程序
    • UIMatch_SingleFetch 类型帮助程序替换为原始的 UIMatch
    • MetaArgs_SingleFetch 类型帮助程序替换为原始的 MetaArgs

然后您就可以使用新的类型安全设置

// vite.config.ts

declare module "@remix-run/server-runtime" {
  interface Future {
    unstable_singleFetch: true; // 👈 enable _types_ for single-fetch
  }
}

export default defineConfig({
  plugins: [
    remix({
      future: {
        unstable_singleFetch: true, // 👈 enable single-fetch
      },
    }),
  ],
});

有关更多信息,请参阅我们文档中的 指南 > 单次获取

对单次获取重新验证行为的更新(不稳定)

使用单次获取,重复使用的路由现在默认情况下会在 GET 导航时重新验证。这样做旨在改进单次获取调用的缓存,同时允许用户选择更高级用例的先前行为。

有了这种新的行为,请求不再需要特殊的查询参数来开箱即用地进行细粒度的路由重新验证 - 例如,GET /a/b/c.data

有两个条件会触发细粒度重新验证,并且会将某些路由排除在单次获取调用之外

  • 如果路由通过 shouldRevalidate 选择退出重新验证
  • 如果路由定义了一个 clientLoader
    • 如果您从您的 clientLoader 中调用 serverLoader(),这将为该路由加载程序发出单独的 HTTP 调用 - 例如,GET /a/b/c.data?_routes=routes/a,用于 routes/a.tsx 中的 clientLoader

当一个或多个路由被排除在单次获取调用之外时,剩余具有加载程序的路由将作为查询参数包含在内。例如,当导航到 /a/b/c 时,如果 A 被排除,并且 root 路由和 routes/b 具有 loader,但 routes/c 没有,则单次获取请求将是 GET /a/b/c.data?_routes=root,routes/b

有关更多信息,请参阅我们文档中的 指南 > 单次获取

次要更改

  • @remix-run/dev - 用于自动依赖项优化的新的 future.unstable_optimizeDeps 标志 (#9921)

补丁更改

  • @remix-run/dev - 处理 modulepreload 清单生成中的循环依赖项 (#9917)
  • @remix-run/dev - 通过仅在 SSR 资产不存在于磁盘上时才将其移动到客户端构建目录来修复 dest already exists 构建错误 (#9901)
  • @remix-run/react - 澄清默认 HydrateFallback 控制台警告中的措辞 (#9899)
  • @remix-run/react - 删除最初为解决 React 17 水合问题而添加的水合 URL 检查,我们不再支持 React 17 (#9890)
    • 还原了最初在 Remix v1.18.0 中通过 #6409 添加的逻辑
    • 此更改旨在解决在 JS 加载时进行快速前进/后退历史导航时可能出现的问题,这会导致服务器匹配和客户端匹配不匹配:#1757
    • 此特定的水合问题会导致此 React v17 循环问题:#1678
    • 我们在 1.18.0 中添加的 URL 比较结果证明容易出现误报,这也会导致用户进入循环场景
    • Remix v2 将其最小 React 版本升级到 v18,消除了 v17 水合错误循环
    • React v18 像处理其他错误一样处理此水合错误,不会导致循环
    • 因此,我们可以删除我们的检查,从而避免它可能触发循环的误报场景
  • @remix-run/react - 延迟路由发现:对 /__manifest 查询参数进行排序以实现更好的缓存(#9888
  • @remix-run/react - 单次获取:改进类型安全(#9893
  • @remix-run/react - 单次获取:修复重新验证行为错误(#9938
  • @remix-run/server-runtime - 不要针对文档请求渲染或尝试包含 304 响应的正文(#9955
  • @remix-run/server-runtime - 单次获取:不要尝试将 turbo-stream 正文编码到 304 响应中(#9941
  • @remix-run/server-runtime - 单次获取:将 .data 请求的 内容类型更改为 text/x-script 以允许 Cloudflare 压缩(#9889

更新的依赖项

按包分类的更改

完整变更日志v2.11.2...v2.12.0

v2.11.2

日期:2024-08-15

补丁更改

  • @remix-run/react - 战争迷雾:由于 React Router 处理了 slug/splat 边缘情况并跟踪以前发现的路由,因此简化了实现(请参见 https://github.com/remix-run/react-router/pull/11883)(#9860
    • ⚠️ 此更改更改了内部 /__manifest 端点的返回值签名,因为我们不再需要 notFoundPaths 字段
  • @remix-run/react - 战争迷雾:更新为使用 RR 中重命名的 unstable_patchRoutesOnNavigation 函数(请参见 https://github.com/remix-run/react-router/pull/11888)(#9860
  • @remix-run/server-runtime - 单次获取:当存在 basename 时修复重定向(#9848
  • @remix-run/server-runtime - 单次获取:将 turbo-stream 更新到 v2.3.0#9856
    • 稳定序列化有效负载的对象键顺序
    • 删除有效负载大小的内存限制

更新的依赖项

按包分类的更改

完整变更日志v2.11.1...v2.11.2

v2.11.1

日期:2024-08-05

补丁更改

  • @remix-run/react - 恢复 #9695,停止无限重新加载(a7cffe57

按包分类的更改

完整变更日志v2.11.0...v2.11.1

v2.11.0

日期:2024-08-01

发生了什么变化

unstable_fogOfWar 未来标志重命名为 unstable_lazyRouteDiscovery(不稳定)

我们发现,future.unstable_fogOfWar 标志名称在没有适当上下文的情况下可能会让人感到困惑(尤其是 博客文章),因此我们为了清楚起见,将该标志重命名为 future.unstable_lazyRouteDiscovery。如果您已经选择使用此功能,请在您的 vite.config.ts 文件(或 remix.config.js)中更新该标志的名称。

在单次获取中删除了 response 存根(不稳定)

最初的单次获取方法基于一个假设,即最终的 middleware 实现将需要类似 ResponseStub API 的东西,以便用户可以在处理程序之前/之后以及处理程序期间在 middleware 中修改 status/headers。作为单次获取的一部分,我们希望对齐文档请求和数据请求之间如何合并响应头。考虑到 response 是未来的 API,我们将文档请求对齐以使用数据请求正在使用的 response 存根,并且我们停止使用 headers() 函数。

但是,Michael 和 Ryan 在最近的 路线图规划 中的认识/对齐使我们意识到最初的假设是错误的。middleware 不需要 response 存根 - 因为用户可以直接修改从 await next() 获取的 Response

删除该假设,并且仍然希望对齐文档请求和数据请求之间如何合并头,使用当前 headers() API 并将单次获取数据请求对齐以使用该现有 API 更有意义。这样,我们就无需引入任何新的与头相关的 API,这将使单次获取的采用变得更加容易。

此更改

  • headers() 函数将允许您控制文档请求和数据请求的头合并
  • 在大多数情况下,如果您正在返回 json()/defer() *没有* 设置自定义 statusheaders,您可以只删除这些实用程序函数并返回原始数据
    • return json({ data: "whatever" });
    • return { data: "whatever" };
  • 如果您*正在* 通过 json/defer 返回自定义 statusheaders
    • 我们添加了一个新的与 API 兼容的 unstable_data 实用程序,它允许您在不将其编码到 Response 中的情况下,将 status/headers 与原始数据一起发送回
  • 我们将在下一个主要版本中删除 jsondefer,但两者都*应该* 仍然在 v2 的单次获取中工作,以允许逐步采用新的行为

⚠️ 如果您已经在其不稳定状态下采用了单次获取并转换为 response 存根,则需要将这些更改移回以利用 headers() API。

次要更改

  • @remix-run/dev - 战争迷雾:为了清楚起见,将 future.unstable_fogOfWar 重命名为 future.unstable_lazyRouteDiscovery#9763
  • @remix-run/server-runtime - 添加了一个新的 replace(url, init?) 替代 redirect(url, init?),它在客户端导航重定向时执行 history.replaceState 而不是 history.pushState#9764
  • @remix-run/server-runtime - 单次获取:添加了一个新的 unstable_data() API,以在需要自定义 status/headers 时替换 json/defer#9769
  • @remix-run/server-runtime - 单次获取:删除 responseStub,转而使用 headers#9769

补丁更改

  • @remix-run/dev - 处理绝对 Vite 基本 URL(#9700
  • @remix-run/react - 将初始水合路由不匹配从 URL 检查更改为匹配检查,以抵抗 URL 不一致(#9695
  • @remix-run/react - 单次获取:确保调用不包含路径名中的任何尾部斜杠(即 /path/.data)(#9792
  • @remix-run/react - 单次获取:将 undefined 添加到 useRouteLoaderData 类型覆盖中(#9796

更新的依赖项

按包分类的更改

完整变更日志v2.10.3...v2.11.0

v2.10.3

日期:2024-07-16

补丁更改

  • @remix-run/architect - 手动将头用分号连接起来,以避免 Remix 和 node/undici Headers 实现之间的差异(#9664
  • @remix-run/react - 在重新加载页面之前,记录加载路由模块时遇到的任何错误(#8932
  • @remix-run/react - 单次获取(不稳定):通过 dataStrategy 代理 request.signal 以便为 loader 调用修复取消(#9738
  • @remix-run/react - 单次获取(不稳定):在幕后采用 React Router 稳定化的 future.v7_skipActionErrorRevalidation#9706
    • 这稳定了 unstable_actionStatus 中的 shouldRevalidate 参数到 actionStatus
    • ⚠️ 如果您已经选择使用单次获取和 unstable_actionStatus 参数,这可能对您的应用程序是一个重大更改

更新的依赖项

按包分类的更改

完整变更日志v2.10.2...v2.10.3

v2.10.2

日期:2024-07-04

补丁更改

  • @remix-run/react - 将 ref 转发到 Formbdd04217
  • @remix-run/server-runtime - 修复了从加载程序返回的原始原生 fetch 响应上的 immutable 头部的错误(#9693

按包变更

完整变更日志: v2.10.1...v2.10.2

v2.10.1

日期: 2024-07-03

补丁变更

  • @remix-run/react - 战争迷雾(不稳定):支持从 <Form> 组件中发现路由 (#9665)
  • @remix-run/react - 战争迷雾(不稳定):不要发现带有 reloadDocument 的链接/表单 (#9686)

更新依赖

按包变更

完整变更日志: v2.10.0...v2.10.1

v2.10.0

日期: 2024-06-25

更新内容

延迟路由发现(又名“战争迷雾”)

Remix 中的“战争迷雾”功能现在可以通过 future.unstable_fogOfWar 标志使用,这是一个优化,可以减少 Remix 路由清单的前期大小。在大多数情况下,Remix 路由清单的大小不会大到影响初始性能指标,但在规模化后,我们发现一些应用程序可以生成大型清单,这些清单在应用程序启动时下载和执行很昂贵。

启用战争迷雾后,Remix 只会在清单中包含最初服务器端渲染的路由,然后它会为用户在应用程序中导航的外部链接获取清单“补丁”。默认情况下,为了避免瀑布,Remix 会为所有渲染的链接获取补丁,因此在理想情况下,它们已经在点击之前就被修补了。如果用户在积极发现完成之前点击一个链接,那么将出现一个小瀑布,首先“发现”该路由,然后导航到该路由。

启用此标志应该不需要更改应用程序代码。有关更多信息,请参阅 文档

次要变更

  • 添加对延迟路由发现(又名“战争迷雾”)的支持 (#9600, #9619)

补丁变更

  • @remix-run/{dev|express|serve} - 将 express 依赖项升级到 ^4.19.2 (#9184)
  • @remix-run/react - 当 clientLoader 存在时,不要预取服务器端 loader 数据 (#9580)
  • @remix-run/react - 当 Layout/ErrorBoundary 渲染也抛出异常时,避免水合循环 (#9566)
  • @remix-run/react - 修复使用子路由和 HydrateFallback 组件以及 basename 时出现的 hydration 错误 (#9584)
  • @remix-run/{server-runtime|react} - 单一获取:更新到 [email protected] (#9562)
  • @remix-run/server-runtime - 单一获取:正确处理从资源路由中抛出的 4xx/5xx 响应存根 (#9501)
  • @remix-run/server-runtime - 单一获取:更改重定向以使用 202 状态以避免自动缓存 (#9564)
  • @remix-run/server-runtime - 单一获取:修复在单一获取中从资源路由返回或抛出响应存根时出现的问题 (#9488)
  • @remix-run/server-runtime - 单一获取:修复从资源路由返回 null 时出现的错误 (#9488)

更新依赖

按包变更

完整变更日志: v2.9.2...v2.10.0

v2.9.2

日期: 2024-05-10

更新内容

更新单一获取的类型安全性

在 2.9.2 中,我们增强了选择使用 future.unstable_singleFetch 功能时的类型安全性。之前,我们将 response 存根添加到 LoaderFunctionArgs 中,并使用类型覆盖来推断 useLoaderData 等,但我们发现这还不够。

在此版本中,我们引入了新函数来帮助在使用单一获取时进行类型推断 - defineLoader/defineAction 以及它们在客户端的对应项 defineClientLoaderdefineClientAction。这些是标识函数;它们不会在运行时修改您的加载器或操作。相反,它们的存在仅仅是为了类型安全性,通过提供参数类型并确保有效返回类型来实现。

export const loader = defineLoader(({ request }) => {
  //                                ^? Request
  return { a: 1, b: () => 2 };
  //           ^ type error: `b` is not serializable
});

请注意,如果您不关心类型安全性,则 defineLoaderdefineAction 在技术上不是定义加载器和操作所必需的。

// this totally works! and typechecking is happy too!
export const loader = () => {
  return { a: 1 };
};

这意味着您可以逐步选择使用 defineLoader,一次一个加载器。

请参阅 单一获取文档 以获取更多信息。

补丁变更

  • @remix-run/dev - Vite:修复运行 remix vite:build 时出现的 dest already exists 错误 (#9305)
  • @remix-run/dev - Vite:修复在路由文件位于应用程序目录之外时,在开发过程中解析关键 CSS 出现的问题 (#9194)
  • @remix-run/dev - Vite:从 Vite 插件的 optimizeDeps.include 列表中删除 @remix-run/node,因为它是不必要的,并且会导致在不依赖此包时出现 Vite 警告 (#9287)
  • @remix-run/dev - Vite:清理开发环境中多余的 ?client-route=1 导入 (#9395)
  • @remix-run/dev - Vite:确保在 Remix Vite 插件中应用 react-refresh Babel 转换时,不会引用 Babel 配置文件 (#9241)
  • @remix-run/react - 单一获取的类型安全性:defineLoaderdefineClientLoaderdefineActiondefineClientAction (#9372)
  • @remix-run/react - 单一获取:将 undefined 添加到 useActionData 类型覆盖 (#9322)
  • @remix-run/react - 单一获取:允许通过 <RemixServer> 在单一获取流传输内联脚本时设置 nonce (#9364)
  • @remix-run/server-runtime - 单一获取:不要通过 handleError 记录抛出的响应存根 (#9369)
  • @remix-run/server-runtime - 单一获取:在 v2 中自动将资源路由裸对象返回包装在 json() 中以实现向后兼容(并记录弃用警告)(#9349)
  • @remix-run/server-runtime - 单一获取:将 response 存根传递给资源路由处理程序 (#9349)

更新依赖

按包变更

完整变更日志: v2.9.1...v2.9.2

v2.9.1

日期: 2024-04-24

补丁变更

  • @remix-run/dev - 修复一个问题,即在 Vite 的 ssr.noExternal 选项中添加了 Remix 包的消费者被 Remix Vite 插件将 Remix 包添加到 Vite 的 ssr.external 选项中覆盖 (#9301)
  • @remix-run/react - 从 TS 构建中忽略 future/*.d.ts 文件 (#9299)

按包变更

完整变更日志: v2.9.0...v2.9.1

v2.9.0

日期: 2024-04-23

更新内容

单一获取(不稳定)

2.9.0 引入了 future.unstable_singleFetch 标志以在您的 Remix 应用程序中启用单一获取行为 (RFC)。请参阅 文档 以获取完整详细信息,但需要注意的主要更改包括

  • loader/action 函数返回的裸对象不再自动序列化为 JSON 响应
    • 相反,它们将通过 turbo-stream 按原样流式传输,这允许直接序列化更复杂的数据类型,例如 PromiseDateMap 实例等等
    • 您需要修改 tsconfig.json 中的 compilerOptions.types 数组,以便在使用单一获取时正确推断类型
  • headers 导出不再在启用单一获取时使用,而是使用新的 response 存根传递给您的 loader/action 函数
  • 在使用单一获取时,json/defer/redirect 实用程序已弃用(但仍能基本按相同方式工作)
  • 操作不再在 4xx/5xx 响应上自动重新验证 - 您可以返回 2xx 以选择重新验证,或者使用 shouldRevalidate

[!IMPORTANT] 单一获取需要使用 undici 作为您的获取 polyfill,或者在 Node 20+ 上使用内置的获取,因为它依赖于那里可用的 API,而不是 @remix-run/web-fetch polyfill。有关更多详细信息,请参阅下面的 Undici 部分。

  • 如果您正在管理自己的服务器并调用 installGlobals(),则需要调用 installGlobals({ nativeFetch: true }) 以避免在使用单一获取时出现运行时错误
  • 如果您使用的是 remix-serve,则它将在启用单一获取时自动使用 undici

Undici

Remix 2.9.0 添加了一个新的 installGlobals({ nativeFetch: true }) 标志,选择使用 undici 作为 Web Fetch polyfill,而不是使用 @remix-run/web-*。此更改有几个主要优势

  • 它将允许我们在未来的 Remix 版本中停止维护我们自己的 web-std-io 分支
  • 它应该让我们更符合规范
    • ⚠️ 我们分支中的某些不符合规范的错误可能会在迁移到 undici 时被“修复”,因此请注意“破坏性错误修复”并注意您在应用程序中执行的任何高级 fetch API 交互
    • ⚠️ 在某些情况下,undici 可能出于设计原因具有不同的行为 - 最值得注意的是,undici 的垃圾回收行为不同,您需要消耗所有获取响应主体 以避免应用程序中的内存泄漏
  • 由于 undicinode 内部使用的获取实现,因此它应该更好地帮助 Remix 应用程序更顺利地放弃 polyfill,以便在 node 20+ 上使用内置的 Node.js API

次要变更

  • 新的 future.unstable_singleFetch 标志 (#8773, #9073, #9084, #9272)
  • @remix-run/node - 添加了一个新的 installGlobals({ nativeFetch: true }) 标志来选择使用 undici 作为 fetch polyfill,而不是 @remix-run/web-* (#9106, #9111, #9198)
  • @remix-run/server-runtime - 添加了 ResponseStub 头部接口,并在启用 Single Fetch 时弃用 headers 导出 (#9142)

补丁更改

  • create-remix - 使用 --template 标志时允许仓库名称中包含 . (#9026)
  • @remix-run/dev - 提高了 monorepos 中 getDependenciesToBundle 的解析能力 (#8848)
  • @remix-run/dev - 通过使用流式 entry.server 修复了启用 Single Fetch 时 SPA 模式的问题 (#9063)
  • @remix-run/dev - Vite: 为转换后的路由添加了 sourcemap 支持 (#8970)
  • @remix-run/dev - 更新了 Remix CLI/Dev Server 打印到控制台的链接,以指向更新的文档位置 (#9176)
  • @remix-run/server-runtime - 处理由 handleDataRequest 创建的重定向 (#9104)

更新的依赖项

按包分类的更改

完整变更日志: v2.8.1...v2.9.0

v2.8.1

日期: 2024-03-07

补丁更改

  • @remix-run/dev - Vite: 支持在运行 remix revealremix routes CLI 命令时从 Vite 配置中读取 (#8916)
  • @remix-run/dev - Vite: 清理生产环境构建中路由 JavaScript 文件中的冗余客户端路由查询字符串 (#8969)
  • @remix-run/dev - Vite: 将 vite 命令添加到 Remix CLI --help 输出中 (#8939)
  • @remix-run/dev - Vite: 修复了 Vite 配置中 build.sourcemap 选项的支持问题 (#8965)
  • @remix-run/dev - Vite: 修复了在没有客户端入口文件的情况下使用 Vite 的 server.fs.allow 选项时的错误 (#8966)
  • @remix-run/react - 加强了内部 LayoutComponent 类型,使其接受有限的子元素 (#8910)

更新的依赖项

按包分类的更改

完整变更日志: v2.8.0...v2.8.1

v2.8.0

日期: 2024-02-28

次要更改

  • @remix-run/dev - Vite: 将解析后的 viteConfig 传递给 Remix Vite 插件的 buildEnd 钩子 (#8885)

补丁更改

  • @remix-run/dev - 在 esbuild 编译器中将 Layout 标记为浏览器安全路由导出 (#8842)
  • @remix-run/dev - Vite: 当依赖项包含 "use client" 指令时,静默构建警告 (#8897)
  • @remix-run/dev - Vite: 修复了 serverBundles 问题,其中会生成多个浏览器清单 (#8864)
  • @remix-run/dev - Vite: 支持自定义 build.assetsDir 选项 (#8843)
  • @remix-run/react - 修复了默认根 ErrorBoundary 组件,使其利用用户提供的 Layout 组件 (#8859)
  • @remix-run/react - 修复了默认根 HydrateFallback 组件,使其利用任何用户提供的 Layout 组件 (#8892)

更新的依赖项

按包分类的更改

完整变更日志: v2.7.2...v2.8.0

2.7.2

日期: 2024-02-21

补丁更改

  • @remix-run/dev - Vite: 修复了在构建包含 .css?url 导入的项目时的错误 (#8829)

2.7.1

日期: 2024-02-20

补丁更改

  • @remix-run/cloudflare-pages - 修复了破坏性变更,并在 getLoadContext 参数中恢复 Cloudflare 事件上下文字段以实现向后兼容性 (#8819)

v2.7.0

日期: 2024-02-20

有什么变化

稳定的 Vite 插件

我们很高兴地宣布,对 Vite 的支持现在在 Remix 2.7.0 中已稳定!自从 Remix Vite 的初始不稳定版本发布以来,我们一直在努力完善和扩展它,并得到了我们所有早期采用者和社区贡献者的帮助。这也意味着,Vite 独有的功能,如 SPA 模式服务器捆绑 以及 basename 支持 现在也正式稳定了 😊。

有关更多信息,请查看 博客文章Vite 文档

新的 Layout 导出

我们发现,在你的根路由中创建你自己的组件来保存你 Component/ErrorBoundary/HydrateFallback 之间的共享布局/应用程序外壳是非常常见的。这太常见了(也可能导致一些轻微的边缘情况问题,比如水合时的 FOUC),以至于我们在 2.7.0 中将它作为一等公民 API 进行了整合。

你现在可以从根路由中导出一个可选的 Layout 组件,它会将你的路由组件、ErrorBoundary 或 HydrateFallback 作为它的 children 提供。有关更多信息,请查看 Layout 文档RFC

Basename 支持

React Router 一直支持一个 basename 配置,它允许你在子路径中(如 https://127.0.0.1/myapp/*)提供你的应用程序,而无需在所有路由路径中都包含 /myapp 段。最初在 Remix 中省略了这个功能,因为 v1 的嵌套文件夹文件约定让将你的路由文件放在 routes/myapp/ 文件夹中变得非常容易,从而提供了相同的功能。社区也提出过一个 公开提案 来添加此功能。

自那以后有两件事发生了变化,让我们重新考虑了缺乏 basename 支持的问题

  • 我们在 v2 中切换到了基于扁平文件的约定,与嵌套文件夹约定相比,必须在所有路由文件中都添加前缀 myapp. 变得很不方便
  • 我们迁移到了 Vite,它有自己的 base 配置,这经常(并且很容易)与 React Router basename 的概念混淆(而实际上它更类似于旧的 Remix publicPath 配置)

2.7.0 中,我们在 Vite 插件配置中添加了对 basename 的支持。有关更多信息,请查看 basename 文档

注意:这是一个 Vite 独有的功能,通过 esbuild 编译器无法使用。

Cloudflare 代理作为 Vite 插件

⚠️ 对于依赖于不稳定 Vite 插件中的 Cloudflare 支持的项目来说,这是一个破坏性变更

Cloudflare 预设 (unstable_cloudflarePreset) 已被删除,并被一个新的 Vite 插件取代

 import {
    unstable_vitePlugin as remix,
-   unstable_cloudflarePreset as cloudflare,
+   cloudflareDevProxyVitePlugin as remixCloudflareDevProxy,
  } from "@remix-run/dev";
  import { defineConfig } from "vite";

  export default defineConfig({
    plugins: [
+     remixCloudflareDevProxy(),
+     remix(),
-     remix({
-       presets: [cloudflare()],
-     }),
    ],
-   ssr: {
-     resolve: {
-       externalConditions: ["workerd", "worker"],
-     },
-   },
  });

关于新插件的一些说明

  • remixCloudflareDevProxy 必须放在 remix 插件之前,以便它可以覆盖 Vite 的开发服务器中间件,以与 Cloudflare 的代理环境兼容
  • 因为它是一个 Vite 插件,所以 remixCloudflareDevProxy 可以将 ssr.resolve.externalConditions 设置为 workerd 兼容
  • remixCloudflareDevProxy 接受一个 getLoadContext 函数,该函数替代了旧的 getRemixDevLoadContext
  • 如果你正在使用需要 getBindingsProxygetPlatformProxynightly 版本,则不再需要它
  • 以前传递给 getBindingsProxygetPlatformProxy 的任何选项现在都应该传递给 remixCloudflareDevProxy
  • 此 API 也更好地与未来使用 Vite 的(实验性)运行时 API 的框架无关的 Vite 插件来支持 Cloudflare 的计划保持一致。

次要更改

  • @remix-run/react - 允许从根路由导出可选的 Layout (#8709)
  • @remix-run/cloudflare-pages - 使 getLoadContext 对于 Cloudflare Pages 成为可选的 (#8701)
    • 默认设置为 (context) => ({ env: context }),这与我们在所有模板中使用的方式相同
    • 这与 Remix Vite 插件的 Cloudflare 预设保持一致,并使我们的模板更简洁
  • @remix-run/dev - Vite: Cloudflare 代理作为 Vite 插件 (#8749)
    • ⚠️ 对于依赖于不稳定 Vite 插件中的 Cloudflare 支持的项目来说,这是一个破坏性变更
  • @remix-run/dev - Vite: 在 Vite 插件中添加了一个新的 basename 选项,允许用户设置内部 React Router basename,以便在子路径下提供应用程序 (#8145)
  • @remix-run/dev - Vite: 通过删除所有 unstable_ / Unstable_ 前缀来稳定 Remix Vite 插件、Cloudflare 预设以及所有相关的类型 (#8713)
    • 虽然这对现有 Remix Vite 插件消费者来说是一个破坏性变更,但现在插件已经稳定下来,除了主要版本之外,将不会再出现任何破坏性变更。感谢所有早期采用者和社区贡献者帮助我们走到今天! 🙏
  • @remix-run/dev - Vite: 通过将 Remix vite 插件配置从 unstable_ssr -> ssr 重命名来稳定 “SPA 模式” (#8692)

补丁更改

  • @remix-run/express - 使用 req.originalUrl 而不是 req.url,以便 Remix 可以看到完整的 URL (#8145)
    • Remix 依赖于了解完整的 URL 来确保服务器端和客户端代码可以协同工作,并且不支持在 Remix 处理程序之前进行 URL 重写
  • @remix-run/react - 修复了当根路由没有子元素时的 SPA 模式错误 (#8747)
  • @remix-run/server-runtime - 如果用户从资源路由返回 defer 响应,则添加更具体的错误 (#8726)
  • @remix-run/dev - 在 SPA 模式 entry.server.tsx 中始终添加 DOCTYPE,可以通过 remix reveal 选择退出 (#8725)
  • @remix-run/dev - 修复了在 SPA 模式中使用 basename 时的构建问题 (#8720)
  • @remix-run/dev - 修复 Remix 配置中同步 routes 函数的类型错误 (#8745)
  • @remix-run/dev - Vite: 修复如果在到达 Remix Vite 插件之前解析和序列化了搜索参数,客户端路由文件请求会失败的问题 (#8740)
  • @remix-run/dev - Vite: 验证如果存在,MDX Rollup 插件是否放置在 Vite 配置中的 Remix 之前 (#8690)
  • @remix-run/dev - Vite: 修复在当前工作目录与项目根目录不同时,开发期间解析关键 CSS 的问题 (#8752)
  • @remix-run/dev - Vite: 要求版本 5.1.0 以支持 .css?url 导入 (#8723)
  • @remix-run/dev - Vite: 支持 Vite 5.1.0.css?url 导入 (#8684)
  • @remix-run/dev - Vite: 启用使用 vite preview 预览 Remix SPA 应用程序 (#8624)
    • 在 SPA 模板中,npm run start 已重命名为 npm run preview,它使用 vite preview 而不是独立的 HTTP 服务器,例如 http-serverserv-cli
  • @remix-run/dev - Vite: 删除将 publicPath 作为选项传递给 Remix vite 插件的能力 (#8145)
    • ⚠️ 这是一个对使用不稳定 Vite 插件和 publicPath 的项目的重大更改
    • 这已经在 Vite 中通过 base 配置处理,因此我们现在从 Vite base 配置设置 Remix publicPath
  • @remix-run/dev - Vite: 为 .md.mdx 文件启用 HMR (#8711)
  • @remix-run/dev - Vite: 在 Windows 中可靠地检测非根路由 (#8806)
  • @remix-run/dev - Vite: 将 remixUserConfig 传递给预设 remixConfig 钩子 (#8797)
  • @remix-run/dev - Vite: 确保仅在服务器构建中引用的 CSS 文件 URL 在客户端可用 (#8796)
  • @remix-run/dev - Vite: 修复 app 目录之外的路由的服务器导出死代码消除 (#8795)

更新的依赖项

按包分类的更改

完整变更日志: v2.6.0...v2.7.0

v2.6.0

日期:2024-02-01

变更内容

不稳定 Vite 插件更新

随着我们继续朝着稳定 Vite 插件迈进,我们在本次发布中对不稳定 Vite 插件引入了一些重大更改。如果您选择使用 Vite 插件,请仔细阅读以下 @remix-run/dev 更改并相应地更新您的应用程序。

我们还从 serverBundles 选项中删除了 unstable_ 前缀,因为我们现在对 API 有信心 (#8596)。

🎉 最后但并非最不重要的是 - 我们在 #8531 中添加了期待已久的 Cloudflare 支持!要开始使用 Cloudflare,您可以使用 unstable-vite-cloudflare 模板

npx create-remix@latest --template remix-run/remix/templates/unstable-vite-cloudflare

有关更多信息,请参阅文档 未来 > Vite > Cloudflare未来 > Vite > 迁移 > 迁移 Cloudflare 函数

次要更改

  • @remix-run/server-runtime - 在请求被中止时添加 future.v3_throwAbortReason 标志以抛出 request.signal.reason,而不是像 new Error("query() call aborted: GET /path") 这样的 Error (#8251)

补丁更改

  • @remix-run/server-runtime - 将从 entry.server 抛出的 Response 解包为 ErrorResponse 并保留状态码 (#8577)

  • @remix-run/dev - Vite: 向 Vite 插件添加 manifest 选项以启用将 .remix/manifest.json 文件写入构建目录 (#8575)

    • ⚠️ 这对 Vite 插件的“服务器包”功能的使用者来说是一个重大更改
    • build/server/bundles.json 文件已被更通用的 build/.remix/manifest.json 取代
    • 虽然旧的服务器包清单在生成服务器包时始终写入磁盘,但必须通过 manifest 选项显式启用构建清单文件
  • @remix-run/dev - Vite: 依赖 Vite 插件排序 (#8627)

    • ⚠️ 这对使用不稳定 Vite 插件的项目来说是一个重大更改

    • Remix 插件预计会处理 JavaScript 或 TypeScript 文件,因此来自其他语言的任何转译必须首先完成。

    • 例如,这意味着将 MDX 插件放在 Remix 插件之前

        import mdx from "@mdx-js/rollup";
        import { unstable_vitePlugin as remix } from "@remix-run/dev";
        import { defineConfig } from "vite";
      
        export default defineConfig({
          plugins: [
      +     mdx(),
            remix()
      -     mdx(),
          ],
        });
      
    • 以前,Remix 插件错误地使用了 Vite 插件 API 中的 enforce: "post" 来确保它最后运行

    • 然而,这导致了其他不可预见的问题

    • 相反,我们现在依赖 Vite 的标准语义来排序插件

    • 官方的 Vite React SWC 插件 也依赖插件排序来处理 MDX

  • @remix-run/dev - Vite: 删除与 <LiveReload /> 的互操作性,改为依赖 <Scripts /> (#8636)

    • ⚠️ 这对使用不稳定 Vite 插件的项目来说是一个重大更改

    • Vite 提供了一个强大的客户端运行时,用于开发功能,如 HMR,这使得 <LiveReload /> 组件过时了

    • 事实上,拥有一个单独的开发脚本组件会导致脚本执行顺序问题

    • 为了解决这个问题,Remix Vite 插件过去会将 <LiveReload /> 覆盖到一个与 Vite 兼容的定制实现中

    • 现在,Remix Vite 插件不再进行所有这些间接操作,而是指示 <Scripts /> 组件自动包含 Vite 的客户端运行时和其他仅限开发的脚本

    • 要采用此更改,您可以从 root.tsx 组件中删除 LiveReload 组件

        import {
      -   LiveReload,
          Outlet,
          Scripts,
        }
      
        export default function App() {
          return (
            <html>
              <head>
              </head>
              <body>
                <Outlet />
                <Scripts />
      -         <LiveReload />
              </body>
            </html>
          )
        }
      
  • @remix-run/dev - Vite: 仅当 Vite 配置中启用了 build.manifest 时,才写入 Vite 清单文件 (#8599)

    • ⚠️ 这对 Vite manifest.json 文件的使用者来说是一个重大更改

    • 要显式启用 Vite 清单文件的生成,您必须在 Vite 配置中将 build.manifest 设置为 true

      export default defineConfig({
        build: { manifest: true },
        // ...
      });
      
  • @remix-run/dev - Vite: 添加新的 buildDirectory 选项,默认值为 "build" (#8575)

    • ⚠️ 这对使用 assetsBuildDirectoryserverBuildDirectory 选项的 Vite 插件使用者来说是一个重大更改

    • 这将取代旧的 assetsBuildDirectoryserverBuildDirectory 选项,它们的默认值分别为 "build/client""build/server"

    • Remix Vite 插件现在构建到包含 clientserver 目录的单个目录中

    • 如果您自定义了构建输出目录,则需要迁移到新的 buildDirectory 选项,例如

      import { unstable_vitePlugin as remix } from "@remix-run/dev";
      import { defineConfig } from "vite";
      
      export default defineConfig({
        plugins: [
          remix({
      -      serverBuildDirectory: "dist/server",
      -      assetsBuildDirectory: "dist/client",
      +      buildDirectory: "dist",
          })
        ],
      });
      
  • @remix-run/dev - Vite: 将 Vite 清单文件写入 build/.vite 目录,而不是嵌套在 build/clientbuild/server 目录中 (#8599)

    • ⚠️ 这对 Vite manifest.json 文件的使用者来说是一个重大更改
    • Vite 清单文件现在被写入 Remix 构建目录
    • 由于所有 Vite 清单现在都在同一个目录中,因此不再命名为 manifest.json
    • 相反,它们被命名为 build/.vite/client-manifest.jsonbuild/.vite/server-manifest.json,或者在使用服务器包时命名为 build/.vite/server-{BUNDLE_ID}-manifest.json
  • @remix-run/dev - Vite: 从 serverBundles 选项中删除 unstable 前缀 (#8596)

  • @remix-run/dev - Vite: 向 remix vite:build 添加 --sourcemapClient--sourcemapServer 标志 (#8613)

  • @remix-run/dev - Vite: 验证从 serverBundles 函数返回的 ID,以确保它们只包含字母数字字符、连字符和下划线 (#8598)

  • @remix-run/dev - Vite: 修复“无法快速刷新”的错误警报 (#8580)

    • HMR 已经正常运行,但错误地记录了在内部客户端路由上“无法快速刷新”
    • 现在内部客户端路由正确地为快速刷新注册 Remix 导出,例如 meta,这消除了错误警报。
  • @remix-run/dev - Vite: Cloudflare Pages 支持 (#8531)

  • @remix-run/dev - Vite: 向 Cloudflare 预设添加 getRemixDevLoadContext 选项 (#8649)

  • @remix-run/dev - Vite: 删除 Vite v4 的未记录的向后兼容层 (#8581)

  • @remix-run/dev - Vite: 添加 presets 选项,以简化与不同平台和工具的集成 (#8514)

  • @remix-run/dev - Vite: 添加 buildEnd 钩子 (#8620)

  • @remix-run/dev - Vite: 向生成的服务器构建中添加 mode 字段 (#8539)

  • @remix-run/dev - Vite: 减少 HMR 期间对路由模块的网络调用 (#8591)

  • @remix-run/dev - Vite: 导出 Unstable_ServerBundlesFunctionUnstable_VitePluginConfig 类型 (#8654)

更新的依赖项

按包分类的更改

完整变更日志: v2.5.1...v2.6.0

v2.5.1

日期:2024-01-18

补丁更改

  • create-remix - 为标题颜色设置高对比度前景/背景 (#8503)
    • bgWhitewhiteBright 在许多终端配色方案中是相同的颜色,导致它呈现为无法辨认的白底白字
  • @remix-run/dev - 向 @remix-run/dev/server-build 虚拟模块添加 isSpaMode (#8492)
  • @remix-run/dev - SPA 模式:自动在不存在的情况下添加<!DOCTYPE html>,以修复 SPA 模板的怪癖模式警告 (#8495)
  • @remix-run/dev - Vite:服务器端代码的错误指向新的文档 (#8488)
  • @remix-run/dev - Vite:修复读取更改文件内容时的 HMR 竞态条件 (#8479)
  • @remix-run/dev - Vite:在客户端构建中树摇未使用路由导出 (#8468)
  • @remix-run/dev - Vite:性能分析 (#8493)
    • 运行remix vite:build --profile以生成一个.cpuprofile,可以共享或上传到 speedscope.app
    • 在开发模式中,按下p + enter以启动新的性能分析会话或停止当前会话
    • 如果您需要分析开发服务器启动,请运行remix vite:dev --profile以使用运行的性能分析会话初始化开发服务器
    • 有关更多信息,请参阅新的Vite > 性能文档
  • @remix-run/dev - Vite:通过在相关文件更改而不是每个请求上使 Remix 的虚拟模块失效来提高开发服务器请求的性能 (#8164)
  • @remix-run/react - 从Blocker/BlockerFunction 类型中删除剩余的unstable_ 前缀 (#8530)
  • @remix-run/react - 在 SPA 模式中仅在<Meta>/<Links> 中使用活动匹配 (#8538)

更新的依赖项

按包进行的更改

完整更改日志v2.5.0...v2.5.1

v2.5.0

日期:2024-01-11

更改内容

SPA 模式(不稳定)

SPA 模式 (RFC) 允许您将 Remix 应用程序生成为从静态index.html 文件提供服务的独立 SPA。您可以通过在 Remix Vite 插件配置中设置unstable_ssr: false 来选择 SPA 模式

// vite.config.ts
import { unstable_vitePlugin as remix } from "@remix-run/dev";
import { defineConfig } from "vite";

export default defineConfig({
  plugins: [remix({ unstable_ssr: false })],
});

在 SPA 模式下的开发就像一个普通的 Remix 应用程序一样,仍然使用 Remix 开发服务器进行 HMR/HDR

remix vite:dev

在 SPA 模式下构建将在您的客户端资产目录中生成一个index.html 文件

remix vite:build

要运行您的 SPA,您可以通过 HTTP 服务器提供您的客户端资产目录

npx http-server build/client

有关更多信息,请参阅SPA 模式文档

服务器捆绑包(不稳定)

这是一个为托管提供商集成设计的进阶功能,您可能希望将服务器代码拆分为多个请求处理程序。将应用程序编译成多个服务器捆绑包时,需要在应用程序前面有一个自定义路由层,将请求引导到正确的捆绑包。此功能目前不稳定,仅用于收集早期反馈。

您可以通过在您的 vite 配置中设置unstable_serverBundles 选项来控制由 Remix Vite 构建生成的服务器捆绑包

import { unstable_vitePlugin as remix } from "@remix-run/dev";
import { defineConfig } from "vite";

export default defineConfig({
  plugins: [
    remix({
      unstable_serverBundles: ({ branch }) => {
        const isAuthenticatedRoute = branch.some(
          (route) => route.id === "routes/_authenticated"
        );

        return isAuthenticatedRoute ? "authenticated" : "unauthenticated";
      },
    }),
  ],
});

次要更改

  • 添加对“SPA 模式”的不稳定支持 (#8457)
  • unstable_serverBundles 选项添加到 Vite 插件以支持将服务器代码拆分为多个请求处理程序 (#8332)

补丁更改

  • create-remix:仅更新 Remix 依赖项的* 版本 (#8458)
  • remix-serve:如果磁盘上不存在源映射,则不要尝试加载它们 (#8446)
  • @remix-run/dev:修复isbot@4 于 2024 年 1 月 1 日发布的问题 (#8415)
    • remix dev 现在将在package.json 中添加"isbot": "^4",而不是使用latest
    • 更新内置的entry.server 文件以与isbot@3isbot@4 兼容,以向已固定isbot@3 的 Remix 应用程序提供向后兼容性
    • 通过create-remix,模板更新为使用isbot@4
  • @remix-run/dev:Vite - 修复更改未渲染路由的导出时的 HMR 问题 (#8157)
  • @remix-run/dev:Vite - 在运行remix vite:build 命令时将NODE_ENV 默认为"production" (#8405)
  • @remix-run/dev:Vite - 删除 Vite 插件配置选项serverBuildPath,转而使用单独的serverBuildDirectoryserverBuildFile 选项 (#8332)
  • @remix-run/dev:Vite - 放宽严格的路由导出限制,恢复对非 Remix 路由导出的支持 (#8420)
  • @remix-run/react:Vite - 修复与来自现有 Remix 编译器的import.meta.hot 的类型冲突 (#8459)
  • @remix-run/server-runtime:将cookie 依赖项更新为0.6.0 以继承对Partitioned 属性的支持 (#8375)

更新的依赖项

按包进行的更改

完整更改日志v2.4.1...v2.5.0

v2.4.1

日期:2023-12-22

补丁更改

  • @remix-run/dev:Vite - 删除unstable_viteServerBuildModuleId,转而手动引用虚拟模块名称"virtual:remix/server-build" (#8264)

    • ⚠️ 这对使用具有自定义服务器的不稳定 Vite 插件的项目来说是一个重大更改

    • 此更改是为了避免@remix-run/dev 可能意外地包含在服务器的生产依赖项中的问题。

    • 相反,您应该在开发模式中使用ssrLoadModule 时手动编写虚拟模块名称"virtual:remix/server-build"

      -import { unstable_viteServerBuildModuleId } from "@remix-run/dev";
      
      // ...
      
      app.all(
        "*",
        createRequestHandler({
          build: vite
      -      ? () => vite.ssrLoadModule(unstable_viteServerBuildModuleId)
      +      ? () => vite.ssrLoadModule("virtual:remix/server-build")
            : await import("./build/server/index.js"),
        })
      );
      
  • @remix-run/dev:Vite - 将vite:devvite:build 命令添加到 Remix CLI (#8211)

    • 为了处理即将推出的 Remix 功能,其中插件选项会影响所需的 Vite 构建次数,您现在应该通过 Remix CLI 运行您的 Vite devbuild 进程。

      {
        "scripts": {
      -    "dev": "vite dev",
      -    "build": "vite build && vite build --ssr"
      +    "dev": "remix vite:dev",
      +    "build": "remix vite:build"
        }
      }
      
  • @remix-run/dev:Vite - 当.server 文件被客户端引用时显示错误消息 (#8267)

    • 以前,从客户端代码引用.server 模块会导致类似的错误消息
      • 请求的模块“/app/models/answer.server.ts”没有提供名为“isDateType”的导出
    • 这很令人困惑,因为answer.server.ts确实提供了isDateType 导出,但是 Remix 用空模块(export {})替换了.server 模块以用于客户端构建
    • 现在,Remix 在从客户端代码引用.server 模块时会明确地导致编译时失败,并包含专门的错误消息,具体取决于导入是在路由模块还是非路由模块中发生
    • 错误消息还包括指向相关文档的链接
  • @remix-run/dev:Vite - 保留来自.client 模块的导出的名称 (#8200)

    • .server 模块不同,主要目的不是阻止代码泄漏到服务器构建中,因为客户端构建已经是公开的
    • 相反,目标是将 SSR 渲染与客户端专用代码隔离
    • 路由需要从.client 模块导入代码,而不会导致编译失败,然后依赖于运行时检查或以其他方式确保执行仅发生在客户端专用上下文中(例如,事件处理程序、useEffect
    • 用空模块替换.client 模块会导致构建失败,因为 ESM 具名导入是在静态分析时进行的
      • 因此,我们保留了具名导出,但将每个导出的值替换为undefined
      • 这样,导入在构建时就是有效的,并且可以使用标准运行时检查来确定代码是在服务器上还是在客户端上运行
  • @remix-run/dev:Vite - 在构建期间禁用 Vite 子编译器中的监视模式 (#8342)

  • @remix-run/dev:Vite - 在生产构建中启用源映射时显示警告 (#8222)

  • @remix-run/react:将服务器loader 错误通过serverLoader 传播到正在 hydration clientLoader 中 (#8304)

  • @remix-run/react 通过@remix-run/react 重新导出Response 帮助程序(defer/json/redirect/redirectDocument),以便在clientLoader/clientAction 中使用 (#8351)

  • @remix-run/server-runtime:将可选的error 添加到ServerRuntimeMetaArgs 类型以与MetaArgs 对齐 (#8238)

  • create-remix:切换到使用@remix-run/web-fetch 而不是node-fetchcreate-remix CLI 内部 (#7345)

  • remix-serve:使用 node fileURLToPath 将源映射 URL 转换为路径 (#8321)

更新的依赖项

按包进行的更改

完整更改日志v2.4.0...v2.4.1

v2.4.0

日期:2023-12-13

更改内容

客户端数据

我们很高兴在本版本中发布客户端数据 RFC!最终的 API 与 RFC 略有不同,因此请查看文档以了解用例和最终 API

虽然我们仍然建议将服务器加载程序/操作用于 Remix 应用程序中大部分的数据需求 - 这些操作提供了一些杠杆,您可以使用它们来实现更高级的用例,例如

  • 跳过 Hop:使用加载器仅用于 SSR,直接从浏览器查询数据 API
  • 全栈状态:使用客户端数据增强服务器数据,以获得完整的加载器数据集
  • 两者之一:有时使用服务器加载器,有时使用客户端加载器,但在一条路由上不会同时使用两者
  • 客户端缓存:将服务器加载器数据缓存到客户端,避免一些服务器调用
  • 迁移:简化从 React Router -> Remix SPA -> Remix SSR 的迁移

future.v3_relativeSplatPath

我们引入了 future.v3_relativeSplatPath 标志来实现一个重大错误修复,该修复涉及在 splat 路由内部进行相对路由时遇到的问题。有关更多信息,请参阅 React Router 6.21.0 版本说明useResolvedPath 文档

Vite 更新(不稳定)

Remix 现在从客户端构建中排除 .server 目录中的模块。

Remix 现在强制执行严格的路由导出,如果在路由模块中存在不支持的导出,则会抛出错误。以前,Remix 编译器允许从路由中导出任何内容。虽然这很方便,但也是常见错误的来源,这些错误难以跟踪,因为它们只在运行时出现。有关更多信息,请参阅 文档

次要变更

  • 添加对 clientLoader/clientAction/HydrateFallback 路由导出的支持 (#8173)
  • 添加一个新的 future.v3_relativeSplatPath 标志来实现一个重大错误修复,该修复涉及在 splat 路由内部进行相对路由时遇到的问题 (#8216)
  • 弃用 DataFunctionArgs,转而使用 LoaderFunctionArgs/ActionFunctionArgs (#8173)
    • 这旨在使服务器/客户端加载器/操作的类型保持一致,因为 clientLoader/clientActon 函数现在具有 serverLoader/serverAction 参数,这些参数区分 ClientLoaderFunctionArgs/ClientActionFunctionArgs
  • Vite:从客户端构建中排除 .server 目录中的模块 (#8154)
  • Vite:严格的路由导出 (#8171)

补丁变更

  • @remix-run/server-runtime:修复 Vite 开发中非 Express 自定义服务器的未样式内容闪现问题 (#8076)

  • @remix-run/server-runtime:在 Vite 开发中将请求处理程序错误传递给 vite.ssrFixStacktrace,以确保堆栈跟踪正确映射到原始源代码 (#8066)

  • remix-serve:修复文件具有 ?t=timestamp 后缀(重建)时的源映射加载问题 (#8174)

  • @remix-run/dev:更改 Vite 构建输出路径以解决 Vite 和 Remix 编译器各自管理 public 目录的方式之间的冲突 (#8077)

    • ⚠️ 这对使用不稳定 Vite 插件的项目来说是一个重大更改
    • 服务器现在编译到 build/server 而不是 build,客户端现在编译到 build/client 而不是 public
    • 有关变更的更多信息以及有关如何迁移项目的指南,请参阅更新后的 Remix Vite 文档
  • @remix-run/dev:将 Vite 同级依赖范围升级到 v5 (#8172)

  • @remix-run/dev:在 Vite 开发中支持具有 handle 导出的路由的 HMR (#8022)

  • @remix-run/dev:修复 Vite 开发中非 Express 自定义服务器的未样式内容闪现问题 (#8076)

  • @remix-run/dev:在 Vite 插件中捆绑客户端入口文件中导入的 CSS (#8143)

  • @remix-run/dev:由于 Vite 中 ?url 导入的 CSS 文件未被正确处理,因此从 Vite 插件中删除了未记录的 legacyCssImports 选项 (#8096)

  • @remix-run/dev:Vite:修复 Windows 上 pnpm 工作区中对默认 entry.{client,server}.tsx 的访问问题 (#8057)

  • @remix-run/dev:删除 unstable_createViteServerunstable_loadViteServerBuild,它们只是在使用自定义服务器时对 Vite 的 createServerssrLoadModule 函数的最小包装器 (#8120)

    • ⚠️ 这对使用具有自定义服务器的不稳定 Vite 插件的项目来说是一个重大更改

    • 相反,我们现在提供 unstable_viteServerBuildModuleId,以便自定义服务器直接与 Vite 交互,而不是通过 Remix API,例如

      -import {
      -  unstable_createViteServer,
      -  unstable_loadViteServerBuild,
      -} from "@remix-run/dev";
      +import { unstable_viteServerBuildModuleId } from "@remix-run/dev";
      

      以中间件模式创建 Vite 服务器

      const vite =
        process.env.NODE_ENV === "production"
          ? undefined
      -    : await unstable_createViteServer();
      +    : await import("vite").then(({ createServer }) =>
      +        createServer({
      +          server: {
      +            middlewareMode: true,
      +          },
      +        })
      +      );
      

      在请求处理程序中加载 Vite 服务器构建

      app.all(
        "*",
        createRequestHandler({
          build: vite
      -      ? () => unstable_loadViteServerBuild(vite)
      +      ? () => vite.ssrLoadModule(unstable_viteServerBuildModuleId)
            : await import("./build/server/index.js"),
        })
      );
      
  • @remix-run/dev:在 Vite 开发中将请求处理程序错误传递给 vite.ssrFixStacktrace,以确保堆栈跟踪正确映射到原始源代码 (#8066)

  • @remix-run/dev:Vite:保留来自 .client 导入的导出的名称 (#8200)

    • .server 模块不同,主要目的不是阻止代码泄漏到服务器构建中,因为客户端构建已经是公开的
    • 相反,目标是将 SSR 渲染与客户端专用代码隔离
    • 路由需要从 .client 模块导入代码,而不会导致编译失败,然后依赖运行时检查来确定代码是在服务器上运行还是在客户端上运行
    • 用空模块替换.client 模块会导致构建失败,因为 ESM 具名导入是在静态分析时进行的
      • 因此,我们保留了命名导出,但将每个导出值替换为一个空对象
      • 这样,导入在构建时是有效的,并且可以使用标准运行时检查来确定代码是在服务器上运行还是在客户端上运行
  • @remix-run/dev:将 @remix-run/node 添加到 Vite 的 optimizeDeps.include 数组 (#8177)

  • @remix-run/dev:提高 Vite 插件性能 (#8121)

    • 并行检测路由模块导出
    • 在 Vite 子编译器中禁用 server.preTransformRequests,因为它仅用于处理路由模块
  • @remix-run/dev:从内置的 Vite 开发服务器中删除自动全局 Node polyfill 安装,而是允许显式选择加入 (#8119)

    • ⚠️ 对于使用不稳定 Vite 插件但没有自定义服务器的项目来说,这是一个重大变更

    • 如果您没有使用自定义服务器,则应该在 Vite 配置中调用 installGlobals

      import { unstable_vitePlugin as remix } from "@remix-run/dev";
      +import { installGlobals } from "@remix-run/node";
      import { defineConfig } from "vite";
      
      +installGlobals();
      
      export default defineConfig({
        plugins: [remix()],
      });
      
  • @remix-run/dev:Vite:在客户端导入 .server 默认导出时,在构建时出现错误 (#8184)

    • Remix 已经在确保服务器代码永远不会进入客户端之前剥离了 .server 文件代码
    • 这会导致客户端代码尝试导入服务器代码时出现错误,这正是我们想要的!
    • 但这些错误对于默认导入来说是在运行时发生的
    • 更好的体验是让这些错误在构建时发生,这样可以确保用户不会遇到这些错误
  • @remix-run/dev:修复使用 Vite 开发服务器时 request instanceof Request 检查问题 (#8062)

更新的依赖项

按包分类的变更

完整变更日志: v2.3.1...v2.4.0

v2.3.1

日期:2023-11-22

补丁变更

  • @remix-run/dev:在 Vite 开发中支持 LiveReload 组件中的 nonce 属性 (#8014)
  • @remix-run/dev:确保服务器构建的 assets 目录中的代码拆分 JS 文件不会在 Vite 构建后被清理 (#8042)
  • @remix-run/dev:修复 Vite 构建中从 public 目录冗余复制资产的问题 (#8039)
    • 这确保了静态资产不会在服务器构建目录中重复。
    • 这还修复了当 assetsBuildDirectory 深度嵌套在 public 目录中时构建会中断的问题。

更新的依赖项

按包分类的变更

完整变更日志: v2.3.0...v2.3.1

v2.3.0

日期:2023-11-16

发生了哪些变化

稳定 useBlocker

我们已经从 useBlocker 钩子中删除了 unstable_ 前缀,因为它已经使用了足够长的时间,我们对 API 有信心。我们不打算从 unstable_usePrompt 中删除前缀,因为浏览器处理 window.confirm 的方式不同,导致 React Router 无法保证一致的/正确的行为。

unstable_flushSync API

我们在命令式 API(useSubmituseNavigatefetcher.submitfetcher.load)中添加了一个新的 unstable_flushSync 选项,让用户可以选择对挂起的/乐观的 UI 进行同步 DOM 更新。

function handleClick() {
  submit(data, { flushSync: true });
  // Everything is flushed to the DOM so you can focus/scroll to your pending/optimistic UI
  setFocusAndOrScrollToNewlyAddedThing();
}

次要变更

  • useBlocker 钩子中删除 unstable_ 前缀 (#7882)
  • useNavigate/useSubmit/fetcher.load/fetcher.submit 中添加 unstable_flushSync 选项,以选择退出 React.startTransition 并进入 ReactDOM.flushSync 以进行状态更新 (#7996)

补丁变更

  • @remix-run/react: 添加缺少的 modulepreload 用于清单 (#7684)
  • @remix-run/server-runtime: 将 cookie 依赖项从 0.4.1 更新为 0.5.0 以继承对 Chrome 中 Priority 属性的支持 (#6770)
  • @remix-run/dev: 修复 FutureConfig 类型 (#7895)
  • 大量针对不稳定的 vite 编译器的微小修复
    • 支持在 Vite 开发中可选渲染 LiveReload 组件 (#7919)
    • 支持在 Vite 开发中 Scripts 之后渲染 LiveReload 组件 (#7919)
    • 修复使用 pnpm 的自定义服务器的 react-refresh/babel 解析 (#7904)
    • 在 Vite 中支持 .jsx 文件中的 JSX 使用,无需在 Vite 中手动导入 React (#7888)
    • 修复当存在不同 developmentproduction 模式之间具有不同本地状态的插件(例如 @mdx-js/rollup)时,Vite 生产构建 (#7911)
    • 缓存 Remix Vite 插件选项的解析 (#7908)
    • 支持 Vite 5 (#7846)
    • 允许 Vite 开发中使用除 "development" 之外的 process.env.NODE_ENV 值 (#7980)
    • 将共享块中的 CSS 附加到 Vite 构建中的路由 (#7952)
    • 让 Vite 通过 /@fs 处理项目根目录之外的文件服务 (#7913)
      • 这修复了在 pnpm 项目中使用默认客户端入口或服务器入口时出现的错误,这些文件可能位于项目根目录之外,但位于工作区根目录内
      • 默认情况下,Vite 会阻止访问工作区根目录之外(使用工作区时)或项目根目录之外(不使用工作区时)的文件,除非用户通过 Vite 的 server.fs.allow 选项显式选择
    • 提高 Vite 开发中 LiveReload 代理的性能 (#7883)
    • @remix-run/react 进行重复数据消除 (#7926)
      • 预捆绑 Remix 依赖项,以避免 Remix 路由器重复
      • 我们的 remix-react-proxy 插件不会处理默认的客户端和服务器入口文件,因为这些文件来自 node_modules 内部
      • 这意味着在 Vite 预捆绑依赖项之前(例如,第一次运行开发服务器时),不匹配的 Remix 路由器会导致 Error: You must render this element inside a <Remix> element
    • 修复使用 Vite 开发服务器中的 defer 时加载时的 React 快速刷新错误 (#7842)
    • 处理 Vite 开发服务器中的多个 Set-Cookie 标头 (#7843)
    • 修复使用自定义 Express 服务器时,Vite 开发中初始页面加载时的未修饰内容闪烁 (#7937)
    • 在 Vite 开发中从服务器的 .env 文件填充 process.env (#7958)
    • 将仅在服务器构建中引用的资产发出到 Vite 构建中的客户端资产目录 (#7892,樱桃挑选在 8cd31d65 中)

更新的依赖项

按包分类的更改

完整变更日志: v2.2.0...v2.3.0

v2.2.0

日期: 2023-10-31

更新内容

Vite!

Remix 2.2.0 为基于 Node 的应用程序添加了对 Vite 的不稳定支持!请查看我们的 公告博客文章Remix 文档中的未来 > Vite 页面 以了解更多详细信息。

您可以使用两个新的(不稳定)模板试用它

# minimal server
npx create-remix@latest --template remix-run/remix/templates/unstable-vite

# custom server (Express example)
npx create-remix@latest --template remix-run/remix/templates/unstable-vite-express
  • @remix-run/dev 中的新 API
    • unstable_vitePlugin: 新的 Remix Vite 插件
    • unstable_createViteServer: 在中间件模式下创建 Vite 服务器,用于与自定义服务器进行互操作
    • unstable_loadViteServerBuild: 允许您的自定义服务器在开发期间将 SSR 请求委托给 Vite
  • 已更改的 API
    • createRequestHandler: 现在还允许 build 参数是一个函数,该函数将在开发期间用于为每个请求动态加载新构建
  • 其他运行时
    • Deno 支持未经测试,但应通过 Deno 的 Node/npm 互操作工作
    • CloudFlare 支持尚未提供

新的 Fetcher API

根据此 RFC,我们引入了一些新的 API,让您可以更细粒度地控制 Fetcher 行为

  • 您现在可以通过 useFetcher({ key: string }) 指定自己的 Fetcher 标识符,这使您能够从应用程序中的不同组件访问相同的 Fetcher 实例,而无需道具传递
  • Fetcher 密钥现在在 useFetchers 返回的 Fetcher 上公开,以便它们可以通过 key 进行查找
  • FormuseSubmit 现在支持可选的 navigate/fetcherKey 道具/参数,以允许在后台使用可选用户指定的 key 启动 Fetcher 提交
    • <Form method="post" navigate={false} fetcherKey="my-key">
    • submit(data, { method: "post", navigate: false, fetcherKey: "my-key" })
    • 以这种方式调用 Fetcher 是短暂的且无状态的
    • 如果您需要访问其中一个 Fetcher 的状态,则需要利用 useFetchers()useFetcher({ key }) 在其他地方查找它

持久性未来标志

与上面提到的同一个 RFC 一样,我们引入了一个新的 future.v3_fetcherPersist 标志,允许您选择加入新的 Fetcher 持久性/清理行为。Fetcher 不会在卸载时立即清理,而是会一直持续到它们返回到 idle 状态。这使得在源 Fetcher 需要卸载的场景中,挂起的/乐观的 UI 非常容易。

  • 这有点像一个长期存在的错误修复,因为 useFetchers() API 始终只反映 正在进行的 Fetcher 信息,用于挂起的/乐观的 UI - 它不打算反映 Fetcher 数据或在它们返回到 idle 状态后保留 Fetcher
  • 请注意,当选择加入此标志时,以下具体行为更改,并检查您的应用程序的兼容性
    • 仍在挂载时完成的 Fetcher 不会在完成之后出现在 useFetchers() 中 - 因为您可以通过 useFetcher().data 访问数据,所以它们在其中没有用
    • 以前在进行中时卸载的 Fetcher 不会立即中止,而是会在它们返回到 idle 状态后进行清理
      • 它们将在进行中通过 useFetchers 公开,因此您仍然可以在卸载后访问挂起的/乐观的 data
      • 如果 Fetcher 在完成时不再挂载,那么它的结果将不会被后处理 - 例如,重定向将不会被跟踪,错误将不会在 UI 中冒泡
      • 但是,如果 Fetcher 在树中的其他地方使用相同的 key 重新挂载,那么它的结果将被处理,即使源 Fetcher 已卸载

次要更改

  • 不稳定的 vite 支持 (#7590)
  • 新的 Fetcher key API 和用于导航 API 的 navigate/fetcherKey 参数 (#10960)
  • 新的 future.v3_fetcherPersist 标志 (#10962)

补丁更改

  • @remix-run/express: 允许 Express 适配器在使用 app.enable('trust proxy') 时在代理后面工作 (#7323)
    • 以前,这使用 req.get('host') 来构建 Remix Request,但这不尊重 X-Forwarded-Host
    • 现在使用 req.hostname,它将尊重 X-Forwarded-Host
  • @remix-run/react: 修复在使用没有 default 导出的路由文件时可能无意中记录的警告 (#7745)
  • create-remix: 支持具有 .tgz 扩展名的本地 tarball,这允许直接支持 pnpm pack tarball (#7649)
  • create-remix: 将 Remix 应用程序版本默认设置为正在使用的 create-remix 版本 (#7670)
    • 这最显著地使更容易使用标签,例如 npm create remix@nightly

更新的依赖项

按包分类的更改

完整变更日志: v2.1.0...v2.2.0

v2.1.0

日期: 2023-10-16

更新内容

视图转换

我们很高兴在 Remix 中发布对 视图转换 API 的实验性支持!您现在可以触发导航 DOM 更新以包装在 document.startViewTransition 中,以在应用程序中的 SPA 导航上启用 CSS 动画转换。

在您的 Remix 应用程序中启用视图转换的最简单方法是通过新的 <Link unstable_viewTransition> 道具。这将导致导航 DOM 更新包装在 document.startViewTransition 中,这将为 DOM 更新启用转换。无需任何额外的 CSS 样式,您将获得页面上的基本交叉淡入淡出动画。

如果您需要为动画应用更细粒度的样式,您可以利用 unstable_useViewTransitionState 钩子,它会告诉您转换何时正在进行,您可以使用它来应用类或样式

function ImageLink(to, src, alt) {
  const isTransitioning = unstable_useViewTransitionState(to);
  return (
    <Link to={to} unstable_viewTransition>
      <img
        src={src}
        alt={alt}
        style={{
          viewTransitionName: isTransitioning ? "image-expand" : "",
        }}
      />
    </Link>
  );
}

您还可以使用 <NavLink unstable_viewTransition> 简写,它会为您管理钩子的使用,并在转换期间自动向 <a> 添加 transitioning

a.transitioning img {
  view-transition-name: "image-expand";
}
<NavLink to={to} unstable_viewTransition>
  <img src={src} alt={alt} />
</NavLink>

有关视图转换的示例用法,请查看 我们对 Astro Records 演示的 fork(它使用 React Router,但 Remix 也是 😉)。

有关使用视图转换 API 的更多信息,请参阅来自 Google Chrome 团队的 使用视图转换 API 进行流畅且简单的转换 指南。

稳定 createRemixStub

经过实际应用经验,我们对 createRemixStub API 充满信心并准备正式推出,因此在 2.1.0 版本中,我们移除了 unstable_ 前缀。

⚠️ 请注意,这涉及一个较小的破坏性更改 - <RemixStub remixConfigFuture> 属性已被重命名为 <RemixStub future>,以将 future 属性与特定文件位置解耦。

次要更改

  • 添加了对 View Transition API 的不稳定支持 (#10916)
  • 稳定了 @remix-run/testingcreateRemixStub 辅助函数 (#7647)

补丁更改

  • SerializeFrom 中模拟了 JSON.parse(JSON.stringify(x)) 的类型 (#7605)
    • 值得注意的是,序列化后仅可分配给 undefined 的类型字段现在被省略,因为 JSON.stringify |> JSON.parse 将省略它们。请参见测试用例以获取示例。
    • 这修复了从 v1.19 升级到 v2 时出现的类型错误。
  • 在指定 tagName 时避免修改 meta 对象 (#7594)
  • 修复了对 route.lazy 路由进行后续客户端导航时的 FOUC 问题 (#7576)
  • 导出正确的 Remix useMatches 包装器,以修复 UIMatch 类型 (#7551)
  • @remix-run/cloudflare - 源映射考虑了输出文件中的特殊字符 (#7574)
  • @remix-run/express - 为 text/event-stream 响应刷新标头 (#7619)

更新的依赖项

按软件包分类的更改

完整变更日志: v2.0.1...v2.1.0

v2.0.1

日期: 2023-09-21

补丁更改

  • 修复了使用 pnpm 时 MDX 文件的类型 (#7491)
  • 更新了 getDependenciesToBundle 以处理没有主导出的 ESM 包 (#7272)
    • 请注意,这些包必须在其 exports 字段中公开 package.json,以便可以解析其路径。
  • 修复了 serverBuildPath 扩展名为 .cjs 的服务器构建 (#7180)
  • 修复了使用 remix-serve 和手动模式 (remix dev --manual) 的 CJS 项目的 HMR (#7487)
    • 通过显式地清除 require 缓存,remix-serve 现在可以正确地重新导入新的服务器更改。
    • ESM 项目已正常工作,不受此影响。
  • 修复了由部分写入的服务器构建引起的错误 (#7470)
    • 以前,在新的服务器构建完全写入之前,有可能触发应用程序服务器代码的重新导入。重新导入部分写入的服务器构建会导致与 build.assets 未定义相关的错误,并在读取 build.assets.version 时崩溃。
  • UIMatchhandle 字段添加了第二个泛型 (#7464)
  • 修复了通过 route.lazy 加载资源路由的问题 (#7498)
  • 当向没有 action 的路由提交时,抛出语义正确的 405 ErrorResponse,而不是仅仅抛出 Error (#7423)
  • 更新到最新版本的 @remix-run/web-fetch (#7477)
  • crypto.randomBytes 切换到 crypto.webcrypto.getRandomValues,用于文件会话存储 ID 生成 (#7203)
  • 使用本机 Blob 类而不是 polyfill (#7217)

按软件包分类的更改 🔗

完整变更日志: v2.0.0...v2.0.1

v2.0.0

日期: 2023-09-15

我们非常高兴地向您发布 Remix v2,我们真心希望这次升级成为您体验过的最顺畅的框架升级!这是我们在 v2 中的主要目标 - 我们希望通过在 Remix v1 中大量使用弃用警告和未来标志 来实现这一目标。

如果您使用的是最新的 1.x 版本,并且已启用所有未来标志并解决了所有控制台警告,那么我们希望您已经完成了升级到 v2 的 90%。总会有一些我们无法放到标志后面的东西(比如破坏性类型更改)或者在最后一刻出现,没有时间在 1.x 中添加警告或标志。

如果您还没有使用最新的 1.x 版本,我们建议您先升级到该版本,并解决所有标志/控制台警告。

> npx upgrade-remix 1.19.3

破坏性更改

以下是 v2 中破坏性更改的非常简洁列表。

  • 有关破坏性更改的最全面讨论,请阅读升级到 v2指南。本文档提供了关于 v2 随附的破坏性更改的全面概述 - 以及如何调整您的应用程序以处理这些更改的说明。
  • 有关更多详细信息,您可以参考下面的按软件包分类的更改部分。

升级的依赖项要求

Remix v2 已升级其对 React 和 Node 的最低版本支持,现在正式需要

  • React 18 (#7121)
    • 有关升级到 React 18 的信息,请参阅 React 的升级指南.
  • Node 18 或更高版本 (#6939, #7292)
    • 有关升级到 Node 18 的信息,请参阅 Node 的v18 公告.
    • 请参阅Remix 文档,以了解我们何时停止支持 Node 版本。

已移除的未来标志

以下未来标志已移除,其行为现在是默认行为 - 您可以从 remix.config.js 文件中移除所有这些标志。

  • v2_dev - 带有 HMR+HDR 的新开发服务器 (#7002)
    • 如果您在 future.v2_dev 中配置了除布尔值之外的配置(例如,future.v2_dev.port),您可以将其提升到 remix.config.js 中的根 dev 对象。
  • v2_errorBoundary - 已移除 CatchBoundary,取而代之的是单一的 ErrorBoundary (#6906)
  • v2_headers - 更改了嵌套路由场景中 headers 的逻辑 (#6979)
  • v2_meta - 更改了 meta() 的返回值格式 (#6958)
  • v2_normalizeFormMethod - 将 formMethod API 规范化为大写 (#6875)
  • v2_routeConvention - 路由现在默认使用扁平路由约定 (#6969)

破坏性更改/API 移除

带弃用警告

以下列出了其他破坏性更改/API 移除,这些更改/移除在 Remix v1 中具有弃用警告。如果您使用的是最新的 1.19.3 版本,没有控制台警告,那么您可能可以使用所有这些更改!

没有弃用警告

不幸的是,我们无法为每个破坏性更改或 API 移除提供弃用警告 🙃。以下是可能需要您查看以升级到 v2 的剩余更改列表。

  • remix.config.js
    • 默认情况下,浏览器不再为 Node 内置模块提供 polyfill,您必须通过 browserNodeBuiltinsPolyfill (#7269) 选择 polyfill。
    • 如果您的应用程序中存在配置文件,则 PostCSS/Tailwind 将默认启用,您可以通过 postcsstailwind 标志 (#6909) 禁用它。
  • @remix-run/cloudflare
    • 删除 createCloudflareKVSessionStorage (#6898)
    • 放弃 @cloudflare/workers-types v2 & v3 支持 (#6925)
  • @remix-run/dev
    • 删除 REMIX_DEV_HTTP_ORIGIN,改为使用 REMIX_DEV_ORIGIN (#6963)
    • 删除 REMIX_DEV_SERVER_WS_PORT,改为使用 dev.port--port (#6965)
    • 删除 --no-restart/restart 标志,改为使用 --manual/manual (#6962)
    • 删除 --scheme/scheme--host/host,改为使用 REMIX_DEV_ORIGIN (#6962)
    • 删除 codemod 命令 (#6918)
  • @remix-run/eslint-config
    • 删除 @remix-run/eslint-config/jest 配置 (#6903)
    • 删除 ESLint 中的魔法导入警告 (#6902)
  • @remix-run/netlify
    • @remix-run/netlify 适配器已被删除,改为使用 Netlify 官方适配器 (#7058)
  • @remix-run/node
    • fetch 默认不再提供 polyfill,应用程序必须调用 installGlobals() 来安装 polyfill (#7009)
    • fetch 和相关 API 不再从 @remix-run/node 导出,应用程序应使用全局命名空间中的版本 (#7293)
    • 应用程序必须调用 sourceMapSupport.install() 来设置源映射支持
  • @remix-run/react
    • 删除 unstable_shouldReload,改为使用 shouldRevalidate (#6865)
  • @remix-run/serve
    • remix-serve 如果 3000 被占用并且未指定 PORT,则会选择一个空闲端口 (#7278)
    • 集成 manual 模式 (#7231)
    • 删除未记录的 createApp Node API (#7229)
    • 在 remix-serve 中为外部包保留动态导入 (#7173)
  • @remix-run/vercel
    • @remix-run/vercel 适配器已被删除,改为使用 Vercel 提供的开箱即用功能 (#7035)
  • create-remix
    • 停止将 isTypeScript 传递给 remix.init 脚本 (#7099)
  • remix
    • 删除魔法导出 (#6895)
类型变更
  • 删除 future.v2_meta 类型中的 V2_ 前缀,因为它们现在是默认行为 (#6958)
    • V2_MetaArgs -> MetaArgs
    • V2_MetaDescriptor -> MetaDescriptor
    • V2_MetaFunction -> MetaFunction
    • V2_MetaMatch -> MetaMatch
    • V2_MetaMatches -> MetaMatches
    • V2_ServerRuntimeMetaArgs -> ServerRuntimeMetaArgs
    • V2_ServerRuntimeMetaDescriptor -> ServerRuntimeMetaDescriptor
    • V2_ServerRuntimeMetaFunction -> ServerRuntimeMetaFunction
    • V2_ServerRuntimeMetaMatch -> ServerRuntimeMetaMatch
    • V2_ServerRuntimeMetaMatches -> ServerRuntimeMetaMatches
  • 以下类型已调整为优先使用 unknown 而不是 any,并与底层 React Router 类型保持一致 (#7319)
    • useMatches() 返回类型从 RouteMatch 重命名为 UIMatch
    • LoaderArgs/ActionArgs 重命名为 LoaderFunctionArgs/ActionFunctionArgs
    • AppDataany 更改为 unknown
    • Location["state"] (useLocation.state) 从 any 更改为 unknown
    • UIMatch["data"] (useMatches()[i].data) 从 any 更改为 unknown
    • UIMatch["handle"] (useMatches()[i].handle) 从 { [k: string]: any } 更改为 unknown
    • Fetcher["data"] (useFetcher().data) 从 any 更改为 unknown
    • MetaMatch.handle (在 meta() 中使用) 从 any 更改为 unknown
    • AppData/RouteHandle 不再导出,因为它们只是 unknown 的别名

新功能

  • 新的 create-remix CLI (#6887)
    • 最值得注意的是,它删除了选择模板/堆栈的下拉菜单,改为使用 --template 标志和我们不断增长的 可用模板 列表
    • 添加了新的 --overwrite 标志 (#7062)
    • 支持 bun 包管理器 (#7074)
  • 通过 build.mode 检测构建模式 (#6964)
  • 支持通过 serverNodeBuiltinsPolyfill.globals/browserNodeBuiltinsPolyfill.globals 为 Node 全局提供 polyfill (#7269)
  • 新的 redirectDocument 实用程序,用于通过新的文档加载进行重定向 (#7040, #6842)
  • meta 参数中添加 error,以便您可以渲染错误标题等 (#7105)
  • unstable_createRemixStub 现在支持在模拟的 Remix 路由上添加 meta/links 函数 (#7186)
    • unstable_createRemixStub 不再支持路由上的 element/errorElement 属性。您必须使用 Component/ErrorBoundary 来匹配您从 Remix 路由模块中导出的内容。

其他值得注意的更改

  • Remix 现在在内部使用 React Router 的 route.lazy 方法在导航时加载路由模块 (#7133)
  • 删除了 @remix-run/node 中的 atob/btoa polyfill,改为使用内置版本 (#7206)
  • @remix-run/dev 包与 @remix-run/css-bundle 包的内容解耦 (#6982)
    • @remix-run/css-bundle 包的内容现在完全由 Remix 编译器管理。即使仍然建议您的 Remix 依赖项都使用相同的版本,此更改确保在升级 @remix-run/dev 时不会出现运行时错误,而无需升级 @remix-run/css-bundle
  • remix-serve 现在如果 3000 被占用,则会选择一个空闲端口 (#7278)
    • 如果设置了 PORT 环境变量,remix-serve 将使用该端口
    • 否则,remix-serve 将选择一个空闲端口 (3000 除非该端口已被占用)

更新的依赖项

按包分类的变更

文档和示例使用以下许可 MIT