如何对 es6 模块进行特征检测

How to feature-detect es6 modules

我想仅在当前运行时支持的情况下使用 ES6 语法导出模块。目标是开发一个支持不同模块管理系统的库。

因为 export 是关键字,类似的东西会抛出语法错误:

typeof export

2021 年更新:

虽然加载程序规范似乎已停滞,但动态导入替代方案已 implemented by various runtimes

由于对模块的支持是动态导入的先决条件,后者可用于探测对前者的支持。

这不依赖于任何 DOM API 细节,因此它可以在其他上下文中使用。一个限制是它必须异步查询。另一个限制是此检测与 unsafe-eval CSP 不兼容,在这种情况下,通过 HTMLScriptElementWorker API 进行探测可用作回退。

let supported = null;
async function modulesSupported() {
   if (supported !== null) {
      return supported;
   }

   try {
     let module = await new Function("return (async () => {return await import('data:application/javascript,export%20let%20canary%20=%201;')})")()()
     supported = module && module.canary && module.canary == 1;
   } catch(e) {
     supported = false;
   }

   return supported;
}

modulesSupported().then(r => console.log(r));
// => `true`

旧答案:

规范的

Revision 27 有一个 Reflect.Loader API 可用于模块反射。

虽然这本身并不是针对 export 关键字的直接特征检测,但可以加载一个使用 data-uri 中的 export 关键字的模块,然后检查它是否抛出解析错误。

但它已从修订版 28 中删除,并具有以下更改日志条目:

Removed loader pipeline and Reflect.Loader API (functionality being transferred to separate specification)


因此,据我所知,在撰写本文时,规范似乎并未提供任何功能检测方法。

将来可能会使用 Reflect.Loader 或其替代品。

编辑:loader spec 似乎是由 whatwg 管理开发的,但它尚未处于我们可以从中导出特征检测的状态。

检查 'noModule' 属性:

document.currentScript && "noModule" in document.currentScript;

使用


'noModule' in HTMLScriptElement.prototype

ref