You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 19 SSR NodeAppEngine下TanStack Query缓存水合及单例问题问询

新版Angular Node App Engine下TanStack Query SSR缓存水合实现方案

新版Angular Node App Engine支持TanStack Query的SSR缓存水合需求,只是需要调整QueryClient的共享方式——放弃传统Providers单例模式,改用请求级实例化+手动传递的方案,适配其函数式server.ts架构。以下是具体实现步骤:

1. 封装QueryClient创建逻辑

创建一个独立的工厂文件(如query-client.factory.ts),统一管理QueryClient的初始化配置,确保每个请求生成隔离的实例:

import { QueryClient } from '@tanstack/angular-query-experimental';

export function createQueryClient() {
  return new QueryClient({
    defaultOptions: {
      queries: {
        staleTime: 60 * 1000,
      },
    },
  });
}

2. Server端生成缓存并传递给应用

在server.ts中手动创建QueryClient实例,预获取数据后注入Angular应用,最后将缓存数据嵌入HTML:

import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app/app.component';
import { provideServerRendering } from '@angular/platform-server';
import { createQueryClient } from './app/query-client.factory';
import { provideAngularQuery } from '@tanstack/angular-query-experimental';

export default async function handler(req: Request) {
  // 为当前请求创建独立的QueryClient
  const queryClient = createQueryClient();

  // 预获取需要缓存的接口数据
  await queryClient.prefetchQuery({
    queryKey: ['home-page-data'],
    queryFn: () => fetch(`${process.env.API_URL}/home`).then(res => res.json()),
  });

  // 将QueryClient注入应用
  const app = await bootstrapApplication(AppComponent, {
    providers: [
      provideServerRendering(),
      provideAngularQuery(() => queryClient),
    ],
  });

  // 提取缓存并插入HTML
  const cacheData = JSON.stringify(queryClient.getQueryCache().getAll());
  const renderedHtml = await app.renderToString();
  const hydratedHtml = renderedHtml.replace(
    '</body>',
    `<script>window.__QUERY_CACHE__ = ${cacheData};</script></body>`
  );

  await app.destroy();
  return new Response(hydratedHtml, { headers: { 'Content-Type': 'text/html' } });
}

3. Client端恢复缓存

在main.ts中读取HTML中的缓存数据,初始化客户端QueryClient并恢复缓存:

import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app/app.component';
import { provideAngularQuery } from '@tanstack/angular-query-experimental';
import { QueryClient } from '@tanstack/angular-query-experimental';

// 读取server端注入的缓存
const preloadedCache = (window as any).__QUERY_CACHE__ || {};

// 初始化客户端QueryClient并恢复缓存
const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      staleTime: 60 * 1000,
    },
  },
});
queryClient.getQueryCache().restore(preloadedCache);

// 启动客户端应用
bootstrapApplication(AppComponent, {
  providers: [provideAngularQuery(() => queryClient)],
});

// 清理全局缓存变量
delete (window as any).__QUERY_CACHE__;

关键注意事项

  • 每个请求必须创建独立的QueryClient实例,避免SSR请求间的缓存污染;
  • 无需依赖全局Providers,通过手动注入的方式实现server端与应用内的QueryClient共享;
  • server端渲染完成后必须销毁应用实例,防止内存泄漏。

内容的提问来源于stack exchange,提问作者radekdob

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 02:21:08