TanStack Query 高级服务端渲染实战:Server Components、流式传输与 Next.js App Router 全指南 TanStack Query 高级服务端渲染实战Server Components、流式传输与 Next.js App Router 全指南【免费下载链接】query Powerful asynchronous state management, server-state utilities and data fetching for the web. TS/JS, React Query, Solid Query, Svelte Query and Vue Query.项目地址: https://gitcode.com/GitHub_Trending/qu/query导读本指南面向已经掌握 React Query 基础 SSR服务端渲染与水合hydration的开发者系统讲解在 TanStack Query 中如何将服务端预取prefetching、脱水/注水dehydrate/hydrate能力与React Server Components、流式 SSRstreaming SSR以及 Next.js App Router结合起来使用包括 pending 状态查询的流式脱水、数据所有权与再校验的边界设计以及免预取流式方案tanstack/react-query-next-experimental的适用场景。阅读完本文你将能够在一套 Server Components 应用中独立搭建靠近数据消费点预取 Suspense 边界级流式下发 客户端缓存水合的完整数据获取链路并理解不同方案的性能取舍。建议先阅读仓库中的 Server Rendering Hydration 指南 了解 SSR 基础再阅读 Performance Request Waterfalls 与 Prefetching Router Integration 获取背景知识。需要说明的是SSR 指南中基于initialData的方案虽然也能在 Server Components 下工作但本指南聚焦于水合 APIdehydrate/HydrationBoundary。Server Components 与 Next.js App Router本节不深入展开 Server Components 的全部细节只给一个关键结论Server Components 是保证只运行在服务器上的组件无论是首次页面访问还是页面间的路由切换它都只在服务端执行。这与 Next.jsgetServerSideProps/getStaticProps、Remixloader的始终在服务端运行类似但后者只能返回数据Server Components 能做的事情更多。而数据恰恰是 React Query 关心的核心因此本节只围绕数据展开。如何把 SSR 指南中学到的把框架 loader 中预取的数据传给应用见 Server Rendering Hydration 指南迁移到 Server Components 与 Next.js App Router最直接的思维方式是把 Server Components 当作另一种框架 loader。术语澄清Server 不等于 Server Components在此之前这些指南一直讨论服务端server与客户端client。需要特别指出这两个概念与Server Components和Client Components并不是一一对应的。Server Components 保证只在服务端运行但 Client Components 实际上可以同时在两处运行——因为在最初的服务端渲染SSR阶段Client Components 也会参与渲染。一个直观的理解方式虽然 Server Components 也会参与渲染但它们发生在loader 阶段永远在服务端而 Client Components 运行在application 阶段。这个 application 可以跑在 SSR 过程中的服务端也可以跑在浏览器里。application 到底在哪里运行、是否会经历 SSR会因框架而异。初始配置双文件拆分任何 React Query 应用的第一步都是创建queryClient并用QueryClientProvider包裹。在 Server Components 场景下各框架写法大体一致区别主要是文件名约定。由于QueryClientProvider底层依赖useContext承载它的组件文件必须标记use client// 在 Next.js 中这个文件叫app/providers.tsx use client // 因为 QueryClientProvider 底层依赖 useContext顶部必须写 use client import { environmentManager, QueryClient, QueryClientProvider, } from tanstack/react-query function makeQueryClient() { return new QueryClient({ defaultOptions: { queries: { // 使用 SSR 时通常希望把默认 staleTime 设到 0 以上 // 避免在客户端立即重新拉取 staleTime: 60 * 1000, }, }, }) } let browserQueryClient: QueryClient | undefined undefined function getQueryClient() { if (environmentManager.isServer()) { // 服务端每次都创建一个新的 query client return makeQueryClient() } else { // 浏览器只在没有现成 client 时才创建新的 // 这一点非常重要避免 React 在初始渲染时因挂起suspend // 而重新创建 client。如果创建点下方有 Suspense 边界 // 可能并不需要这样处理 if (!browserQueryClient) browserQueryClient makeQueryClient() return browserQueryClient } } export default function Providers({ children }: { children: React.ReactNode }) { // 注意如果创建 query client 的代码与可能挂起的代码之间 // 没有 Suspense 边界请避免用 useState 初始化 client // 因为初始渲染一旦挂起且没有边界React 会丢弃这个 client const queryClient getQueryClient() return ( QueryClientProvider client{queryClient}{children}/QueryClientProvider ) }然后在根布局中挂载这个 Provider// 在 Next.js 中这个文件叫app/layout.tsx import Providers from ./providers export default function RootLayout({ children, }: { children: React.ReactNode }) { return ( html langen head / body Providers{children}/Providers /body /html ) }这与 SSR 指南中的做法本质相同只是代码被拆分到了两个文件。仓库中的 examples/react/nextjs-app-prefetching 示例正是这一结构的完整可运行版本其 providers.tsx 作为use client客户端 Provider 负责包裹QueryClientProvider并挂载 Devtoolsget-query-client.ts 则导出统一的getQueryClient()。预取与数据脱水/注水先回顾使用Next.js Pages Router时如何预取、脱水再注水数据// pages/posts.tsx import { dehydrate, HydrationBoundary, QueryClient, useQuery, } from tanstack/react-query // 这里也可以是 getServerSideProps export async function getStaticProps() { const queryClient new QueryClient() await queryClient .query({ queryKey: [posts], queryFn: getPosts, }) .catch(noop) return { props: { dehydratedState: dehydrate(queryClient), }, } } function Posts() { // 这个 useQuery 也可以发生在 PostsRoute 的更深层子组件里 // 数据无论在哪一层都会立即可用 // // 注意这里用的是 useQuery 而不是 useSuspenseQuery。 // 因为数据已经被预取组件自身没有必要再挂起。 // 一旦忘记或删掉预取这里会在客户端重新拉取数据 // 而如果用了 useSuspenseQuery后果会更糟。 const { data } useQuery({ queryKey: [posts], queryFn: getPosts }) // 这个查询没有在服务端预取直到客户端才会开始请求 // 两种模式混用是完全没问题的 const { data: commentsData } useQuery({ queryKey: [posts-comments], queryFn: getComments, }) // ... } export default function PostsRoute({ dehydratedState }) { return ( HydrationBoundary state{dehydratedState} Posts / /HydrationBoundary ) }迁移到 App Router 后整体结构非常相似只是代码要重新归置。首先用一个Server Component来完成预取部分// app/posts/page.tsx import { dehydrate, HydrationBoundary, QueryClient, } from tanstack/react-query import Posts from ./posts export default async function PostsPage() { const queryClient new QueryClient() await queryClient .query({ queryKey: [posts], queryFn: getPosts, }) .catch(noop) return ( // 序列化现在简单到像传 props 一样。 // HydrationBoundary 本身是 Client Component水合会发生在那里。 HydrationBoundary state{dehydrate(queryClient)} Posts / /HydrationBoundary ) }再看客户端组件部分// app/posts/posts.tsx use client export default function Posts() { // 这个 useQuery 也可以发生在 Posts 的更深层 // 子组件里数据无论在哪一层都会立即可用 const { data } useQuery({ queryKey: [posts], queryFn: () getPosts(), }) // 这个查询没有在服务端预取直到客户端才会开始请求 // 两种模式混用是完全没问题的。 const { data: commentsData } useQuery({ queryKey: [posts-comments], queryFn: getComments, }) // ... }上面两段代码有一个讨巧的地方唯一与 Next.js 相关的只有文件名其余代码在任何支持 Server Components 的框架里写法都一致。另外需要注意的是SSR 指南中曾提到可以在每个路由外面统一包一层HydrationBoundary来省去样板代码但这种做法在 Server Components 下行不通每个页面仍需自己放置HydrationBoundary。类型提示如果使用低于5.1.3的 TypeScript 和低于18.2.8的types/react时在 async Server Components 上遇到类型错误建议将两者都升级到最新版本。作为临时规避手段也可以在内部调用该组件处加上{/* ts-expect-error Server Component */}。警告不推荐在queryFn中使用 Next.js Server Actions 来拉取数据。从客户端调用时Server Actions 会串行执行而非并行这与 React Query 的拉取与重拉取方式相冲突可能导致查询一直处于 pending 状态甚至 action 根本不会执行把 Server Action 引用直接传给queryFn还会报Only plain objects, and a few built-ins, can be passed to Server Actions...因为你必须调用action 而不是把它当作引用传递。客户端拉取数据时应使用指向 API route 的fetch或 tRPC 之类的 RPC 层。Server Actions 依然非常适合用于变更useMutation。嵌套 Server ComponentsServer Components 的一大优势是可以嵌套、可以存在于 React 树的多层从而把数据预取放到更贴近数据实际使用位置的地方和 Remix loaders 一样而不必只在应用顶层预取。最简单的形态就是一个 Server Component 渲染另一个 Server Component下面的例子为简洁起见省略了 Client Components// app/posts/page.tsx import { dehydrate, HydrationBoundary, QueryClient, } from tanstack/react-query import Posts from ./posts import CommentsServerComponent from ./comments-server export default async function PostsPage() { const queryClient new QueryClient() await queryClient .query({ queryKey: [posts], queryFn: getPosts, }) .catch(noop) return ( HydrationBoundary state{dehydrate(queryClient)} Posts / CommentsServerComponent / /HydrationBoundary ) } // app/posts/comments-server.tsx import { dehydrate, HydrationBoundary, QueryClient, } from tanstack/react-query import Comments from ./comments export default async function CommentsServerComponent() { const queryClient new QueryClient() await queryClient .query({ queryKey: [posts-comments], queryFn: getComments, }) .catch(noop) return ( HydrationBoundary state{dehydrate(queryClient)} Comments / /HydrationBoundary ) }可见在多个位置使用HydrationBoundary、为预取创建并脱水多个queryClient都是完全合法的。不过请留意由于渲染CommentsServerComponent之前先await了getPosts这会在服务端形成一条请求瀑布waterfall1. | getPosts() 2. | getComments()如果到数据源的服务端延迟不高这可能不是大问题但仍值得指出来。在 Next.js 中除了page.tsx你还可以在layout.tsx与 parallel routes 中预取数据。由于这些都隶属于路由体系Next.js 知道如何把它们并行拉取。因此如果上面的CommentsServerComponent改以 parallel route 表达上述瀑布会被自动压平。随着更多框架开始支持 Server Components它们可能采用各自的路由约定细节请查阅框架文档。备选共用一个queryClient做预取上面的示例为每个需要拉取数据的 Server Component 都新建了queryClient这是推荐做法。如果愿意也可以改成在全部 Server Components 之间复用一个实例// app/getQueryClient.tsx import { QueryClient } from tanstack/react-query import { cache } from react // cache() 的作用域按请求隔离不会在请求之间泄漏数据 const getQueryClient cache(() new QueryClient()) export default getQueryClient好处是在 Server Components 调用链上的任何位置包括工具函数都能通过getQueryClient()拿到同一个 client。代价是每次执行dehydrate(getQueryClient())都会序列化整个queryClient——其中包含之前已经序列化过、且与当前 Server Component 无关的查询纯属不必要的开销。Next.js 本身会对使用fetch()的请求去重但如果你在queryFn里用了别的方式或者使用了不会自动去重的框架那么上述单queryClient方案尽管存在重复序列化可能反而更合理。社区展望作为后续改进方向未来可能新增一个只脱水自上次dehydrateNew()以来新增查询的dehydrateNew()函数名称待定。感兴趣的读者欢迎参与共建。数据所有权与再校验在 Server Components 场景下必须认真思考数据所有权data ownership与再校验revalidation。为了说清楚原因看一个改造后的例子// app/posts/page.tsx import { dehydrate, HydrationBoundary, QueryClient, } from tanstack/react-query import Posts from ./posts export default async function PostsPage() { const queryClient new QueryClient() // 注意这里取用了 query 的返回值 const posts await queryClient.query({ queryKey: [posts], queryFn: getPosts, }) return ( HydrationBoundary state{dehydrate(queryClient)} {/* 这是新增的部分 */} divNr of posts: {posts.length}/div Posts / /HydrationBoundary ) }现在getPosts的数据同时被一个 Server Component 和一个 Client Component 渲染。首次页面渲染没有问题但问题在于当staleTime过期后查询因某种原因在客户端重新校验时会发生什么React Query 完全不知道如何重新校验 Server Component。如果它在客户端重新拉取了数据导致 React 重渲染帖子列表那么divNr of posts: {posts.length}/div就会失步out of sync。如果把staleTime: Infinity设为永不失效、让 React Query 不再重新校验就没有这个问题——但如果你当初选择 React Query这通常不是你想要的。将 React Query 与 Server Components 搭配在以下场景中最有价值应用已在用 React Query想迁移到 Server Components又不想重写全部数据获取代码希望沿用熟悉的编程范式同时按需享受 Server Components 的红利某些用例 React Query 能覆盖、而你的框架本身没有对应能力。什么时候该把 React Query 与 Server Components 组合使用很难给出放之四海而皆准的结论。如果你正从零开始搭建一个全新的 Server Components 应用建议先用框架自带的数据获取工具直到确实需要 React Query 再引入。也许永远都不需要——这完全没关系请为问题选用合适的工具。如果确实要用一个经验法则是避免在服务端渲染queryClient.query的返回值也不要把它传给其他组件哪怕是 Client Component。从 React Query 的视角看Server Components 只是预取数据的地方仅此而已。当然Server Components 与 Client Components 各自持有部分数据是完全可行的只需确保这两套现实不要失步即可。借助 Server Components 实现流式传输Next.js App Router 会把任何已经就绪的应用部分尽快流式传输到浏览器——已经完成的内容会立刻展示不必等待仍然 pending 的内容。这种流式是按Suspense边界切分的。注意创建loading.tsx文件会自动在背后生成一个Suspense边界。配合上文描述的预取模式React Query 与这种流式传输完全兼容。每个 Suspense 边界的数据就绪后Next.js 就能渲染并把完成的内容流式发给浏览器。即便你按上文那样使用useQuery也成立因为真正的挂起发生在你await预取的那一刻。从 React Query v5.40.0 起不再需要await全部预取——pending状态的查询同样可以被脱水并发送给客户端。这意味着你可以尽早发起预取不必让某个查询阻塞整个 Suspense 边界查询完成时数据会被流式推送到客户端。这非常适用于只在用户交互后才会看到的内容或者说你只想await无限查询infinite query的第一页而第二页的预取不需要阻塞渲染。要让这一切生效必须指示queryClient把 pending 查询也纳入dehydrate。这可以全局配置也可以在调用dehydrate时传入对应选项。另外还需要把getQueryClient()从app/providers.tsx中抽出来因为 Server Component 与客户端 Provider 都要用到它// app/get-query-client.ts import { environmentManager, QueryClient, defaultShouldDehydrateQuery, } from tanstack/react-query function makeQueryClient() { return new QueryClient({ defaultOptions: { queries: { staleTime: 60 * 1000, }, dehydrate: { // 把 pending 查询也纳入脱水范围 shouldDehydrateQuery: (query) defaultShouldDehydrateQuery(query) || query.state.status pending, shouldRedactErrors: (error) { // 不应吞掉 Next.js 的服务端错误—— // Next.js 正是借此识别动态页面的 // 所以我们不能对它们做 redact。 // Next.js 也会自动用更友好的 digest 帮我们 redact 错误。 return false }, }, }, }) } let browserQueryClient: QueryClient | undefined undefined export function getQueryClient() { if (environmentManager.isServer()) { // 服务端每次都创建一个新的 query client return makeQueryClient() } else { // 浏览器只在没有现成 client 时才创建新的 // 这一点非常重要避免 React 在初始渲染时因挂起 // 而重新创建 client。如果创建点下方有 Suspense 边界 // 可能并不需要这样处理 if (!browserQueryClient) browserQueryClient makeQueryClient() return browserQueryClient } }仓库示例 nextjs-app-prefetching 的 get-query-client.ts 正是这种写法的落地实现——它把shouldDehydrateQuery设为defaultShouldDehydrateQuery(query) || query.state.status pending从而保证 pending 查询也能跨过服务器/客户端边界被水合。注意该方案之所以在 Next.js 与 Server Components 下成立是因为把 Promise 传给 Client Components 时React 能在线上把 Promise 序列化。之后只需要提供HydrationBoundary不再需要await预取// app/posts/page.tsx import { dehydrate, HydrationBoundary } from tanstack/react-query import { getQueryClient } from ./get-query-client import Posts from ./posts // 因为不再 await 任何东西函数也不必是 async 了 export default function PostsPage() { const queryClient getQueryClient() // look ma, no await void queryClient .query({ queryKey: [posts], queryFn: getPosts, }) .catch(noop) return ( HydrationBoundary state{dehydrate(queryClient)} Posts / /HydrationBoundary ) }在客户端这个 Promise 会被放进 QueryCache。于是可以在Posts组件中调用useSuspenseQuery来消费这个在服务端创建的Promise// app/posts/posts.tsx use client export default function Posts() { const { data } useSuspenseQuery({ queryKey: [posts], queryFn: getPosts }) // ... }注意这里用useQuery替代useSuspenseQuery也能正确拿到该 Promise。但在这种情况下 Next.js 不会挂起组件会以pending状态渲染这同时意味着放弃了服务端渲染该内容。非 JSON 数据类型的序列化与反序列化如果查询结果包含非 JSON 数据类型可以在服务端序列化后通过dehydrate.serializeData与hydrate.deserializeData两个选项在边界两侧做序列化/反序列化从而保证服务端与客户端缓存中的数据格式一致// app/get-query-client.ts import { QueryClient, defaultShouldDehydrateQuery } from tanstack/react-query import { deserialize, serialize } from ./transformer function makeQueryClient() { return new QueryClient({ defaultOptions: { // ... hydrate: { deserializeData: deserialize, }, dehydrate: { serializeData: serialize, }, }, }) } // ...// app/posts/page.tsx import { dehydrate, HydrationBoundary, QueryClient, } from tanstack/react-query import { getQueryClient } from ./get-query-client import { serialize } from ./transformer import Posts from ./posts export default function PostsPage() { const queryClient getQueryClient() // look ma, no await void queryClient .query({ queryKey: [posts], queryFn: () getPosts().then(serialize), // -- 在服务端序列化数据 }) .catch(noop) return ( HydrationBoundary state{dehydrate(queryClient)} Posts / /HydrationBoundary ) }// app/posts/posts.tsx use client export default function Posts() { const { data } useSuspenseQuery({ queryKey: [posts], queryFn: getPosts }) // ... }现在getPosts可以返回例如Temporal日期时间对象了数据会在客户端被序列化与反序列化——前提是你的 transformer 能处理这些数据类型。完整可运行代码见 Next.js App with Prefetching 示例。流式场景下使用 Persist Adapter如果要把 persist adapter 与上面的流式 Server Components特性一起使用必须小心不要把 Promise 存进存储。既然 pending 查询可以被脱水并流式传给客户端就应该把 persister 配置为只持久化成功的查询PersistQueryClientProvider client{queryClient} persistOptions{{ persister, // 不想把 Promise 保存进 storage因此只持久化成功查询 dehydrateOptions: { shouldDehydrateQuery: defaultShouldDehydrateQuery }, }} {children} /PersistQueryClientProvider这样就保证了只有成功解析的查询才会被持久化避免对 pending Promise 做序列化引发问题。Next.js 中实验性的免预取流式方案上文推荐的预取方案之所以是首选是因为它同时压平了首次页面加载和后续页面导航两条路径上的请求瀑布。不过还存在一条实验性路线——完全跳过预取仍能让流式 SSR 工作它就是tanstack/react-query-next-experimental包。使用该包时你只需在组件里调用useSuspenseQuery就能让数据在服务端Client Component 中被拉取。结果会随着 Suspense 边界的解析从服务端流式传给客户端。如果你调用useSuspenseQuery却没有用Suspense包裹那么 HTML 响应要等该 fetch 完成后才会开始——某些场景下这正是你要的但请记住这会伤害 TTFB首字节时间。配置方式把应用包进ReactQueryStreamedHydration组件// app/providers.tsx use client import { environmentManager, QueryClient, QueryClientProvider, } from tanstack/react-query import * as React from react import { ReactQueryStreamedHydration } from tanstack/react-query-next-experimental function makeQueryClient() { return new QueryClient({ defaultOptions: { queries: { // 使用 SSR 时通常希望把默认 staleTime 设到 0 以上 // 避免在客户端立即重新拉取 staleTime: 60 * 1000, }, }, }) } let browserQueryClient: QueryClient | undefined undefined function getQueryClient() { if (environmentManager.isServer()) { // 服务端每次都创建一个新的 query client return makeQueryClient() } else { // 浏览器只在没有现成 client 时才创建新的 // 这一点非常重要避免 React 在初始渲染时因挂起 // 而重新创建 client。如果创建点下方有 Suspense 边界 // 可能并不需要这样处理 if (!browserQueryClient) browserQueryClient makeQueryClient() return browserQueryClient } } export function Providers(props: { children: React.ReactNode }) { // 注意如果创建 query client 的代码与可能挂起的代码之间 // 没有 Suspense 边界请避免用 useState 初始化 client // 因为初始渲染一旦挂起且没有边界React 会丢弃这个 client const queryClient getQueryClient() return ( QueryClientProvider client{queryClient} ReactQueryStreamedHydration {props.children} /ReactQueryStreamedHydration /QueryClientProvider ) }其工作原理可以从仓库源码中得到印证在 packages/react-query-next-experimental/src/ReactQueryStreamedHydration.tsx 中服务端通过订阅 QueryCache 的added/updated事件来记录trackedKeys并在每次 flush 时仅脱水那些新加入/更新的查询而在 packages/react-query-next-experimental/src/HydrationStreamProvider.tsx 中服务端借助 Next.js 的useServerInsertedHTML在每次 Suspense 边界完成时把序列化后的 dehydrated state 以script形式注入 HTML客户端则从window上对应数组里取出并调用onEntries完成水合——流式注水正是在这一步实现的。该源码还支持传入transformer如 superjson/devalue 风格的自定义序列化以及nonce配合 CSP选项。仓库中的 Next.js Suspense Streaming 示例 给出了完整用法。这条路线最大的优点是不再需要手工预取查询也能让 SSR 工作而且结果依旧会流式到达开发者体验与低代码复杂度都非常出色。它的缺点最好结合 Performance Request Waterfalls 指南 中那个复杂瀑布的例子来理解。带预取的 Server Components 能同时消灭首次页面加载与后续导航上的请求瀑布而这条免预取路线只压平首次加载的瀑布在页面导航时会退回到与最初例子一样的深层瀑布1. | JS for Feed 2. | getFeed() 3. | JS for GraphFeedItem 4. | getGraphDataById()这甚至比getServerSideProps/getStaticProps还要差因为后两者至少能把数据拉取与代码拉取并行起来。如果你看重 DX/迭代/上线速度、对代码复杂度敏感查询嵌套不深或者已经用useSuspenseQueries等工具并行拉取来压平请求瀑布这个权衡是划算的。两条路线或许可以组合使用但官方也还没有验证过。如果尝试了欢迎反馈结果甚至为文档贡献心得。结语Server Components 与流式渲染仍是相当新的概念社区也还在摸索 React Query 该如何融入、API 还能如何改进。官方欢迎任何建议、反馈与 bug 报告。同样很难在一篇指南里穷尽这个新范式的所有细节——如果缺少某些信息或有改进建议欢迎反馈。延伸阅读想要判断应用在同时使用 Server Components 时是否需要 React Query可阅读 Server Rendering Hydration 基础指南 与文章You Might Not Need React Query深入理解请求瀑布与性能取舍见 Performance Request Waterfalls预取与路由集成、代码分割等模式见 Prefetching Router Integration完整可运行实现参考仓库 Next.js App with Prefetching 示例 与 Next.js Suspense Streaming 示例。【免费下载链接】query Powerful asynchronous state management, server-state utilities and data fetching for the web. TS/JS, React Query, Solid Query, Svelte Query and Vue Query.项目地址: https://gitcode.com/GitHub_Trending/qu/query创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

