Web Workers - 如何导入模块
Web Workers - How To Import Modules
我正在使用 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" );
所以,我的问题是,我们如何将新的导入模块语法用于 worker?
第二个问题是,importScripts
从一个没有导出全局对象父对象的模块导入时,导入了什么?
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 起可用 ✔️
工人中的 ES 模块已在 Chrome 中可用,启用实验性 Web 平台功能,在启动时使用正确的标志 chrome:
chrome.exe --enable-experimental-web-platform-features
这是将工作脚本作为模块加载时需要使用的语法:
new Worker( 'my-worker.js', { type : 'module' } );
这个功能已经开发了将近一年,应该很快就可以使用,不需要特殊的标志,但是,还没有正式的发布日期。
对我来说分配给 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 中测试)
2020 年:
Chrome 80 has shipped module workers in February 2020 (and Chrome 82 will ship modules for shared workers). Firefox/Safari do not support those features for now: tests
您可能想使用 import-from-worker lib 来为您完成繁重的工作(目前,您需要检查 workers 中对模块的支持并自己进行回退)。
截至 11 月 21 日,在工人中导入模块似乎仍然不稳定。一种解决方案是使用 rollup 从您的 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 中。但它仍然是干的,因为代码是由汇总生成的。
我正在使用 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" );
所以,我的问题是,我们如何将新的导入模块语法用于 worker?
第二个问题是,importScripts
从一个没有导出全局对象父对象的模块导入时,导入了什么?
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 起可用 ✔️
工人中的 ES 模块已在 Chrome 中可用,启用实验性 Web 平台功能,在启动时使用正确的标志 chrome:
chrome.exe --enable-experimental-web-platform-features
这是将工作脚本作为模块加载时需要使用的语法:
new Worker( 'my-worker.js', { type : 'module' } );
这个功能已经开发了将近一年,应该很快就可以使用,不需要特殊的标志,但是,还没有正式的发布日期。
对我来说分配给 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 中测试)
2020 年:
Chrome 80 has shipped module workers in February 2020 (and Chrome 82 will ship modules for shared workers). Firefox/Safari do not support those features for now: tests
您可能想使用 import-from-worker lib 来为您完成繁重的工作(目前,您需要检查 workers 中对模块的支持并自己进行回退)。
截至 11 月 21 日,在工人中导入模块似乎仍然不稳定。一种解决方案是使用 rollup 从您的 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 中。但它仍然是干的,因为代码是由汇总生成的。