在服务工作者文件中使用 ESM(导入/导出)
Posted
技术标签:
【中文标题】在服务工作者文件中使用 ESM(导入/导出)【英文标题】:Use ESM in a service worker file (import/export) 【发布时间】:2019-11-19 01:48:04 【问题描述】:我正在尝试使用服务工作者文件,它也是一个 ESM 模块。
register
方法有一个额外的参数,接受一个 options
对象,该对象有一个 type
字段,其有效值似乎是 classic
和 module
,但是当我使用时:
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(导入/导出)的主要内容,如果未能解决你的问题,请参考以下文章
如何以及何时使用“ng build”生成的 lib 文件夹的 esm5 和 esm2015 目录?