最新新闻

CPLEX容器化部署实践:用Docker解决求解器环境依赖与多版本共存

CPLEX容器化部署实践:用Docker解决求解器环境依赖与多版本共存

简介:面向Java开发者的Docker化CPLEX部署资源,致力于解决IBM ILOG CPLEX优化求解器在容器环境中的快速集成难题。压缩包共7个文件,体量仅5KB,包含两份Dockerfile、一个可直接运行的Java示例、CPLEX属性配置、AMPL模型定义、说明文…

2026/9/9 21:17:24
Spring表达式语言SpEL:从Bean属性注入到自建规则引擎的实战指南

Spring表达式语言SpEL:从Bean属性注入到自建规则引擎的实战指南

简介:Spring SpEL(Spring Expression Language)表达式详解资料包,面向需要在Spring框架中处理动态数据绑定、复杂逻辑判断的Java开发者,适合从基础语法到AOP切点表达式用法的系统学习。资源共14个文件,以Ja…

2026/9/9 21:17:24
Serverless Framework Sandboxes 故障排查实战指南:AWS Lambda MicroVMs 部署与运行时疑难问题定位

Serverless Framework Sandboxes 故障排查实战指南:AWS Lambda MicroVMs 部署与运行时疑难问题定位

Serverless Framework Sandboxes 故障排查实战指南:AWS Lambda MicroVMs 部署与运行时疑难问题定位 【免费下载链接】serverless ⚡ Serverless Framework – Effortlessly build apps that auto-scale, incur zero costs when idle, and require minimal maintenan…

