如何基于ES5/ES2015浏览器支持预取JavaScript文件?
基于浏览器支持的脚本预取方案(ES5 vs ES2015)
这个问题问得很到位!要实现根据浏览器ES模块支持情况预取对应版本的脚本,我们可以参照script标签的type="module"和nomodule逻辑,用link标签来实现,下面给你两种靠谱的方案:
方案1:原生HTML标签实现(推荐)
利用浏览器对modulepreload和nomodule属性的原生支持,无需额外JS:
<!-- 支持ES模块的浏览器会预取ES2015脚本 --> <link rel="modulepreload" href="https://some-file-es2015.js" crossorigin="anonymous"> <!-- 不支持ES模块的浏览器会预取ES5脚本,支持的浏览器会忽略此标签 --> <link rel="prefetch" as="script" href="https://some-file-es5.js" crossorigin="anonymous" nomodule>
原理说明:
rel="modulepreload":这是专门为ES模块设计的预加载类型,只有支持ES模块的浏览器会识别并处理这个标签,它不仅会预取主脚本,还会自动处理模块的依赖项,比普通prefetch更适配模块场景。nomodule属性:支持ES模块的浏览器会自动忽略带有这个属性的资源标签,刚好符合我们让现代浏览器跳过ES5脚本预取的需求。
方案2:JavaScript动态创建(兼容旧浏览器)
如果需要兼容一些支持ES模块但不支持modulepreload的老版本浏览器,可以通过特性检测动态生成预取标签:
// 检测浏览器是否支持ES模块(通过判断script元素是否有noModule属性) const supportsESModules = 'noModule' in HTMLScriptElement.prototype; const link = document.createElement('link'); link.rel = 'prefetch'; link.as = 'script'; link.crossorigin = 'anonymous'; // 根据支持情况设置预取的脚本地址 link.href = supportsESModules ? 'https://some-file-es2015.js' : 'https://some-file-es5.js'; document.head.appendChild(link);
原理说明:
我们通过检测HTMLScriptElement.prototype上是否存在noModule属性来判断浏览器是否支持ES模块——这是业界通用的特性检测方式,因为支持ES模块的浏览器都会实现这个属性来支持nomodule脚本标签。
内容的提问来源于stack exchange,提问作者Mayur Patil
相关产品推荐
相关产品推荐

