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

为何多数Jaspr组件需添加@client注解?(Dart)

Jaspr中无客户端逻辑的页面组件为何必须添加@client注解?

错误原因:Jaspr的代码拆分与水合机制

你遇到的AssetNotFoundException本质是Jaspr的构建逻辑约束导致的:所有路由页面组件必须标记为@client,不管组件有没有客户端交互逻辑。核心原因在于:

  • Jaspr采用服务端渲染(SSR)+客户端水合(Hydration)的混合模式,客户端需要匹配服务端渲染的DOM结构,这就要求页面组件的代码必须存在于客户端包中。
  • @client注解的核心作用不是标记"有客户端逻辑",而是告诉构建工具:该组件需要被打包到客户端代码中,用于完成水合过程和路由匹配。
  • 当你移除@client后,构建工具不会生成该组件的客户端资产文件(比如.client.dart、.ddc.dill),但路由系统仍然尝试在客户端加载这些组件,从而抛出资产找不到的错误。

关于服务端路由提取的疑问

你的猜测有误,context.binding.currentUri在服务端和客户端都能正常访问:

  • 服务端渲染时,Jaspr会将当前HTTP请求的URI注入到BindingContext中,所以你在build方法里可以直接获取路由参数。
  • 客户端水合时,currentUri会对应浏览器的当前URL,保证前后端路由一致。

你可以通过kIsServer常量区分前后端环境,验证这一点:

import 'package:jaspr/jaspr.dart';
import 'package:jaspr/server.dart'; // 引入kIsServer

@client
class EmptyPage extends StatelessComponent {
  const EmptyPage({super.key});

  @override
  Iterable<Component> build(BuildContext context) sync* {
    final uri = context.binding.currentUri;
    if (kIsServer) {
      print('[Server] 当前请求URI: $uri'); // 服务端打印请求URL
    } else {
      print('[Client] 当前浏览器URI: $uri'); // 客户端打印浏览器URL
    }
    final page = uri.pathSegments.last;
    yield h1([text('Empty: $page')]);
  }
}

例外情况:纯服务端静态组件

如果某个组件是完全静态的、不需要参与客户端水合(比如页面底部的版权信息),可以使用@server注解标记,这样构建工具不会将其打包到客户端代码中。但注意:@server组件不能作为路由页面使用,只能作为页面内的子组件,因为路由页面必须参与客户端的路由匹配和水合流程。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 08:42:09