Hilla 2.3.2无法生成BrowserCallable端点及Record的TypeScript类求助
Hilla 2.3.2 TypeScript生成失效问题排查指南
问题背景
使用Hilla 2.3.2搭配hilla-maven-plugin和Spring开发时,标注@BrowserCallable的端点类和Record不再生成对应TypeScript类。构建无报错,但Frontend/generated/仅生成少量Vaadin相关文件,回退至历史正常版本也无法解决。以下是调试日志开启方法、插件扫描机制说明及排查步骤:
一、开启Hilla Maven插件调试日志
有两种方式获取插件执行的详细日志:
- 临时开启:执行Maven命令时添加
-X参数,直接输出所有调试信息:mvn spring-boot:run -X - 永久配置:在pom.xml的hilla-maven-plugin中添加
verbose配置,每次构建自动输出详细日志:<plugin> <groupId>dev.hilla</groupId> <artifactId>hilla-maven-plugin</artifactId> <version>${hilla.version}</version> <configuration> <verbose>true</verbose> </configuration> <executions> <!-- 原有执行配置 --> </executions> </plugin>
二、Hilla Maven插件类路径扫描机制
- 扫描范围:默认扫描项目编译后的class文件(
target/classes目录)及依赖中的class文件,但仅处理三类内容:标注@BrowserCallable的类、这些类引用的Record/POJO、vaadin.whitelisted-packages配置的包下类。 - 触发时机:
prepare-frontend目标默认在Maven的process-resources阶段执行,此阶段可能早于Java编译,导致插件无法扫描到最新生成的class文件。 - 白名单控制:仅配置的包会被扫描,你的
application.properties中已包含com.test,此配置无问题。
三、问题排查步骤
- 确认Java类已编译:检查
target/classes/com/test目录下是否存在TestController.class和TestDTO.class,若不存在先执行mvn compile完成编译。 - 清理缓存目录:删除以下目录后重新构建,排除缓存干扰:
Frontend/generated/target/frontend/node_modules/.vaadin/
- 调整插件执行时机:将
prepare-frontend的执行阶段改为process-classes,确保插件扫描已编译的class文件:<execution> <phase>process-classes</phase> <goals> <goal>prepare-frontend</goal> </goals> </execution> - 排查DevTools影响:暂时注释
spring-boot-devtools依赖,重新运行项目,排查类加载干扰问题。
附:项目相关代码
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.1.5</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.test</groupId> <artifactId>test</artifactId> <version>1.0.0-SNAPSHOT</version> <name>test</name> <packaging>jar</packaging> <properties> <java.version>21</java.version> <maven.compiler.source>21</maven.compiler.source> <maven.compiler.target>21</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <hilla.version>2.3.2</hilla.version> </properties> <repositories> <repository> <id>central</id> <url>https://repo.maven.apache.org/maven2</url> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories> <dependencyManagement> <dependencies> <dependency> <groupId>dev.hilla</groupId> <artifactId>hilla-bom</artifactId> <version>${hilla.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jdbc</artifactId> <exclusions> <exclusion> <groupId>com.zaxxer</groupId> <artifactId>HikariCP</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>2.0.9</version> </dependency> <dependency> <groupId>dev.hilla</groupId> <artifactId>hilla-react</artifactId> </dependency> <dependency> <groupId>dev.hilla</groupId> <artifactId>hilla-spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.parttio</groupId> <artifactId>line-awesome</artifactId> <version>2.0.0</version> </dependency> </dependencies> <build> <defaultGoal>spring-boot:run</defaultGoal> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.11.0</version> <configuration> <source>21</source> <target>21</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>3.2.1</version> <configuration> <skipTests>true</skipTests> </configuration> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <groupId>dev.hilla</groupId> <artifactId>hilla-maven-plugin</artifactId> <version>${hilla.version}</version> <executions> <execution> <goals> <goal>prepare-frontend</goal> </goals> </execution> </executions> </plugin> </plugins> </build> <profiles> <profile> <!-- Production mode is activated using -Pproduction --> <id>production</id> <build> <plugins> <plugin> <groupId>dev.hilla</groupId> <artifactId>hilla-maven-plugin</artifactId> <version>${hilla.version}</version> <executions> <execution> <goals> <goal>build-frontend</goal> </goals> <phase>compile</phase> </execution> </executions> </plugin> </plugins> </build> </profile> </profiles> </project>
application.properties
server.port=8888 vaadin.launch-browser=true spring.devtools.restart.additional-exclude=dev/hilla/openapi.json vaadin.whitelisted-packages = com.vaadin,org.vaadin,dev.hilla,com.test
Spring应用类
package com.test; import com.vaadin.flow.component.page.AppShellConfigurator; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.context.properties.ConfigurationPropertiesScan; @SpringBootApplication @ConfigurationPropertiesScan public class TestApplication implements AppShellConfigurator { public static void main(String[] args) { SpringApplication.run(TestApplication.class, args); } }
控制器端点
package com.test; import com.vaadin.flow.server.auth.AnonymousAllowed; import dev.hilla.BrowserCallable; import java.util.List; @BrowserCallable @AnonymousAllowed public class TestController { public List<TestDTO> test() { return List.of( new TestDTO("a"), new TestDTO("b") ); } }
Record类
package com.test; public record TestDTO(String id) { }
内容的提问来源于stack exchange,提问作者mferrari
相关产品推荐
相关产品推荐

