如何修改JSF代码使@ResourceDependency加载ES6模块类型脚本?
JSF 加载ES6模块脚本的解决方案
问题背景
- 项目使用自定义
@FacesComponent组件,通过@ResourceDependency引入JavaScript资源 - 该JS资源已升级为ES6模块,但JSF默认生成的是
<script type="text/javascript" src="..."></script>标签,无法以模块方式加载 - 尝试过自定义
ResourceHandlerWrapper设置资源ContentType为module,但未生效
可行解决方案
1. 直接用JSF 2.3+的@ResourceDependency扩展属性(推荐)
JSF 2.3及更高版本允许给@ResourceDependency添加attributes参数,直接指定script的type属性,无需额外扩展:
@FacesComponent("myCustomComponent") @ResourceDependency( library = "test", name = "module.js", attributes = {"type", "module"} ) public class MyCustomComponent extends UIComponentBase { // 组件业务逻辑 }
这样JSF会直接渲染出<script type="module" src="..."></script>标签,是最简洁的实现方式。
2. 修复自定义ResourceHandlerWrapper实现
之前的代码可能因原Resource实例不可修改导致失效,改用ResourceWrapper包装原资源并重写getContentType方法更可靠:
public class MyResourceHandler extends ResourceHandlerWrapper { public MyResourceHandler(ResourceHandler wrapped) { super(wrapped); } @Override public Resource createResource(String resourceName, String libraryName) { Resource originalRes = super.createResource(resourceName, libraryName); if (originalRes != null && "module.js".equals(resourceName) && "test".equals(libraryName)) { return new ResourceWrapper() { @Override public Resource getWrapped() { return originalRes; } @Override public String getContentType() { return "module"; } }; } return originalRes; } }
然后在faces-config.xml中注册这个资源处理器:
<application> <resource-handler>com.yourpackage.MyResourceHandler</resource-handler> </application>
3. 手动渲染script标签(兼容旧版JSF)
如果项目使用的JSF版本低于2.3,可以在组件的编码方法中手动输出模块脚本标签,同时移除原来的@ResourceDependency:
@Override public void encodeBegin(FacesContext context) throws IOException { super.encodeBegin(context); ResponseWriter writer = context.getResponseWriter(); // 获取资源请求路径 String resourcePath = context.getApplication().getResourceHandler() .createResource("module.js", "test").getRequestPath(); writer.startElement("script", this); writer.writeAttribute("type", "module", null); writer.writeAttribute("src", resourcePath, null); writer.endElement("script"); }
内容的提问来源于stack exchange,提问作者DaniEll
相关产品推荐
相关产品推荐

