我正在尝试使用 Vue cli3 启动并运行 Web Worker,但无法使其正常工作。
我想使用以下包,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。
作为 Javascript 新手,当我尝试将 Web Worker 与 VueJS 结合使用时,我不断地回到这个问题。我从来没有设法让它与
vue-worker
或 worker-loader
一起工作。
现在已经是 2020 年了,Google 发布了 worker-plugin。
要使用它,请创建一个模块
my-worker
,其中包含两个文件 index.js
和 worker.js
。
index.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()
]
}
};
现在您可以在组件中使用您的工作人员:
import worker from '@/my-worker'
导入它。mounted()
在
worker.worker.onmessage = event => { // do something when receiving postMessage }
worker.send(payload)
启动工作线程。我在 github 上设置了一个起始代码。不过我还没能让 HMR 发挥作用...
这对我有用(注意第一行):
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文件
这是您需要的吗? Vue 与工作加载程序的问题
从经典的 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();
}
};
我尝试将 Web Worker 添加到 vue-cli4 项目,这是我发现的:
使用worker-loader并在chainWebpack中进行配置: HMR 工作正常,但 sourcemap 损坏,它显示 babel 转换后的代码。
使用worker-plugin,如@braincoke提到的: HMR 坏了,但 sourcemap 工作正常。 eslint 崩溃了,同时建议禁用所有工作 js 文件 eslint。
最后,我的解决方案是扔掉 vue-cli,拥抱 vite。它原生支持 Worker,现在一切顺利。 (我认为将 webpack 升级到 v5 可以解决这个问题,但我从未尝试过。)
由于
worker-loader
不再需要,从 Webpack 5 开始,对我有用的是添加 import.meta.url
,因为通过当前文件的相对 URL 启动 Worker 不起作用。有效的方法是加载与应用程序中执行 JS 代码的 HTML 文件相关的脚本:
const worker = new Worker(new URL('./worker-test.js', import.meta.url));