2026/9/9 21:17:24
用GTP5.4从零打造飞书编辑器:AI辅助开发实战

用GTP5.4从零打造飞书编辑器:AI辅助开发实战

1. 从零到一:为什么我会想到用“GTP5.4”写一个飞书编辑器先交代一下背景。我主要负责团队内部的知识库和文档流程管理,飞书是日常协作的主力工具。飞书的文档能力确实强,但真正用久了你会发现,默认编辑器在批量处理、复杂排版、表…

2026/9/9 21:17:24
Vue3.x集成Cesium实战:三维GIS高频功能与避坑指南

Vue3.x集成Cesium实战:三维GIS高频功能与避坑指南

简介:面向Vue3开发者的Cesium三维地图集成资源,聚焦于在Vue3单页应用中接入三维地球引擎时遇到的依赖安装、路径配置、组件生命周期管理和交互事件绑定等关键问题,适合具备前端基础、希望快速搭建三维地图功能模块的工程师。压缩包共85个文件…

2026/9/9 21:17:24
STM32F407+LAN9252 EtherCAT从站开发实战:从ESC初始化到PDO交换

STM32F407+LAN9252 EtherCAT从站开发实战:从ESC初始化到PDO交换

简介:STM32F407与LAN9252从站芯片通信的嵌入式工程源码包,面向具备单片机与SPI基础、正在学习工业以太网从站开发的软硬件工程师。包内共238个文件,以C/H源码、汇编启动文件为主,另有PDF说明、HTML文档、工程配置与原理图文件&…

2026/9/9 21:12:23