无法在Vuejs和Webpack中使用Worker-Loader

11

我正在尝试在Vue cli3中启用Web Workers,但是我在使其正常工作方面遇到了困难。

我想使用以下包: worker-loader(而不是vue-worker),因为它看起来维护良好且有更多的贡献。

按照他们的教程,我尝试使用vue cli修改webpack,如下所示:

module.exports = {
    chainWebpack: config => {
        config.module
          .rule('worker-loader')
          .test(/\.worker\.js$/)
          .use('worker-loader')
            .loader('worker-loader')
            .end()
    }
}

我希望这应该与他们的相匹配。

{
  module: {
    rules: [
      {
        test: /\.worker\.js$/,
        use: { loader: 'worker-loader' }
      }
    ]
  }
}

可以在此处阅读(https://github.com/webpack-contrib/worker-loader)。我尽力按照Vue CLI3的文档进行操作(在此处找到:https://cli.vuejs.org/guide/webpack.html#simple-configuration)。

我的组件非常简单:

import Worker from 'worker-loader!./../../sharedComponents/equations/recurringTimeComposer.js';

<...>
watch:{

 recurringPaymentReturnObj: function(newVal, oldVal){
        const myWorker = new Worker;
        myWorker.postMessage({ hellothere: 'sailor' });
        myWorker.onmessage = (e) => {
            console.log('value of e from message return', e.data);
 }
}
<...>

而在我的./../../sharedComponents/equations/recurringTimeComposer.js文件中,我有:

onmessage = function(e) {
    console.log('Message received from main script: ', e.data);
    // var workerResult = 'Result: ' + e.data;
    // console.log('Posting message back to main script');
    postMessage('hello back handsome');
    close();
}

我一直收到错误信息:

ReferenceError: window is not defined a162426ab2892af040c5.worker.js:2:15

经过一番搜索,我找到了这篇文章:https://github.com/webpack/webpack/issues/6642,其中建议最好的修复方式是将以下内容添加到Webpack中:

output: {
       path: path.join(__dirname, 'dist'),
       filename: 'bundle.js'
       publicPath: 'http://localhost:3000',
       globalObject: 'this'
},

修改了我的 vue.config.js 文件后,我得到了:

module.exports = {
    chainWebpack: config => {
        config.module
          .rule('worker-loader')
          .test(/\.worker\.js$/)
          .use('worker-loader')
            .loader('worker-loader')
            .end()
        config
            .output
            .path(path.join(__dirname, 'dist'))
            .filename('bundle.js')
            .publicPath('http://localhost:8080')
            .globalObject('this')
    }
}

...但我仍然收到窗口未定义的错误。

有没有人知道出了什么问题?这似乎是webpack中的奇怪错误。

谢谢!

编辑:哦对了,这里还有WebWorker的MDN页面:https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers


啊……如果有人对这个问题有答案,请添加,但是我目前正在使用vue-worker,因为我无法将其他内容集成到webpack中。谢谢~ - Peter Weyand
6个回答

6
作为一个对Javascript不熟悉的人,我在尝试使用VueJS的Web Workers时一直遇到这个问题。我从来没有成功地使用vue-workerworker-loader
现在是2020年,Google发布了worker-plugin
要使用它,需要创建一个名为my-worker的模块,并包含两个文件:index.jsworker.jsindex.js创建了该模块:
const worker = new Worker('./worker.js', { type: 'module' });

const send = message => worker.postMessage({
  message
})

export default {
  worker,
  send
}

worker.js 包含逻辑:

import _ from 'lodash'
addEventListener("message", async event => {
    let arrayToReverse = event.data.message.array
    let reversedArray = _.reverse(arrayToReverse)
    // Send the reversed array
    postMessage(reversedArray)
});

您还需要更新vue.config.js以使用WorkerPlugin:

const WorkerPlugin = require('worker-plugin')
module.exports = {
  configureWebpack: {
    output: {
      globalObject: "this"
    },
    plugins: [
      new WorkerPlugin()
    ]
  }
};

现在你可以在组件中使用你的 worker:
  1. 使用 import worker from '@/my-worker' 导入它。
  2. mounted() 生命周期钩子中设置一个 listener,使用 worker.worker.onmessage = event => { // 当接收到 postMessage 时执行某些操作 }
  3. 使用 worker.send(payload) 启动 worker。
我在 GitHub 上设置了一个起始代码:github。尽管如此,我仍未成功使 HMR 工作...

6
这对我有用(注意第一行):
config.module.rule('js').exclude.add(/\.worker\.js$/)

config.module
  .rule('worker-loader')
  .test(/\.worker\.js$/)
  .use('worker-loader')
  .loader('worker-loader')

第一行代码排除了worker.js文件,这样就避免了两个加载器对同一个js文件进行争夺。


第一行也解决了我的问题,谢谢! - g-radam

0

0

我尝试在一个vue-cli4项目中添加Web Worker,以下是我的发现:

  1. 使用worker-loader并在chainWebpack中进行配置: HMR工作正常,但sourcemap出了问题,它显示了babel转换后的代码。

  2. 使用@braincoke提到的worker-plugin: HMR出了问题,但sourcemap正常工作。同时建议禁用所有worker js文件的eslint。

最终,我的解决方案是放弃vue-cli,拥抱vite。它原生支持worker,现在一切都很顺利。(我认为将webpack升级到v5可以解决这个问题,但我从未尝试过。)


0

从经典的vue和webpack配置升级后,我发现为了使这个工作正常,我需要停用并行处理。

// vue.config.js
module.exports = {
    parallel: false,
    chainWebpack: (config) => {
        config.module
        .rule('worker')
        .test(/\.worker\.js$/)
        .use('worker-loader')
        .loader('worker-loader')
        .end();
    }
};

0
由于Webpack 5中不再需要worker-loader,对我而言,解决方法是添加import.meta.url,因为通过相对URL初始化Worker无法正常工作。有效的方法是相对于在应用程序中执行JS代码的HTML文件加载脚本。
const worker = new Worker(new URL('./worker-test.js', import.meta.url));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接