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 for SharedWorkers?好的,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 氧气?

excel导入hive的web工具 #导入MD文档图片#

Apache Ranger 1.1.0源码导入IDEA并运行调试security-admin web模块

模块类型 Web Worker 中多个脚本的高效动态导入

当产生一个新进程时,导入会发生啥?