【问题标题】:How to feature-detect es6 modules如何对 es6 模块进行特征检测
【发布时间】:2015-03-11 09:56:31
【问题描述】:

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

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

typeof export

【问题讨论】:

  • 即使在 ES5 中 exportimport 也是保留关键字,它会引发无法捕获的语法错误
  • 我认为你应该使用 ES6 语法;并分发 6-to-5 编译的版本。
  • 不重复,因为语法规则不同(生成器可以通过 eval 测试,模块不能,afaics)
  • @joews 因为eval 将其字符串解析为 Script 而不是 Module(换句话说,ExportDeclaration' s 和 ImportDeclaration 不能被评估)

标签: javascript ecmascript-6


【解决方案1】:

使用


'noModule' in HTMLScriptElement.prototype

ref

【讨论】:

    【解决方案2】:

    2021 年更新:

    虽然 Loader 规范似乎停滞不前,但动态导入替代方案一直是 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 中被删除,并带有以下更改日志条目:

    删除了加载器管道和 Reflect.Loader API(功能被转移到单独的规范中)


    因此,据我所知,在撰写本文时,该规范似乎没有提供任何特征检测方式。

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

    编辑:loader spec 似乎是由 whatwg 管理开发的,但它还没有处于我们可以从中派生特征检测的状态。

    【讨论】:

    • 那个未来已经到来了吗?
    • 如果提案github.com/domenic/proposal-import-function 成为现实(现在是in stage 2),我们将轻松检查typeof import === 'function'
    • @krampstudio 您的评论建议的代码在 Chrome 中产生“未捕获的语法错误”。请查看我的答案以进行工作检查。
    【解决方案3】:

    检查“noModule”属性:

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

    【讨论】:

    • 这不起作用,因为 OP 通常想要检查不同的运行时。 DOM API 不一定可用,例如在 node.js 或网络工作者中。如果它们可用,则通过构建 <script type='module'> 元素进行检查将是微不足道的。
    • @the8472 Web Worker 由 DOM API 加载,因此您应该知道是否支持 es6 模块。使用 node.js,您只需要最低版本的 node.js。
    猜你喜欢
    • 2014-05-30
    • 2016-12-19
    • 2020-06-04
    • 2013-07-22
    • 1970-01-01
    • 2015-09-13
    • 2017-10-27
    • 1970-01-01
    • 2020-09-11
    相关资源
    最近更新 更多