React Router v7 已发布。 查看文档
CHANGELOG.md
本页内容

Remix 版本

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

我们在此文件中管理版本说明,而不是分页的 Github 版本页面,原因有以下两点:

  • Github UI 中的分页意味着您无法轻松地一次搜索大量版本的版本说明
  • 分页的 Github 界面还会截断较长的版本说明,且列表视图中不会显示,您需要点击进入详细视图才能看到完整的版本说明
目录

v2.15.2

日期:2024-12-20

补丁更改

  • @remix-run/dev - 允许通过将 future flag 设置为 false 来抑制 future flag 警告 (#10358)
  • @remix-run/react - 抛出未包装的 Single Fetch redirect 以与 Single Fetch 之前的行为保持一致 (#10317)

更新的依赖

完整更新日志v2.15.1...v2.15.2

v2.15.1

日期:2024-12-09

补丁更改

  • create-remix - 将 fs-extradevDependencies 移至 dependencies (#10300)

完整更新日志v2.15.0...v2.15.1

v2.15.0

日期:2024-11-19

补丁更改

  • 稳定 future.v3_routeConfig future flag,替换 future.unstable_routeConfig。这支持使用 routes.ts 来辅助迁移到 React Router v7。(#10236)

    请注意,如果您已经启用了 future.unstable_routeConfig flag,那么您在 app/routes.ts 中的路由配置不再通过 routes 导出定义,现在必须通过默认导出定义。

    import { type RouteConfig } from "@remix-run/route-config";
    
    -export const routes: RouteConfig = [];
    +export default [] satisfies RouteConfig;
    

v2.14.0

日期:2024-11-08

次要更改

  • 弃用 SerializeFrom,转而使用泛型,因为它将在 React Router v7 中被删除 (#10173)

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

  • future.unstable_routeConfig flag 后添加对 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 future flag 后,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 future flag 记录弃用警告 (#10126)

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

补丁更改

  • @remix-run/react - 修复使用 Single Fetch 时 defaultShouldRevalidate 的值 (#10139)
  • @remix-run/server-runtime - 更新外部访问的资源路由警告,以涵盖 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(用于 Single Fetch)
  • unstable_flushSyncflushSync (useSubmit, fetcher.load, fetcher.submit)
  • unstable_viewTransitionviewTransition (<Link>, <Form>, useNavigate, useSubmit)
  • 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
      • Single Fetch: unstable_dataStrategy -> dataStrategy
      • 延迟路由发现:unstable_patchRoutesOnNavigation -> patchRoutesOnNavigation
    • 稳定面向公众的 API
      • Single Fetch: unstable_data() -> data()
      • unstable_viewTransition -> viewTransition (Link, Form, navigate, submit)
      • unstable_flushSync> -> <Link viewTransition> (Link, Form, navigate, submit, useFetcher)
  • 稳定 future flags (#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 作为 renderToReadableStream signal 传递,以便为 cloudflare/deno 运行时中止服务器渲染,因为当 request 被中止时,中止渲染是没有用的,因为 React 无法刷新未解析的边界 (#10047)
    • 这种情况已经不正确一段时间了,但最近才暴露出来,原因是我们在通过 remix vite:dev 运行时中止请求的方式存在错误,因为我们在成功渲染后错误地中止了请求,这导致我们中止了已完成的 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 的错误 (#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:Single Fetch:修复当 loaderactionclientLoaderclientAction 返回裸对象、json(...)defer(...)unstable_data(...) 的混合类型时的类型错误。(#9999)
  • @remix-run/node/@remix-run/cloudflare/@remix-run/deno - Single Fetch:通过运行时包重新导出 interface Future,以便 pnpm 不会抱怨 @remix-run/server-runtime 不是依赖项 (#9982)
    • 如果您已经选择加入 Single Fetch,您可以在 vite.config.ts 中更改您的 Single Fetch 类型增强,以增强 @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 调用 - 即,对于 routes/a.tsx 中的 clientLoader,调用 GET /a/b/c.data?_routes=routes/a

当一个或多个路由被排除在单次获取调用之外时,其余具有加载器的路由将作为查询参数包含在内。例如,当导航到 /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 - 处理模块预加载清单生成中的循环依赖关系(#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 实用工具,该工具将允许您在发送回原始数据的同时发送回 status/headers,而无需将其编码到 Response
  • 我们将在下一个主要版本中删除 jsondefer,但两者应该仍然可以在 v2 的单次获取中工作,以便逐步采用新行为

⚠️ 如果你已经在不稳定的状态下采用了 Single Fetch 并转换为 response stub,你需要将这些更改移回利用 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 - Single Fetch:添加一个新的 unstable_data() API 作为 json/defer 的替代方案,当需要自定义 status/headers 时使用 (#9769)
  • @remix-run/server-runtime - Single Fetch:移除 responseStub,改为使用 headers (#9769)

补丁更改

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

更新的依赖项

按包更改

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

v2.10.3

日期:2024-07-16

补丁更改

  • @remix-run/architect - 手动使用分号连接 headers,以避免 Remix 和 node/undici Headers 实现之间的差异 (#9664)
  • @remix-run/react - 记录在重新加载页面之前加载路由模块时遇到的任何错误 (#8932)
  • @remix-run/react - Single Fetch(不稳定):通过 dataStrategy 代理 request.signal 用于 loader 调用以修复取消 (#9738)
  • @remix-run/react - Single Fetch(不稳定):在底层采用 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 转发到 Form (bdd04217)
  • @remix-run/server-runtime - 修复了从加载器返回的原始原生 fetch 响应的 immutable headers 的 bug (#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 渲染也抛出错误时的 hydration 循环 (#9566)
  • @remix-run/react - 修复了当使用子路由和带有 basenameHydrateFallback 组件时的 hydration bug (#9584)
  • @remix-run/{server-runtime|react} - Single Fetch:更新到 turbo-stream@2.2.0 (#9562)
  • @remix-run/server-runtime - Single Fetch:正确处理抛出的 4xx/5xx 响应存根 (#9501)
  • @remix-run/server-runtime - Single Fetch:将重定向更改为使用 202 状态,以避免自动缓存 (#9564)
  • @remix-run/server-runtime - Single Fetch:修复了从单次获取中的资源路由返回或抛出响应存根的问题 (#9488)
  • @remix-run/server-runtime - Single Fetch:修复了从资源路由返回 null 时的错误 (#9488)

更新的依赖项

按包更改

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

v2.9.2

日期:2024-05-10

更改内容

更新 Single Fetch 的类型安全性

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

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

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 - Single Fetch:将 undefined 添加到 useActionData 类型覆盖中 (#9322)
  • @remix-run/react - Single Fetch:允许通过 <RemixServer> 在单次获取流传输内联脚本上设置 nonce (#9364)
  • @remix-run/server-runtime - Single Fetch:不要通过 handleError 记录抛出的响应存根 (#9369)
  • @remix-run/server-runtime - Single Fetch:自动将资源路由裸对象返回值包装在 json() 中,以实现 v2 中的向后兼容(并记录弃用警告)(#9349)
  • @remix-run/server-runtime - Single Fetch:将 response 存根传递给资源路由处理程序 (#9349)

更新依赖

按包变更

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

v2.9.1

日期:2024-04-24

补丁更新

  • @remix-run/dev - 修复了以下问题:将 Remix 包添加到 Vite 的 ssr.noExternal 选项中的使用者会被 Remix Vite 插件添加到 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.jsoncompilerOptions.types 数组以正确推断类型
  • 当启用单次获取时,不再使用 headers 导出,而是使用传递给 loader/action 函数的新 response 存根
  • 当使用单次获取时,json/defer/redirect 工具已弃用(但仍然大致相同)
  • 操作不再自动在 4xx/5xx 响应上重新验证 - 您可以返回 2xx 以选择重新验证或使用 shouldRevalidate

[!IMPORTANT] 单次获取需要使用 undici 作为您的 fetch polyfill,或者在 Node 20+ 上使用内置的 fetch,因为它依赖于这些 API 中可用的 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 的垃圾回收行为有所不同,并且您需要使用所有 fetch 响应正文,以避免应用程序中的内存泄漏
  • 由于 undicinode 内部使用的 fetch 实现,它应该更好地为 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 标头接口,并在启用单次获取时弃用 headers 导出 (#9142)

补丁更新

  • create-remix - 当使用 --template 标志时,允许在存储库名称中使用 . (#9026)
  • @remix-run/dev - 改进了 monorepos 中的 getDependenciesToBundle 解析 (#8848)
  • @remix-run/dev - 通过使用流式 entry.server 修复启用单次获取时的 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 插件

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

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

新的 Layout 导出

我们发现,在根路由中创建自己的组件来保存 Component/ErrorBoundary/HydrateFallback 之间的共享布局/应用外壳非常常见。这非常常见(并且还可能导致一些轻微的边缘情况问题,例如水合作用时的 FOUC),因此我们已将其作为 2.7.0 中的一级 API 纳入。

你现在可以从根路由导出可选的 Layout 组件,该组件将作为其 children 提供给你的路由组件、ErrorBoundary 或 HydrateFallback。更多信息,请参阅 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 来支持 Cloudflare 的框架无关 Vite 插件。

次要更改

  • @remix-run/react - 允许从根路由导出可选的 Layout (#8709)
  • @remix-run/cloudflare-pages - 使 Cloudflare Pages 的 getLoadContext 可选 (#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 - 修复了使用 basename 时 SPA 模式下的构建问题 (#8720)
  • @remix-run/dev - 修复了同步 routes 函数的 Remix 配置中的类型错误 (#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)
    • ⚠️ 对于使用带有 publicPath 的不稳定 Vite 插件的项目,这是一个重大更改
    • 这已通过 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:修复应用程序目录之外的路由的服务器导出死代码消除 (#8795)

更新的依赖项

按包更改

完整更改日志v2.6.0...v2.7.0

v2.6.0

日期:2024-02-01

发生了什么变化

不稳定 Vite 插件更新

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

我们还删除了 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:将 --sourcemapClient--sourcemapServer 标志添加到 remix vite:build#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:将 getRemixDevLoadContext 选项添加到 Cloudflare 预设(#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 - 将 isSpaMode 添加到 @remix-run/dev/server-build 虚拟模块(#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:如果磁盘上不存在,则不尝试加载 sourcemap(#8446
  • @remix-run/dev:修复 2024 年 1 月 1 日发布的 isbot@4 的问题(#8415
    • 现在,remix dev"isbot": "^4" 添加到 package.json 中,而不是使用 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 正在将 .server 模块替换为空模块 (export {}) 用于客户端构建
    • 现在,当从客户端代码引用 .server 模块时,Remix 会在编译时显式失败,并根据导入发生在路由模块还是非路由模块中,包含专用错误消息
    • 错误消息还包含指向相关文档的链接
  • @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: 通过在水合 clientLoader 的过程中,通过 serverLoader 传播服务器 loader 错误 (#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: 切换为在 create-remix CLI 中使用 @remix-run/web-fetch 而不是 node-fetch (#7345)

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

更新依赖项

按包查看更改

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

v2.4.0

日期: 2023-12-13

有什么变化

客户端数据

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

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

  • 跳过跳转: 直接从浏览器查询数据 API,仅使用加载器进行 SSR
  • 全栈状态: 使用客户端数据增强服务器数据,以获得完整的加载器数据集
  • 二选一: 有时使用服务器加载器,有时使用客户端加载器,但不在同一路由上同时使用两者
  • 客户端缓存: 在客户端缓存服务器加载器数据,并避免一些服务器调用
  • 迁移: 简化您从 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 函数具有区分 ClientLoaderFunctionArgs/ClientActionFunctionArgsserverLoader/serverAction 参数
  • 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 插件中删除未记录的 legacyCssImports 选项,原因是 Vite 中 CSS 文件的 ?url 导入未正确处理 (#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: 确保在 Vite 构建后,服务器构建的 assets 目录中的代码拆分 JS 文件不会被清理 (#8042)
  • @remix-run/dev: 修复 Vite 构建中从 public 目录复制 assets 时的冗余 (#8039)
    • 这确保了静态 assets 不会在服务器构建目录中重复
    • 这也修复了一个问题,即如果 assetsBuildDirectory 深度嵌套在 public 目录中,构建会中断

更新的依赖

按包变更

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

v2.3.0

日期: 2023-11-16

变更内容

稳定 useBlocker

我们从 useBlocker 钩子中删除了 unstable_ 前缀,因为它已经使用了足够长的时间,我们对 API 充满信心。由于浏览器处理 window.confirm 的方式存在差异,这阻止了 React Router 保证一致/正确的行为,因此我们不打算从 unstable_usePrompt 中删除前缀。

unstable_flushSync API

我们为命令式 API (useSubmituseNavigatefetcher.submitfetcher.load) 添加了一个新的 unstable_flushSync 选项,以允许用户选择加入同步 DOM 更新,用于待处理/乐观 UI。

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,而无需手动导入 React (#7888)
    • 修复存在在 developmentproduction 模式之间具有不同本地状态的插件(例如 @mdx-js/rollup)时 Vite 生产构建的问题 (#7911)
    • 缓存 Remix Vite 插件选项的解析 (#7908)
    • 支持 Vite 5 (#7846)
    • 允许在 Vite 开发环境中使用 "development" 以外的 process.env.NODE_ENV 值 (#7980)
    • 在 Vite 构建中,将共享块中的 CSS 附加到路由 (#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 Fast Refresh 错误 (#7842)
    • 处理 Vite 开发服务器中的多个 Set-Cookie 标头 (#7843)
    • 修复在使用自定义 Express 服务器时,Vite 开发环境中初始页面加载时出现未样式化内容闪烁的问题 (#7937)
    • 在 Vite 开发环境中,从服务器上的 .env 文件填充 process.env (#7958)
    • 在 Vite 构建中,将仅在服务器构建中引用的 assets 发射到客户端 assets 目录中 (#7892, 在 8cd31d65 中 cherry-picked)

更新的依赖

按包变更

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

v2.2.0

日期: 2023-10-31

变更内容

Vite!

Remix 2.2.0 为基于 Node 的应用程序添加了对 Vite 的不稳定支持!有关更多详细信息,请参阅我们的 公告博客文章Remix 文档中的Future > 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 实例,而无需进行 props 传递
  • Fetcher 键现在在从 useFetchers 返回的 fetcher 上公开,以便可以通过 key 查找它们
  • FormuseSubmit 现在支持可选的 navigate/fetcherKey 属性/参数,允许在底层启动一个 fetcher 提交,并可选择由用户指定 key
    • <Form method="post" navigate={false} fetcherKey="my-key">
    • submit(data, { method: "post", navigate: false, fetcherKey: "my-key" })
    • 以这种方式调用 fetcher 是临时的和无状态的。
    • 如果您需要访问这些 fetcher 的状态,您需要利用 useFetchers()useFetcher({ key }) 在其他地方查找。

持久化 Future Flag

根据上述相同的 RFC,我们引入了一个新的 future.v3_fetcherPersist 标志,允许您选择加入新的 fetcher 持久化/清理行为。fetcher 不会在卸载时立即清理,而是会一直保留到它们返回 idle 状态。这使得在原始 fetcher 需要卸载的场景中,待处理/乐观 UI 容易实现。

  • 这在某种程度上是一个长期存在的 bug 修复,因为 useFetchers() API 的初衷始终只是反映待处理/乐观 UI 的正在运行的 fetcher 信息,而不是在 fetcher 返回 idle 状态后反映 fetcher 数据或保留 fetcher。
  • 在选择加入此标志时,请留意以下特定行为更改,并检查您的应用程序的兼容性:
    • 仍在挂载时完成的 Fetcher 在完成后将不再出现在 useFetchers() 中 - 它们在那里没有作用,因为您可以通过 useFetcher().data 访问数据。
    • 先前在运行时卸载的 Fetcher 不会立即中止,而是在返回 idle 状态后进行清理。
      • 它们在运行时仍会通过 useFetchers 公开,以便您在卸载后仍然可以访问待处理/乐观数据。
      • 如果 fetcher 完成时不再挂载,则其结果将不会进行后处理 - 例如,不会遵循重定向,并且错误不会在 UI 中冒泡。
      • 但是,如果使用相同的 key 在树中的其他位置重新挂载 fetcher,那么即使原始 fetcher 已卸载,其结果也将被处理。

次要更改

  • 不稳定的 vite 支持 (#7590)
  • 用于导航 API 的新 fetcher key 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 中对 View Transitions API 的实验性支持!您现在可以触发以 document.startViewTransition 包裹的导航 DOM 更新,以便在应用程序中的 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 演示(它使用 React Router,Remix 也是如此 😉)。

有关使用 View Transitions API 的更多信息,请参阅 Google Chrome 团队的 使用 View Transitions API 实现平滑简单的转换 指南。

稳定的 createRemixStub

在经过实际经验之后,我们对 createRemixStub API 充满信心,并准备好提交它,因此在 2.1.0 中,我们删除了 unstable_ 前缀。

⚠️ 请注意,这确实涉及 1 个小的重大更改 - <RemixStub remixConfigFuture> 属性已重命名为 <RemixStub future>,以将 future 属性与特定的文件位置分离。

次要更改

  • 添加了对 View Transition API 的不稳定支持 (#10916)
  • 稳定了 @remix-run/testing createRemixStub 辅助程序 (#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 - sourcemap 会考虑输出文件中的特殊字符 (#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 现在可以正确地重新导入 CJS 中的新服务器更改。
    • ESM 项目已经正常工作,不受此影响。
  • 修复了部分写入的服务器构建引起的错误 (#7470)
    • 以前,有可能在新服务器构建完全写入之前触发重新导入应用程序服务器代码。重新导入部分写入的服务器构建会导致与 build.assets 未定义以及读取 build.assets.version 时崩溃相关的问题。
  • handle 字段向 UIMatch 添加第二个泛型 (#7464)
  • 修复了通过 route.lazy 加载的资源路由 (#7498)
  • 当提交到没有 action 的路由时,抛出一个语义正确的 405 ErrorResponse,而不是仅仅抛出一个 Error (#7423)
  • 更新到最新版本的 @remix-run/web-fetch (#7477)
  • 将文件会话存储 ID 生成从 crypto.randomBytes 切换到 crypto.webcrypto.getRandomValues (#7203)
  • 使用本机 Blob 类而不是 polyfill (#7217)

按包更改 🔗

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

v2.0.0

日期: 2023-09-15

我们非常高兴地向您发布 Remix v2,我们真的希望这次升级是您经历过的最顺利的框架升级之一!这是我们 v2 的主要目标 - 我们旨在通过大量使用弃用警告和 Remix v1 中的 Future Flags 来实现的目标。

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

如果您尚未使用最新的 1.x 版本,我们建议您首先升级到该版本并解决任何标志/控制台警告。

> npx upgrade-remix 1.19.3

重大更改

以下是 v2 中重大更改的非常简洁的列表。

  • 有关重大更改的最详尽讨论,请阅读升级到 v2指南。本文档全面介绍了 v2 带来的重大更改,以及如何调整您的应用程序以处理这些更改的说明。
  • 有关更多详细信息,您可以参考下面的按包更改部分。

升级的依赖项要求

Remix v2 已经升级了对 React 和 Node 的最低版本支持,现在正式要求:

已删除的 Future Flags

以下 future flags 已被删除,它们的行为现在是默认行为 - 您可以从 remix.config.js 文件中删除所有这些 flags。

  • 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 删除

带有弃用警告

以下列出了在 Remix v1 中有弃用警告的其他重大更改/API 删除。如果您使用的是最新的 1.19.3 版本,并且没有任何控制台警告,那么您可能可以顺利处理所有这些更改!

没有弃用警告

不幸的是,我们没有设法对每个重大更改或 API 删除都发出弃用警告 🙃。以下是您可能需要查看以升级到 v2 的其余更改列表:

  • remix.config.js
    • 默认情况下,浏览器中不再填充 Node 内置函数,您必须通过 browserNodeBuiltinsPolyfill 选择启用填充 (#7269)
    • 如果您的应用程序中存在配置文件,则默认启用 PostCSS/Tailwind,您可以通过 postcsstailwind flags 禁用此功能 (#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)
    • 删除 magic imports ESLint 警告 (#6902)
  • @remix-run/netlify
  • @remix-run/node
    • 默认情况下不再填充 fetch - 应用程序必须调用 installGlobals() 来安装填充程序 (#7009)
    • fetch 和相关 API 不再从 @remix-run/node 导出 - 应用程序应使用全局命名空间中的版本 (#7293)
    • 应用程序必须调用 sourceMapSupport.install() 来设置源代码映射支持。
  • @remix-run/react
    • 删除 unstable_shouldReload,转而使用 shouldRevalidate (#6865)
  • @remix-run/serve
    • 如果 3000 端口被占用,并且未指定 PORT,则 remix-serve 会选择一个打开的端口 (#7278)
    • 集成 manual 模式 (#7231)
    • 删除未记录的 createApp Node API (#7229)
    • 在 remix-serve 中为外部捆绑包保留动态导入 (#7173)
  • @remix-run/vercel
  • create-remix
    • 停止将 isTypeScript 传递给 remix.init 脚本 (#7099)
  • remix
    • 删除 magic exports (#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 填充节点全局变量 (#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 填充程序,转而使用内置版本 (#7206)
  • @remix-run/dev 包与 @remix-run/css-bundle 包的内容分离 (#6982)
    • @remix-run/css-bundle 包的内容现在完全由 Remix 编译器管理。即使仍然建议您的 Remix 依赖项都共享相同的版本,此更改也确保在升级 @remix-run/dev 而不升级 @remix-run/css-bundle 时不会出现运行时错误。
  • 如果 3000 端口被占用,则 remix-serve 现在会选择一个打开的端口 (#7278)
    • 如果设置了 PORT 环境变量,则 remix-serve 将使用该端口。
    • 否则,remix-serve 会选择一个开放的端口(除非 3000 端口已被占用,否则会使用 3000 端口)。

更新的依赖项

按包更改

文档和示例在以下许可下授权 MIT