如何在Spring Boot中使用ViteJS生成的资源文件
Spring整合Vite哈希资源的最优方案(替代手动解析manifest.json)
针对Spring后端+React前端(Vite构建)的场景,完全不用手动解析manifest.json再传递给Thymeleaf,有几个更优雅的实现方式:
1. 自定义Thymeleaf方言:模板内直接映射文件名
这是最贴合Spring+Thymeleaf开发流程的方案,通过自定义方言提供模板函数,自动读取并解析manifest.json。
步骤1:实现Manifest资源解析器
创建一个组件负责加载和缓存manifest.json的映射关系:
@Component public class ManifestResourceResolver { private final Map<String, String> resourceHashMap; public ManifestResourceResolver() throws IOException { // 加载static目录下的manifest.json(Vite构建后需放到此处) Resource manifestResource = new ClassPathResource("static/manifest.json"); ObjectMapper objectMapper = new ObjectMapper(); this.resourceHashMap = objectMapper.readValue( manifestResource.getInputStream(), new TypeReference<Map<String, String>>() {} ); } // 根据原始文件名返回带哈希的文件名,找不到则返回原文件名 public String getHashedName(String originalFileName) { return resourceHashMap.getOrDefault(originalFileName, originalFileName); } }
步骤2:注册自定义Thymeleaf方言
把解析器封装成Thymeleaf表达式对象,让模板可以直接调用:
@Configuration public class ThymeleafCustomConfig { @Bean public Dialect manifestResourceDialect(ManifestResourceResolver resolver) { return new AbstractDialect() { @Override public String getName() { return "manifest-resource"; } @Override public Set<IExpressionObjectFactory> getExpressionObjectFactories() { return Collections.singleton(new IExpressionObjectFactory() { @Override public Set<String> getAllExpressionObjectNames() { return Collections.singleton("res"); } @Override public Object buildObject(IExpressionContext context, String name) { return resolver; } @Override public boolean isCacheable(String name) { return true; } }); } }; } }
步骤3:在Thymeleaf模板中使用
直接通过表达式调用,无需手动传递模型属性:
<script th:src="@{/${res.getHashedName('index.js')}}" /> <link th:href="@{/${res.getHashedName('style.css')}}" rel="stylesheet" />
2. Vite插件自动注入哈希文件名到模板
如果不想写Java代码,可以借助Vite插件在构建阶段直接替换模板中的占位符,生成带哈希文件名的Thymeleaf模板。
比如使用vite-plugin-html,配置示例:
import { createHtmlPlugin } from 'vite-plugin-html'; export default { plugins: [ createHtmlPlugin({ inject: { data: { jsBundle: '<%= assets["index.js"] %>', cssBundle: '<%= assets["index.css"] %>' } }, template: './src/templates/index.html' // 你的Thymeleaf源模板 }) ] };
构建后,模板中的占位符会被替换成带哈希的文件名,Spring直接使用生成后的模板即可。这种方案适合前后端模板耦合度较低的场景。
3. Spring静态资源转换器(适合纯资源访问场景)
如果是直接通过URL访问静态资源,可以实现ResourceTransformer接口,在请求时自动替换文件名,但这种方式对Thymeleaf模板的支持不如方言方案直接,更适合API式的资源访问。
推荐方案
优先选择自定义Thymeleaf方言,它完全融入Spring生态,无需改变现有开发流程,同时保证了哈希文件名映射的自动化和可维护性。
内容的提问来源于stack exchange,提问作者Вукашин Лекић
相关产品推荐
相关产品推荐

