Ala*_*ruz 6 javascript java spring spring-mvc spring-boot
我正在开发一个Web应用程序,并打算利用缓存资源所带来的性能提升,但是它带有一个重要的警告。每当我更新静态文件时,用户都不会立即看到这些更改,因此必须禁用浏览器的缓存才能获取最新版本。为了解决此问题,我决定添加静态资产版本控制。可以与以下代码配合使用。
@Override
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**")
.addResourceLocations("classpath:/static/")
.setCacheControl(CacheControl.maxAge(365, TimeUnit.DAYS))
.resourceChain(true)
.addResolver(new VersionResourceResolver().addContentVersionStrategy("/**"))
// Costume made transformer to handle JS imports
.addTransformer(new JsLinkResourceTransformer())
.addTransformer(new CssLinkResourceTransformer());
}
@Bean
public ResourceUrlEncodingFilter resourceUrlEncodingFilter() {
return new ResourceUrlEncodingFilter();
}
Run Code Online (Sandbox Code Playgroud)
除了一个简单的细节,一切都按预期进行。JS导入仍在加载无版本文件。因此,类似的内容import * from './myscrypt.js'
将无法正常工作。
为了避免这种新的警告,我必须实现自己的资源转换器。该实现完成了工作,现在我的导入将获取正确的版本,例如import * from './myscript-149shdhgshs.js'
。然后,我以为一切都已解决,但是又出现了一个新问题。这是场景,这将使其更易于理解。
script.js
script-v1.js
script-v1.js
从myscript.js
myscript-v1.js
myscript.js
制作新版本myscript-v2.js
script-v1.js
存储在缓存中,所以myscript-v1.js
即使有新版本,也要使用旧的import加载它。我似乎无法使其工作。当然,我可以停止使用js modules
,而是立即加载所有脚本,但这不是我想要的解决方案。是否有js module
使用Spring 进行版本控制的解决方案?
解决这个缓存版本的方法是使用应用程序版本。如果该项目是基于Maven构建的,那么我看到您正在使用classpath
资源进行静态文件解析。每当js文件发生新更改时,您都将拥有新的构建,并且如果可以在每个构建上更改版本,则这是我的解决方法。
pom.xml
<version>0.1.0</version>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
Run Code Online (Sandbox Code Playgroud)
application.yml
build:
version: @project.version@
Run Code Online (Sandbox Code Playgroud)
这会将版本从pom.xml推送到IDE上的开发人员和内置jar的application.yml
控制者
我在这里使用小胡子视图解析器。
@Controller
public class HelloController {
@Value("${build.version}")
private String version;
private String encodedVersion;
@PostConstruct
public void setup() {
encodedVersion = new String(Base64.getEncoder().encode(version.getBytes())).replace("=", "");
}
@RequestMapping("/home")
public ModelAndView home() {
ModelAndView mv = new ModelAndView();
mv.setViewName("home.html");
return mv;
}
@ModelAttribute("version")
public String getVersion() {
return encodedVersion;
}
}
Run Code Online (Sandbox Code Playgroud)
home.html
<html>
<head>
<script type="text/javascript" src="/pop.js?cache={{version}}"></script>
<script type="text/javascript">
window.version = "{{version}}" // in case you need this somewhere
</script>
</head>
<body>
<h1>Home1</h1>
version: {{version}}
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
处理现有的js文件
@Configuration
@AutoConfigureAfter(DispatcherServletAutoConfiguration.class)
public class Config implements WebMvcConfigurer {
@Value("${build.version}")
private String version;
private String encodedVersion;
@PostConstruct
public void setup() {
encodedVersion = new String(Base64.getEncoder().encode(version.getBytes())).replace("=", "");
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**").addResourceLocations("classpath:/static/").setCacheControl(CacheControl.maxAge(365, TimeUnit.DAYS)).resourceChain(true)
.addResolver(new VersionResourceResolver().addContentVersionStrategy("/**"))
.addTransformer(new ResourceTransformer() {
@Override
public Resource transform(HttpServletRequest request, Resource resource, ResourceTransformerChain transformerChain) throws IOException {
// Be aware of side effects changing line break
String result = new BufferedReader(new InputStreamReader(resource.getInputStream())).lines().collect(Collectors.joining("\n"));
result = result.replace("{{cacheVersion}}", encodedVersion);
return new TransformedResource(resource, result.getBytes());
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
pop.js
import mod1 from './mod1.js?cache={{cacheVersion}}';
function dis() {
console.log("hello")
}
Run Code Online (Sandbox Code Playgroud)
由于版本已添加,ModelAttribute
因此它将在所有请求映射中可用。对于每个版本,此设置都会更改,并且使用此缓存版本变量可以提取文件。
归档时间: |
|
查看次数: |
136 次 |
最近记录: |