Web Workers - 如何导入模块
Posted
技术标签:
【中文标题】Web Workers - 如何导入模块【英文标题】:Web Workers - How To Import Modules 【发布时间】:2017-10-22 10:47:48 【问题描述】:我正在使用 ES2015 导入/导出模块。
在我的工作文件中,当我尝试像往常一样导入函数时:
worker.js
import a, b, c from "./abc.js";
我得到错误:
SyntaxError: import declarations may only appear at top level of a module
当我在模块“abc.js”中导出函数时,我不确定如何使用旧的(显然即将淘汰)语法来使用它们:
self.importScripts( "/app/abc.js" );
那么,我的问题是,我们如何将新的导入模块语法与工作人员一起使用?
第二个问题是,importScripts
从没有导出全局对象父级的模块导入时会导入什么?
【问题讨论】:
【参考方案1】:Workers 中的 ES2015 模块在 Safari 和 Chromium 浏览器中可用。
如果您的目标是其他浏览器/版本,您仍然需要使用importScripts()
。
如果可用,您可以像这样创建一个模块工作者:
new Worker("worker.js", type: "module" );
见:https://html.spec.whatwg.org/#module-worker-example
这些是每个浏览器的错误报告:
Firefox: 开发中? 请投票! Chromium 浏览器:Dedicated Workers:自 80 版起可用 ✔️Shared Workers:自 83 版起可用 ✔️Service Workers : 自 91 版起可用 ✔️ Webkit: Safari 桌面版:自 Safari 14.1 起可用 ✔️ Safari Mobile (ios):自 Safari 15 起可用 ✔️【讨论】:
如何知道什么时候支持? 查看我更新的答案。 Chromium 正在积极开发它。 啊,所以只有新的Worker(..)需要指定“模块”。实际的工作代码可以正常导入/导出。这是正确的吗?听起来像节点的 .mjs :) 它将与 Chromium 80 一起发货,Chrome 80 计划在 2020 年 2 月 4 日稳定。好吧……。 该死的,82 forSharedWorker
s?好的,they decided to skip the 82 和 the 83’s planned to be stable on May 19, 2020。【参考方案2】:
worker 中的 ES 模块已经在 Chrome 中可用,启用 Experimental Web Platform Features,在启动 chrome 时使用正确的标志:
chrome.exe --enable-experimental-web-platform-features
这是您将工作脚本作为模块加载所需的语法:
new Worker( 'my-worker.js', type : 'module' );
这个功能已经开发了将近一年,应该很快就可以使用,不需要特殊的标志,但是,还没有正式的发布日期。
【讨论】:
也改为在chrome://flags/
中以一个标志开始,然后搜索Experimental Web Platform features
或类似的东西【参考方案3】:
对我来说,分配给self.
效果很好。
我已将导入导入另一个 js 文件:abcImported.js
import a, b, c from "./abc.js";
export a, b, c ;
在服务工作者中:
self.a = require('abcImported.js').a;
self.b = require('abcImported.js').b;
通过这种方式,它可以在worker内部访问。 (在 chrome 中测试)
【讨论】:
你从哪里得到require
?
我认为这是另一个(疯狂!)工作流已将“require”修改为可行的解决方案的情况。卷起?还是更有可能是 Webpack?
是的,webpack。就我而言,它是使用 webpacker gem 的 rails 应用程序,它使用 webpack :)
abcImported.js
是单独托管的文件吗?【参考方案4】:
2020:
Chrome 80 has shipped module workers in February 2020(Chrome 82 将为共享工作者提供模块)。 Firefox/Safari 目前不支持这些功能:tests
您可以使用希望使用 import-from-worker lib 来为您完成繁重的工作(现在,您需要检查对工作模块的支持并自己执行回退)。
【讨论】:
twitter.com/DasSurma/status/1392799265567694851【参考方案5】:截至 11 月 21 日,在 worker 中导入模块似乎仍然很不稳定。一种解决方案是使用汇总从您的工作人员生成 IIFE,如下所示:
//worker.js
import MyModule from 'my-module.js'
onconnect = async (e) =>
var port = e.ports[0];
MyModule.func()
port.onmessage = (e) =>
port.postMessage("Hi App");
//rollup config
export default [
'input': 'worker.js',
'output':
'file': 'dist/worker.js',
'format': 'iife'
,
,
]
//dist/worker.js (rollup output)
(function ()
'use strict';
//MyModule code here, generated by rollup
MyModule.func()
onconnect = async (e) =>
var port = e.ports[0];
port.onmessage = (e) =>
port.postMessage("Hi App");
;
;
());
//main app
const worker = new SharedWorker("/dist/worker.js");
worker.port.onmessage = (e) =>
console.log('Message received from worker: ' + e.data);
worker.port.postMessage("Hi worker");
本质上,rolllup 正在做浏览器应该做的工作。 这对我来说效果很好。当然,代码大小会增加,因为模块代码也被复制到 worker 中。但它仍然是 DRY,因为代码是由 rollup 生成的。
【讨论】:
以上是关于Web Workers - 如何导入模块的主要内容,如果未能解决你的问题,请参考以下文章
如何修复 Go 1.11 模块未知导入路径,找不到模块提供包?
如何在没有动态 Web 模块 3.0 facet hacks 的情况下将 jdk 9 maven spring boot 2 项目导入 eclipse ee 氧气?