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

如何在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,提问作者Вукашин Лекић

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 05:45:21