Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/dynamind/minimal-vue-worker
A minimal example of a Web Worker in VueJS (Vue CLI 3)
https://github.com/dynamind/minimal-vue-worker
vue webpack worker
Last synced: about 1 month ago
JSON representation
A minimal example of a Web Worker in VueJS (Vue CLI 3)
- Host: GitHub
- URL: https://github.com/dynamind/minimal-vue-worker
- Owner: dynamind
- Created: 2018-08-28T15:41:40.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2022-12-08T23:33:18.000Z (about 2 years ago)
- Last Synced: 2024-03-22T08:10:24.180Z (10 months ago)
- Topics: vue, webpack, worker
- Language: Vue
- Size: 1.07 MB
- Stars: 38
- Watchers: 1
- Forks: 5
- Open Issues: 16
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Minimal example of using a Web Worker with Vue
## Requirements
- Vue CLI 3 (see [https://cli.vuejs.org]() for installation instructions)
- `worker-loader` to let Webpack load the worker for you
- `promise-worker` to simplify communication with the worker## Running the example
This example uses the standard Vue CLI 3 commands:
```bash
yarn serve
```#### Stand-alone build
```bash
yarn build
```You could use Python's SimpleHTTPServer to check out the build locally:
```bash
cd dist
python -m SimpleHTTPServer
```## Build it yourself
### Create the app (using Vue CLI 3.0)
```bash
vue create minimal-vue-worker
# select your preferred preset, such as 'default'
cd minimal-vue-worker
```### Add `worker-loader` and `promise-worker`
```bash
yarn add --dev worker-loader promise-worker
```### Configuring the build with `vue.config.js`
### Issue with globalObject
Setting `globalObject` to `this` to fix a reference error: "Uncaught ReferenceError: window is not defined".> **Note:** This is a workaround taken from webpack/webpack#6642 (comment) and should be replaced by `target: 'universal'` when webpack/webpack#6525 has been implemented.
```js
module.exports = {
chainWebpack: config => {
config.output
.globalObject('this')
/* ... */
}
}
```#### Hot Module Replacement in Safari
For HMR there's currently an issue in Safari which can be fixed with a small config change:```js
module.exports = {
chainWebpack: config => {
/* ... */
if (process.env.NODE_ENV === 'development') {
config.output
.publicPath('/')
.filename('[name].[hash].js')
.end()
}
/* ... */
}
```#### Webpack Loader configuration
Configuring the `worker-loader` here using a rule does not work reliably.
- Hot Module Replacement does not seem to work at all
- Even refresh (F5) doesn't reload the worker javascript, unless the development server is restarted
- Sometimes the contents of `index.html` is served in stead of the worker javascript!Using the inline loader syntax works fine:
```js
import Worker from 'worker-loader!./worker'
```But if it did work, I would need to add the following configuration here, which triggers the loader for any file ending with `worker.js`. You can't use this in combination with the inline syntax.
```js
module.exports = {
chainWebpack: config => {
/* ... */
config.module
.rule('worker')
.test(/worker\.js$/)
.use('worker-loader')
.loader('worker-loader')
.end()
/* ... */
}
}
```### Create the primary entrypoints of your worker
```bash
mkdir src/my-worker
touch src/my-worker/index.js
touch src/my-worker/worker.js
```This is slightly opinionated, but the idea is this: the `index.js` defines the public API of your worker, and `worker.js` defines the private API. The `index.js` offers a thin layer of abstraction to simplify communication with the worker.
> **Note:** Take care that the `worker.js` does not import anything major from the main application, especially when you're refactoring an existing code base. You don't want to duplicate your entire app inside your worker...
#### index.js
This is the script the rest of your application sees. It sets up the `postMessage` and `onMessage` code, and exports a simple API.
```js
import PromiseWorker from 'promise-worker'
import Worker from 'worker-loader!./worker'const promiseWorker = new PromiseWorker(new Worker())
const send = message => promiseWorker.postMessage({
type: 'message',
message
})export default {
send
}
```#### worker.js
This is where messages come in and are passed on to other modules if you like.
Promise-Worker makes all this really simple and intuitive, and if you like you can still access the raw Web Worker API, i.e. `postMessage` and `onMessage`.
```js
import registerPromiseWorker from 'promise-worker/register'registerPromiseWorker((message) => {
if (message.type === 'message') {
return `Worker replies: ${JSON.stringify(message)}`
}
})
```#### Using the worker
In any part of your application where you want to use the worker, do something like this:
```js
import myWorker from '@/my-worker'
/* ... */
myWorker.send({ anything: 'you need' })
.then(reply => {
// Handle the reply
})
```