在服务工作者文件中使用 ESM(导入/导出)

Posted

技术标签:

【中文标题】在服务工作者文件中使用 ESM(导入/导出)【英文标题】:Use ESM in a service worker file (import/export) 【发布时间】:2019-11-19 01:48:04 【问题描述】:

我正在尝试使用服务工作者文件,它也是一个 ESM 模块。

register 方法有一个额外的参数,接受一个 options 对象,该对象有一个 type 字段,其有效值似乎是 classicmodule,但是当我使用时:

navigator.serviceWorker.register('worker.js',  type: 'module' );
// `worker.mjs` doesn't work either
// The file exists in both cases!

我在 Chrome 中收到一个未指定的 DOMException,但没有消息。

通过阅读规范,我知道type 的有效值是什么,特别是:

https://html.spec.whatwg.org/multipage/workers.html#workertype

在我看来,我的代码是有效的。

作为健全性检查,我还尝试将type 显式设置为classic,然后服务工作人员注册顺利进行。如果我将其设置为无效值,我会得到一个 TypeError 告诉我,所以浏览器并不知道 type: module。它被视为一种特殊情况,它只是抛出一个DOMException 而没有任何消息。

我是否正确使用了type 字段?是不是还太早了,浏览器还不支持?

【问题讨论】:

.mjs 是 Node.js 的东西,而不是 Node.js 之外的 ESM 东西。 (而且 Node.js 现在有 type。希望 .mjs 会死掉......) 什么版本的 Chrome?你的 service worker 脚本的内容有什么不同吗? 重复***.com/questions/44118600 【参考方案1】:

这太愚蠢了!记录错误对象时,Chrome 只会将DOMException 打印到控制台(甚至不可扩展),并且该对象实例上的Object.keys 返回[],但是当我专门打印e.message 时,罪魁祸首就被发现了:

RegistrationOptions 中的 type 'module' 尚未实现。详情请参阅https://crbug.com/824647。

对 Chrome 不感兴趣。

【讨论】:

【参考方案2】:

在浏览器上,不能使用裸名来标识模块,除非您还有将裸名映射到模块的module map(又名import map,此链接包含更多信息)。

如果worker.js 与加载它的页面位于同一位置,则:

navigator.serviceWorker.register('./worker.js',  type: 'module' );
// -------------------------------^^

当然,也可以添加一个模块映射。

【讨论】:

不幸的是,这不被支持,并且错误消息被掩盖得令人难以置信。发布问题后才弄清楚,请参阅我的答案。 @TomášHübelbauer - 是的,刚刚看到。当它支持 时,我怀疑您需要执行上述操作。 :-) 我会记住这一点。使用经典(默认)注册,传递worker.js(没有./)对我来说效果很好。浏览器能够正确解析相对 URL。 @TomášHübelbauer - 对,路径或地图的要求与模块特别相关。例如,对于非工作人员,<script src="foo.js"></script> 有效;但没有地图,<script type="module" src="foo.js"></script> 没有,它必须是 <script type="module" src="./foo.js"></script>

以上是关于在服务工作者文件中使用 ESM(导入/导出)的主要内容,如果未能解决你的问题,请参考以下文章

elasticsearch5数据导入导出

如何以及何时使用“ng build”生成的 lib 文件夹的 esm5 和 esm2015 目录?

模块化 —— CommonJSAMDUMDESM(上)

oracle 导入导出功能

从 phpMyAdmin 使用导出/导入 SQL 文件时出错

2016.8.17服务器端数据库用户导入导出方法 expdp和impdp