此页面列出了 Remix 从 v2.0.0 开始的所有版本/版本说明。对于 v2 之前的版本,请参考 Github 版本页面。
我们在此文件中管理版本说明,而不是分页的 Github 版本页面,原因有以下两点:
日期: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
日期:2024-12-09
create-remix - 将 fs-extra 从 devDependencies 移至 dependencies (#10300)完整更新日志: v2.15.0...v2.15.1
日期: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;
日期: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)create-remix@remix-run/architect@remix-run/cloudflare@remix-run/cloudflare-pages@remix-run/cloudflare-workers@remix-run/css-bundle@remix-run/deno@remix-run/dev@remix-run/eslint-config@remix-run/express@remix-run/fs-routes@remix-run/node@remix-run/react@remix-run/route-config@remix-run/routes-option-adapter@remix-run/serve@remix-run/server-runtime@remix-run/testing完整更新日志: v2.13.1...v2.14.0
日期:2024-10-11
@remix-run/dev - 将 future.v3_optimizeDeps 恢复为 future.unstable_optimizeDeps,因为它不打算在 Remix v2 中稳定 (#10099)完整更新日志: v2.13.0...v2.13.1
日期:2024-10-11
此版本稳定了一些“不稳定”的 API,为即将发布的 React Router v7 版本做准备(有关更多信息,请参阅这些帖子)
unstable_data → data(用于 Single Fetch)unstable_flushSync → flushSync (useSubmit, fetcher.load, fetcher.submit)unstable_viewTransition → viewTransition (<Link>, <Form>, useNavigate, useSubmit)future.unstable_optimizeDeps → future.v3_optimizeDeps (文档)2.13.1 中恢复为 future.unstable_optimizeDepsfuture.unstable_lazyRouteDiscovery → future.v3_lazyRouteDiscovery (文档)future.unstable_singleFetch → future.v3_singleFetch (文档)unstable_dataStrategy -> dataStrategyunstable_patchRoutesOnNavigation -> patchRoutesOnNavigationunstable_data() -> data()unstable_viewTransition -> viewTransition (Link, Form, navigate, submit)unstable_flushSync> -> <Link viewTransition> (Link, Form, navigate, submit, useFetcher)future.unstable_lazyRouteDiscovery -> future.v3_lazyRouteDiscoveryfuture.unstable_optimizeDeps -> future.v3_optimizeDepsfuture.unstable_singleFetch -> future.v3_singleFetch@remix-run/dev - 停止将 request.signal 作为 renderToReadableStream signal 传递,以便为 cloudflare/deno 运行时中止服务器渲染,因为当 request 被中止时,中止渲染是没有用的,因为 React 无法刷新未解析的边界 (#10047)remix vite:dev 运行时中止请求的方式存在错误,因为我们在成功渲染后错误地中止了请求,这导致我们中止了已完成的 React 渲染,并尝试关闭已关闭的 ReadableStreamrequest.signalentry.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)create-remix@remix-run/architect@remix-run/cloudflare@remix-run/cloudflare-pages@remix-run/cloudflare-workers@remix-run/css-bundle@remix-run/deno@remix-run/dev@remix-run/eslint-config@remix-run/express@remix-run/node@remix-run/react@remix-run/serve@remix-run/server-runtime@remix-run/testing完整更新日志: v2.12.1...v2.13.0
日期: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:修复当 loader、action、clientLoader 或 clientAction 返回裸对象、json(...)、defer(...) 和 unstable_data(...) 的混合类型时的类型错误。(#9999)@remix-run/node/@remix-run/cloudflare/@remix-run/deno - Single Fetch:通过运行时包重新导出 interface Future,以便 pnpm 不会抱怨 @remix-run/server-runtime 不是依赖项 (#9982)vite.config.ts 中更改您的 Single Fetch 类型增强,以增强 @remix-run/node(或 cloudflare/deno),而不是 @remix-run/server-runtime完整更新日志: v2.12.0...v2.12.1
日期:2024-09-09
您现在可以通过使用 future.unstable_optimizeDeps 未来标志来选择在开发期间进行自动依赖优化。有关详细信息,请查看指南 > 依赖优化中的文档。对于之前为了解决此限制的用户,您不再需要显式地将路由添加到 Vite 的 optimizeDeps.entries,也不需要禁用 remix-dot-server 插件。
tsconfig.json > compilerOptions > types 中删除 "@remix-run/react/future/single-fetch.d.ts" 覆盖defineLoader、defineAction、defineClientLoader、defineClientAction 辅助函数UIMatch_SingleFetch 类型辅助函数替换为原始的 UIMatchMetaArgs_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 选择不进行重新验证clientLoaderclientLoader 中调用 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)v1.18.0 中通过 #6409 添加的逻辑1.18.0 中添加的 URL 比较结果发现其自身存在误报,这也会将用户置于循环场景中@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
日期: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
日期:2024-08-05
@remix-run/react - 回滚 #9695,停止无限重新加载(a7cffe57)完整更改日志:v2.11.0...v2.11.1
日期: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() 而不 设置自定义 status 或 headers,则只需删除这些实用函数并返回原始数据即可return json({ data: "whatever" });return { data: "whatever" };json/defer 返回自定义 status 或 headersunstable_data 实用工具,该工具将允许您在发送回原始数据的同时发送回 status/headers,而无需将其编码到 Response 中json 和 defer,但两者应该仍然可以在 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)create-remix@remix-run/architect@remix-run/cloudflare@remix-run/cloudflare-pages@remix-run/cloudflare-workers@remix-run/css-bundle@remix-run/deno@remix-run/dev@remix-run/eslint-config@remix-run/express@remix-run/node@remix-run/react@remix-run/serve@remix-run/server-runtime@remix-run/testing完整变更日志: v2.10.3...v2.11.0
日期: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 参数稳定为 actionStatusunstable_actionStatus 参数,这可能对你的应用程序来说是一个重大更改create-remix@remix-run/architect@remix-run/cloudflare@remix-run/cloudflare-pages@remix-run/cloudflare-workers@remix-run/css-bundle@remix-run/deno@remix-run/dev@remix-run/eslint-config@remix-run/express@remix-run/node@remix-run/react@remix-run/serve@remix-run/server-runtime@remix-run/testing完整变更日志: v2.10.2...v2.10.3
日期:2024-07-04
@remix-run/react - 将 ref 转发到 Form (bdd04217)@remix-run/server-runtime - 修复了从加载器返回的原始原生 fetch 响应的 immutable headers 的 bug (#9693)create-remix@remix-run/architect@remix-run/cloudflare@remix-run/cloudflare-pages@remix-run/cloudflare-workers@remix-run/css-bundle@remix-run/deno@remix-run/dev@remix-run/eslint-config@remix-run/express@remix-run/node@remix-run/react@remix-run/serve@remix-run/server-runtime@remix-run/testing完整变更日志: v2.10.1...v2.10.2
日期:2024-07-03
@remix-run/react - 战争迷雾(不稳定):支持从 <Form> 组件发现路由 (#9665)@remix-run/react - 战争迷雾(不稳定):不要发现带有 reloadDocument 的链接/表单 (#9686)create-remix@remix-run/architect@remix-run/cloudflare@remix-run/cloudflare-pages@remix-run/cloudflare-workers@remix-run/css-bundle@remix-run/deno@remix-run/dev@remix-run/eslint-config@remix-run/express@remix-run/node@remix-run/react@remix-run/serve@remix-run/server-runtime@remix-run/testing完整变更日志: v2.10.0...v2.10.1
日期:2024-06-25
Remix 中的“战争迷雾”功能,现在可以通过 future.unstable_fogOfWar 标志使用,是一种优化,可以减少 Remix 路由清单的预加载大小。在大多数情况下,Remix 路由清单不会非常大,以至于会影响初始性能指标,但我们发现在大规模情况下,某些应用程序可能会生成很大的清单,这些清单在应用程序启动时下载和执行的成本很高。
启用战争迷雾后,Remix 将仅在清单中包含最初服务器渲染的路由,然后在用户导航时为传出的链接获取清单“补丁”。默认情况下,为了避免瀑布效应,Remix 会获取所有渲染链接的补丁,以便在理想情况下,它们在被点击之前就已经打过补丁。如果用户在急切的发现完成之前点击链接,则会发生一个小瀑布,首先“发现”路由,然后导航到该路由。
启用此标志不需要更改应用程序代码。有关更多信息,请参阅文档。
@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 - 修复了当使用子路由和带有 basename 的 HydrateFallback 组件时的 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)create-remix@remix-run/architect@remix-run/cloudflare@remix-run/cloudflare-pages@remix-run/cloudflare-workers@remix-run/css-bundle@remix-run/deno@remix-run/dev@remix-run/eslint-config@remix-run/express@remix-run/node@remix-run/react@remix-run/serve@remix-run/server-runtime@remix-run/testing完整变更日志: v2.9.2...v2.10.0
日期:2024-05-10
在 2.9.2 中,我们增强了选择加入 future.unstable_singleFetch 功能时的类型安全性。之前,我们将 response 存根添加到 LoaderFunctionArgs 中,并使用类型覆盖来推断 useLoaderData 等,但我们发现这还不够。
在此版本中,我们引入了新函数来帮助在使用单次获取时进行类型推断 - defineLoader/defineAction 及其客户端对应项 defineClientLoader 和 defineClientAction。这些是恒等函数;它们不会在运行时修改你的加载器或操作。相反,它们的存在仅仅是为了通过为 args 提供类型并确保有效的返回类型来实现类型安全。
export const loader = defineLoader(({ request }) => {
// ^? Request
return { a: 1, b: () => 2 };
// ^ type error: `b` is not serializable
});
请注意,如果你不关心类型安全,则在定义加载器和操作时,技术上不需要 defineLoader 和 defineAction
// 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 - 单次获取的类型安全:defineLoader、defineClientLoader、defineAction、defineClientAction (#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)@remix-run/cloudflare@remix-run/cloudflare-pages@remix-run/cloudflare-workers@remix-run/css-bundle@remix-run/deno@remix-run/dev@remix-run/eslint-config@remix-run/express@remix-run/node@remix-run/react@remix-run/serve@remix-run/server-runtime@remix-run/testing完整更新日志: v2.9.1...v2.9.2
日期: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
日期:2024-04-23
2.9.0 引入了 future.unstable_singleFetch 标志,以便在您的 Remix 应用程序中启用单次获取行为 (RFC)。请参阅文档以获取完整详细信息,但需要注意的高级更改包括:
loader/action 函数返回的裸对象不再自动序列化为 JSON 响应turbo-stream 按原样流式传输,该流允许直接序列化更复杂的类型,例如 Promise、Date、Map 实例等等tsconfig.json 的 compilerOptions.types 数组以正确推断类型headers 导出,而是使用传递给 loader/action 函数的新 response 存根json/defer/redirect 工具已弃用(但仍然大致相同)4xx/5xx 响应上重新验证 - 您可以返回 2xx 以选择重新验证或使用 shouldRevalidate[!IMPORTANT] 单次获取需要使用
undici作为您的 fetch polyfill,或者在 Node 20+ 上使用内置的 fetch,因为它依赖于这些 API 中可用的 API,而不是@remix-run/web-fetchpolyfill。请参阅下面的 Undici 部分以获取更多详细信息。
- 如果您正在管理自己的服务器并调用
installGlobals(),您将需要调用installGlobals({ nativeFetch: true }),以避免在使用单次获取时出现运行时错误- 如果您正在使用
remix-serve,如果启用了单次获取,它将自动使用undici
Remix 2.9.0 添加了一个新的 installGlobals({ nativeFetch: true }) 标志,以选择使用 undici 作为 Web Fetch polyfill,而不是 @remix-run/web-* 包。此更改有几个主要好处:
undici 而“修复”,因此请注意“破坏性的错误修复”,并留意您在应用程序中执行的任何高级 fetch API 交互undici 的行为可能在设计上有所不同 - 最值得注意的是,undici 的垃圾回收行为有所不同,并且您需要使用所有 fetch 响应正文,以避免应用程序中的内存泄漏undici 是 node 内部使用的 fetch 实现,它应该更好地为 Remix 应用程序做好准备,以便更顺利地删除 polyfill,以在 node 20+ 上使用内置的 Node.js APIfuture.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)create-remix@remix-run/architect@remix-run/cloudflare@remix-run/cloudflare-pages@remix-run/cloudflare-workers@remix-run/css-bundle@remix-run/deno@remix-run/dev@remix-run/eslint-config@remix-run/express@remix-run/node@remix-run/react@remix-run/serve@remix-run/server-runtime@remix-run/testing完整更新日志: v2.8.1...v2.9.0
日期:2024-03-07
@remix-run/dev - Vite:支持在运行 remix reveal 和 remix 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)create-remix@remix-run/architect@remix-run/cloudflare@remix-run/cloudflare-pages@remix-run/cloudflare-workers@remix-run/css-bundle@remix-run/deno@remix-run/dev@remix-run/eslint-config@remix-run/express@remix-run/node@remix-run/react@remix-run/serve@remix-run/server-runtime@remix-run/testing完整更新日志: v2.8.0...v2.8.1
日期: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)create-remix@remix-run/architect@remix-run/cloudflare@remix-run/cloudflare-pages@remix-run/cloudflare-workers@remix-run/css-bundle@remix-run/deno@remix-run/dev@remix-run/eslint-config@remix-run/express@remix-run/node@remix-run/react@remix-run/serve@remix-run/server-runtime@remix-run/testing完整更新日志: v2.7.2...v2.8.0
日期:2024-02-21
@remix-run/dev - Vite:修复了构建包含 .css?url 导入的项目时出现的错误 (#8829)日期:2024-02-20
@remix-run/cloudflare-pages - 修复了破坏性更改,并在 getLoadContext 参数中恢复了 Cloudflare 事件上下文字段,以实现向后兼容性 (#8819)日期:2024-02-20
我们很高兴地宣布,Remix 2.7.0 中对 Vite 的支持现在是稳定的!自从 Remix Vite 的初始不稳定版本发布以来,我们一直在努力改进和扩展它,并在过去几个月中获得了所有早期采用者和社区贡献者的帮助。这也意味着,诸如 SPA 模式、服务器捆绑包和 basename 支持等仅 Vite 的功能现在也正式稳定了😊。
Layout 导出我们发现,在根路由中创建自己的组件来保存 Component/ErrorBoundary/HydrateFallback 之间的共享布局/应用外壳非常常见。这非常常见(并且还可能导致一些轻微的边缘情况问题,例如水合作用时的 FOUC),因此我们已将其作为 2.7.0 中的一级 API 纳入。
你现在可以从根路由导出可选的 Layout 组件,该组件将作为其 children 提供给你的路由组件、ErrorBoundary 或 HydrateFallback。更多信息,请参阅 Layout 文档 和 RFC。
React Router 长期以来一直支持 basename 配置,该配置允许你在子路径(例如 https:///myapp/*)中提供你的应用程序,而无需在所有路由路径中包含 /myapp 段。最初,Remix 中省略了此功能,因为 v1 的嵌套文件夹文件约定使得将你的路由文件放置在 routes/myapp/ 文件夹中非常容易,从而为你提供了相同的功能。社区中也有一个 开放提案 来添加此功能。
此后发生了两件事,使我们重新考虑了缺少 basename 支持的问题
myapp. 前缀的方式变得远不符合人体工程学base 配置,该配置经常(并且容易)与 React Router basename 的概念混淆(而实际上它更符合旧的 Remix publicPath 配置)在 2.7.0 中,我们已在 Vite 插件配置中添加了对 basename 的支持。更多信息,请查看 basename 文档。
注意:这是一个仅限 Vite 的功能,不能通过 esbuild 编译器使用。
⚠️ 对于依赖不稳定 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 的代理环境兼容remixCloudflareDevProxy 可以将 ssr.resolve.externalConditions 设置为与 workerd 兼容remixCloudflareDevProxy 接受一个 getLoadContext 函数,该函数取代了旧的 getRemixDevLoadContextgetBindingsProxy 或 getPlatformProxy 的 nightly 版本,则不再需要这些getBindingsProxy 或 getPlatformProxy 的任何选项现在都应该传递给 remixCloudflareDevProxy@remix-run/react - 允许从根路由导出可选的 Layout (#8709)@remix-run/cloudflare-pages - 使 Cloudflare Pages 的 getLoadContext 可选 (#8701)(context) => ({ env: context }),这是我们过去在所有模板中使用的@remix-run/dev - Vite:Cloudflare 代理作为 Vite 插件 (#8749)@remix-run/dev - Vite:向 Vite 插件添加新的 basename 选项,允许用户设置内部 React Router basename,以便在子路径下提供他们的应用程序 (#8145)@remix-run/dev - Vite:通过删除所有 unstable_ / Unstable_ 前缀来稳定 Remix Vite 插件、Cloudflare 预设和所有相关类型 (#8713)@remix-run/dev - Vite:通过将 Remix vite 插件配置从 unstable_ssr -> ssr 重命名来稳定“SPA 模式” (#8692)@remix-run/express - 使用 req.originalUrl 而不是 req.url,以便 Remix 看到完整的 URL (#8145)@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)npm run start 已重命名为 npm run preview,它使用 vite preview 而不是独立的 HTTP 服务器(例如 http-server 或 serv-cli)@remix-run/dev - Vite:删除将 publicPath 作为选项传递给 Remix vite 插件的功能 (#8145)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:修复应用程序目录之外的路由的服务器导出死代码消除 (#8795)create-remix@remix-run/architect@remix-run/cloudflare@remix-run/cloudflare-pages@remix-run/cloudflare-workers@remix-run/css-bundle@remix-run/deno@remix-run/dev@remix-run/eslint-config@remix-run/express@remix-run/node@remix-run/react@remix-run/serve@remix-run/server-runtime@remix-run/testing完整更改日志: v2.6.0...v2.7.0
日期:2024-02-01
在我们继续朝着稳定 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)
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)
⚠️ 这对使用 assetsBuildDirectory 和 serverBuildDirectory 选项的 Vite 插件使用者来说是一项重大更改
这取代了旧的 assetsBuildDirectory 和 serverBuildDirectory 选项,它们的默认值分别为 "build/client" 和 "build/server"。
Remix Vite 插件现在构建到一个包含 client 和 server 目录的单个目录中。
如果您自定义了构建输出目录,则需要迁移到新的 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/client 和 build/server 目录中(#8599)
manifest.json 文件的使用者来说是一项重大更改manifest.json。build/.vite/client-manifest.json 和 build/.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)
--sourcemapClient、--sourcemapClient=inline 或 --sourcemapClient=hidden--sourcemapServer、--sourcemapServer=inline 或 --sourcemapServer=hidden@remix-run/dev - Vite:验证从 serverBundles 函数返回的 ID,以确保它们仅包含字母数字字符、连字符和下划线(#8598)
@remix-run/dev - Vite:修复“无法快速刷新”的误报(#8580)
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_ServerBundlesFunction 和 Unstable_VitePluginConfig 类型(#8654)
create-remix@remix-run/architect@remix-run/cloudflare@remix-run/cloudflare-pages@remix-run/cloudflare-workers@remix-run/css-bundle@remix-run/deno@remix-run/dev@remix-run/eslint-config@remix-run/express@remix-run/node@remix-run/react@remix-run/serve@remix-run/server-runtime@remix-run/testing完整更新日志: v2.5.1...v2.6.0
日期:2024-01-18
create-remix - 用于标题颜色的高对比度前景/背景(#8503)bgWhite 和 whiteBright 在许多终端颜色主题中是相同的颜色,这导致它呈现为难以辨认的白底白字。@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 以使用正在运行的分析会话初始化开发服务器。@remix-run/dev - Vite:通过在相关文件更改时而不是在每个请求时使 Remix 的虚拟模块失效,从而提高开发服务器请求的性能(#8164)@remix-run/react - 从 Blocker/BlockerFunction 类型中删除遗留的 unstable_ 前缀(#8530)@remix-run/react - 仅在 SPA 模式下在 <Meta>/<Links> 中使用活动匹配项(#8538)create-remix@remix-run/architect@remix-run/cloudflare@remix-run/cloudflare-pages@remix-run/cloudflare-workers@remix-run/css-bundle@remix-run/deno@remix-run/dev@remix-run/eslint-config@remix-run/express@remix-run/node@remix-run/react@remix-run/serve@remix-run/server-runtime@remix-run/testing完整更新日志: v2.5.0...v2.5.1
日期:2024-01-11
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";
},
}),
],
});
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@3 和 isbot@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,转而使用单独的 serverBuildDirectory 和 serverBuildFile 选项(#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)create-remix@remix-run/architect@remix-run/cloudflare@remix-run/cloudflare-pages@remix-run/cloudflare-workers@remix-run/css-bundle@remix-run/deno@remix-run/dev@remix-run/eslint-config@remix-run/express@remix-run/node@remix-run/react@remix-run/serve@remix-run/server-runtime@remix-run/testing完整变更日志: v2.4.1...v2.5.0
日期: 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:dev 和 vite:build 命令添加到 Remix CLI (#8211)
为了处理即将推出的 Remix 功能,其中您的插件选项可能会影响所需的 Vite 构建数量,您现在应该通过 Remix CLI 运行您的 Vite dev 和 build 进程。
{
"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 模块不同,主要思想不是阻止代码泄漏到服务器构建中,因为客户端构建已经是公开的.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)
create-remix@remix-run/architect@remix-run/cloudflare@remix-run/cloudflare-pages@remix-run/cloudflare-workers@remix-run/css-bundle@remix-run/deno@remix-run/dev@remix-run/eslint-config@remix-run/express@remix-run/node@remix-run/react@remix-run/serve@remix-run/server-runtime@remix-run/testing完整变更日志: v2.4.0...v2.4.1
日期: 2023-12-13
我们很高兴在此版本中推出 客户端数据 RFC!最终 API 与 RFC 略有不同,因此请查看文档以了解用例和最终 API
虽然我们仍然建议在 Remix 应用程序中将服务器加载器/操作用于您的大部分数据需求,但这些功能提供了一些您可以利用的杠杆,以用于更高级的用例,例如
future.v3_relativeSplatPath我们引入了 future.v3_relativeSplatPath 标志,以实现当在 splat 路由内部时,相对路由的一个破坏性错误修复。有关更多信息,请参阅 React Router 6.21.0 版本说明和 useResolvedPath 文档
Remix 现在将 .server 目录中的模块排除在客户端构建之外。
Remix 现在强制执行严格的路由导出,如果您在路由模块中有不受支持的导出,将会抛出错误。以前,Remix 编译器会允许从路由导出任何内容。虽然这很方便,但它也是错误的常见来源,这些错误很难追踪,因为它们仅在运行时出现。有关更多信息,请参阅 文档。
clientLoader/clientAction/HydrateFallback 路由导出的支持 (#8173)future.v3_relativeSplatPath 标志,以实现当在 splat 路由内部时,相对路由的一个破坏性错误修复 (#8216)DataFunctionArgs,改用 LoaderFunctionArgs/ActionFunctionArgs (#8173)clientLoader/clientActon 函数具有区分 ClientLoaderFunctionArgs/ClientActionFunctionArgs 的 serverLoader/serverAction 参数.server 目录中的模块排除在客户端构建之外 (#8154)@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)
build/server 而不是 build,客户端现在编译到 build/client 而不是 public@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_createViteServer 和 unstable_loadViteServerBuild,这些函数在使用自定义服务器时仅是 Vite 的 createServer 和 ssrLoadModule 函数的最小包装器 (#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 模块不同,主要思想不是阻止代码泄漏到服务器构建中,因为客户端构建已经是公开的.client 模块导入代码,而不会导致编译失败,然后依赖运行时检查来确定代码是在服务器端还是客户端运行.client 模块替换为空模块会导致构建失败,因为 ESM 命名导入是静态分析的@remix-run/dev: 将 @remix-run/node 添加到 Vite 的 optimizeDeps.include 数组中 (#8177)
@remix-run/dev: 提升 Vite 插件性能 (#8121)
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-run/dev: 修复使用 Vite 开发服务器时 request instanceof Request 检查 (#8062)
create-remix@remix-run/architect@remix-run/cloudflare@remix-run/cloudflare-pages@remix-run/cloudflare-workers@remix-run/css-bundle@remix-run/deno@remix-run/dev@remix-run/eslint-config@remix-run/express@remix-run/node@remix-run/react@remix-run/serve@remix-run/server-runtime@remix-run/testing完整变更日志: v2.3.1...v2.4.0
日期: 2023-11-22
@remix-run/dev: 支持 Vite 开发环境中的 LiveReload 组件上的 nonce 属性 (#8014)@remix-run/dev: 确保在 Vite 构建后,服务器构建的 assets 目录中的代码拆分 JS 文件不会被清理 (#8042)@remix-run/dev: 修复 Vite 构建中从 public 目录复制 assets 时的冗余 (#8039)assetsBuildDirectory 深度嵌套在 public 目录中,构建会中断create-remix@remix-run/architect@remix-run/cloudflare@remix-run/cloudflare-pages@remix-run/cloudflare-workers@remix-run/css-bundle@remix-run/deno@remix-run/dev@remix-run/eslint-config@remix-run/express@remix-run/node@remix-run/react@remix-run/serve@remix-run/server-runtime@remix-run/testing完整变更日志: v2.3.0...v2.3.1
日期: 2023-11-16
useBlocker我们从 useBlocker 钩子中删除了 unstable_ 前缀,因为它已经使用了足够长的时间,我们对 API 充满信心。由于浏览器处理 window.confirm 的方式存在差异,这阻止了 React Router 保证一致/正确的行为,因此我们不打算从 unstable_usePrompt 中删除前缀。
unstable_flushSync API我们为命令式 API (useSubmit、useNavigate、fetcher.submit、fetcher.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 编译器进行了大量小修复LiveReload 组件 (#7919)Scripts 之后渲染 LiveReload 组件 (#7919)pnpm 的自定义服务器的 react-refresh/babel 解析 (#7904).jsx 文件中使用 JSX,而无需手动导入 React (#7888)development 和 production 模式之间具有不同本地状态的插件(例如 @mdx-js/rollup)时 Vite 生产构建的问题 (#7911)"development" 以外的 process.env.NODE_ENV 值 (#7980)/@fs 处理项目根目录之外的文件 (#7913)server.fs.allow 明确选择加入@remix-run/react (#7926)remix-react-proxy 插件不处理默认的客户端和服务器入口文件,因为这些文件来自 node_modules 内Error: You must render this element inside a <Remix> elementdefer 时加载时的 React Fast Refresh 错误 (#7842)Set-Cookie 标头 (#7843).env 文件填充 process.env (#7958)8cd31d65 中 cherry-picked)create-remix@remix-run/architect@remix-run/cloudflare@remix-run/cloudflare-pages@remix-run/cloudflare-workers@remix-run/css-bundle@remix-run/deno@remix-run/dev@remix-run/eslint-config@remix-run/express@remix-run/node@remix-run/react@remix-run/serve@remix-run/server-runtime@remix-run/testing完整变更日志: v2.2.0...v2.3.0
日期: 2023-10-31
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 请求委托给 VitecreateRequestHandler:现在还允许 build 参数是一个函数,该函数将用于在开发期间为每个请求动态加载新的构建npm 互操作工作根据此 RFC,我们引入了一些新的 API,使您可以更精细地控制 fetcher 行为
useFetcher({ key: string }) 指定自己的 fetcher 标识符,这允许您从应用程序中的不同组件访问同一个 fetcher 实例,而无需进行 props 传递useFetchers 返回的 fetcher 上公开,以便可以通过 key 查找它们Form 和 useSubmit 现在支持可选的 navigate/fetcherKey 属性/参数,允许在底层启动一个 fetcher 提交,并可选择由用户指定 key。<Form method="post" navigate={false} fetcherKey="my-key">submit(data, { method: "post", navigate: false, fetcherKey: "my-key" })useFetchers() 或 useFetcher({ key }) 在其他地方查找。根据上述相同的 RFC,我们引入了一个新的 future.v3_fetcherPersist 标志,允许您选择加入新的 fetcher 持久化/清理行为。fetcher 不会在卸载时立即清理,而是会一直保留到它们返回 idle 状态。这使得在原始 fetcher 需要卸载的场景中,待处理/乐观 UI 更容易实现。
useFetchers() API 的初衷始终只是反映待处理/乐观 UI 的正在运行的 fetcher 信息,而不是在 fetcher 返回 idle 状态后反映 fetcher 数据或保留 fetcher。useFetchers() 中 - 它们在那里没有作用,因为您可以通过 useFetcher().data 访问数据。idle 状态后进行清理。useFetchers 公开,以便您在卸载后仍然可以访问待处理/乐观数据。key 在树中的其他位置重新挂载 fetcher,那么即使原始 fetcher 已卸载,其结果也将被处理。vite 支持 (#7590)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。create-remix@remix-run/architect@remix-run/cloudflare@remix-run/cloudflare-pages@remix-run/cloudflare-workers@remix-run/css-bundle@remix-run/deno@remix-run/dev@remix-run/eslint-config@remix-run/express@remix-run/node@remix-run/react@remix-run/serve@remix-run/server-runtime@remix-run/testing完整变更日志: v2.1.0...v2.2.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 属性与特定的文件位置分离。
SerializeFrom 中模拟 JSON.parse(JSON.stringify(x)) 的类型 (#7605)undefined 的类型字段现在被省略,因为 JSON.stringify |> JSON.parse 将省略它们。有关示例,请参阅测试用例。tagName 时避免修改 meta 对象 (#7594)route.lazy 路由时出现的 FOUC (#7576)useMatches 包装器以修复 UIMatch 类型 (#7551)@remix-run/cloudflare - sourcemap 会考虑输出文件中的特殊字符 (#7574)@remix-run/express - 为 text/event-stream 响应刷新标头 (#7619)create-remix@remix-run/architect@remix-run/cloudflare@remix-run/cloudflare-pages@remix-run/cloudflare-workers@remix-run/css-bundle@remix-run/deno@remix-run/dev@remix-run/eslint-config@remix-run/express@remix-run/node@remix-run/react@remix-run/serve@remix-run/server-runtime@remix-run/testing完整变更日志: v2.0.1...v2.1.0
日期: 2023-09-21
getDependenciesToBundle 以处理没有主导出的 ESM 包 (#7272)exports 字段中公开 package.json,以便可以解析其路径。serverBuildPath 扩展名为 .cjs 的服务器构建问题 (#7180)remix-serve 和手动模式 (remix dev --manual) 的 CJS 项目的 HMR (#7487)require 缓存,remix-serve 现在可以正确地重新导入 CJS 中的新服务器更改。build.assets 未定义以及读取 build.assets.version 时崩溃相关的问题。handle 字段向 UIMatch 添加第二个泛型 (#7464)route.lazy 加载的资源路由 (#7498)action 的路由时,抛出一个语义正确的 405 ErrorResponse,而不是仅仅抛出一个 Error (#7423)@remix-run/web-fetch (#7477)crypto.randomBytes 切换到 crypto.webcrypto.getRandomValues (#7203)Blob 类而不是 polyfill (#7217)完整变更日志: v2.0.0...v2.0.1
日期: 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 中重大更改的非常简洁的列表。
Remix v2 已经升级了对 React 和 Node 的最低版本支持,现在正式要求:
以下 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)以下列出了在 Remix v1 中有弃用警告的其他重大更改/API 删除。如果您使用的是最新的 1.19.3 版本,并且没有任何控制台警告,那么您可能可以顺利处理所有这些更改!
remix.config.js
browserBuildDirectory 重命名为 assetsBuildDirectory (#6900)devServerBroadcastDelay (#7063)devServerPort 重命名为 dev.port (000457e0)1.x 版本中选择启用此功能,则您的配置标志将为 future.v2_dev.port,但在稳定的 2.x 版本中,它将为 dev.port。serverModuleFormat 从 cjs 更改为 esm (#6949)serverBuildTarget (#6896)serverBuildDirectory 更改为 serverBuildPath (#6897)serverNodeBuiltinsPolyfill 选择启用填充 (#6911)@remix-run/react
useTransition (#6870)fetcher.type 并展平 fetcher.submission (#6874)<fetcher.Form method="get"> 现在更准确地归类为 state:"loading",而不是 state:"submitting",以便更好地与底层 GET 请求对齐。imagesrcset/imagesizes 的驼峰式版本 (#6936)不幸的是,我们没有设法对每个重大更改或 API 删除都发出弃用警告 🙃。以下是您可能需要查看以升级到 v2 的其余更改列表:
remix.config.js
browserNodeBuiltinsPolyfill 选择启用填充 (#7269)postcss 和 tailwind flags 禁用此功能 (#6909)@remix-run/cloudflare
@remix-run/dev
@remix-run/eslint-config
@remix-run/netlify
@remix-run/netlify 适配器,转而使用 Netlify 官方适配器 (#7058)@remix-run/node
fetch - 应用程序必须调用 installGlobals() 来安装填充程序 (#7009)fetch 和相关 API 不再从 @remix-run/node 导出 - 应用程序应使用全局命名空间中的版本 (#7293)sourceMapSupport.install() 来设置源代码映射支持。@remix-run/react
unstable_shouldReload,转而使用 shouldRevalidate (#6865)@remix-run/serve
@remix-run/vercel
@remix-run/vercel 适配器,转而使用 Vercel 提供的开箱即用功能 (#7035)create-remix
isTypeScript 传递给 remix.init 脚本 (#7099)remix
future.v2_meta 类型中删除了 V2_ 前缀,因为它们现在是默认行为 (#6958)V2_MetaArgs -> MetaArgsV2_MetaDescriptor -> MetaDescriptorV2_MetaFunction -> MetaFunctionV2_MetaMatch -> MetaMatchV2_MetaMatches -> MetaMatchesV2_ServerRuntimeMetaArgs -> ServerRuntimeMetaArgsV2_ServerRuntimeMetaDescriptor -> ServerRuntimeMetaDescriptorV2_ServerRuntimeMetaFunction -> ServerRuntimeMetaFunctionV2_ServerRuntimeMetaMatch -> ServerRuntimeMetaMatchV2_ServerRuntimeMetaMatches -> ServerRuntimeMetaMatchesunknown 而不是 any,并与底层 React Router 类型对齐 (#7319)useMatches() 返回类型从 RouteMatch 重命名为 UIMatchLoaderArgs/ActionArgs 重命名为 LoaderFunctionArgs/ActionFunctionArgsAppData 从 any 更改为 unknownLocation["state"] (useLocation.state) 从 any 更改为 unknownUIMatch["data"] (useMatches()[i].data) 从 any 更改为 unknownUIMatch["handle"] (useMatches()[i].handle) 从 { [k: string]: any } 更改为 unknownFetcher["data"] (useFetcher().data) 从 any 更改为 unknownMetaMatch.handle (在 meta() 中使用) 从 any 更改为 unknownAppData/RouteHandle 不再导出,因为它们只是 unknown 的别名。create-remix CLI (#6887)
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 路由模块导出的内容。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 时不会出现运行时错误。remix-serve 现在会选择一个打开的端口 (#7278)PORT 环境变量,则 remix-serve 将使用该端口。remix-serve 会选择一个开放的端口(除非 3000 端口已被占用,否则会使用 3000 端口)。react-router-dom@6.16.0@remix-run/router@1.9.0@remix-run/web-fetch@4.4.0@remix-run/web-file@3.1.0@remix-run/web-stream@1.1.0create-remix@remix-run/architect@remix-run/cloudflare@remix-run/cloudflare-pages@remix-run/cloudflare-workers@remix-run/css-bundle@remix-run/deno@remix-run/dev@remix-run/eslint-config@remix-run/express@remix-run/node@remix-run/react@remix-run/serve@remix-run/server-runtime@remix-run/testing