2

I’m building an application that uses Vue for our front-end, specifically Vue 3 Composition API + Typescript. I need the ability to use web workers for long running processes in the background. I was able to get a vanillajs web worker to run alongside the Vue application no problem. My issue is that I need my web worker to have access to classes and functions that are written inside the Vue app. Both my web worker and my Vue app need to use the same classes and functions and I don’t want to have to write them in two places. Is there a way to share them? Any help is appreciated.

zlowe
  • 474
  • 4
  • 9
  • The question doesn't make sense without a context. Which classes and functions? You can't access anything from main app, Vue or not. Some of the code can be shared between main and worker apps if needed. It should be written with this concern in mind. – Estus Flask Mar 15 '22 at 19:42

2 Answers2

1

The answer is yes:

There is a way to let the web worker having access to the Vue.js framework through one single JavaScript file.

The library that will help you with this in your Vue.js project is vue-worker. This library uses the simple-web-worker package. (Inline Web Workers approach)

As you may know, a standard web worker requires an extra js file that will contain the code of the worker. For inline web workers it isn't necessary to use a helper method. That will inject a property into Vue (and pass it to every child component), with a default name of $worker. In total you can say it is behaving as an JavaScript promise but without really being a second JavaScript file.


Now your turn:

There is a really good documentation to follow along with this approach I described and additional a second "old-fashion" way. Try it out :)

Ole Pannier
  • 3,208
  • 9
  • 22
  • 33
  • 1
    thank you so much for your help! I was able to get a web worker running using this method but I have a problem. I can't pass in any variables, functions or classes to the web worker. It throws an error saying they're undefined, which unfortunately makes sense since it's in an entirely different scope. As far as I can tell it's not going to be possible to accomplish what I need using web workers, unless you have any more suggestions? – zlowe Mar 16 '22 at 19:21
  • You are welcome. I truly have another way for that. You can use Blob to make your worker inline too. Take a look at this post: https://stackoverflow.com/questions/5408406/web-workers-without-a-separate-javascript-file Feel free to tick the question as correct, if it will solve your problem! Good luck! – Ole Pannier Mar 16 '22 at 21:10
1

I was able to figure out a solution using esbuild. I added a process to my npm run serve and npm run build commands so it runs node ./esbuild.js before the vue-cli commands. This compiles my typescript web worker to javascript and puts it in the public folder before compiling the Vue app. Now I can create a web worker like normal using:

const worker = new Worker('/worker.js', { type: 'module' })

And here is my esbuild.js file:

const esbuild = require('esbuild')
const { nodeExternalsPlugin } = require('esbuild-node-externals')

const config = {
    entryPoints: ['./src/workers/worker.ts'],
    outfile: 'public/worker.js',
    bundle: true,
    minify: false,
    plugins: [nodeExternalsPlugin()]
}

esbuild.build(config).catch(() => process.exit(1))
zlowe
  • 474
  • 4
  • 9