DEV Community

Cover image for The easy way of using Web Workers in Nuxt.
Ismael Garcia
Ismael Garcia

Posted on • Originally published at must-know-resources-for-programmers.giessen.dev

2 1 1 1 1

The easy way of using Web Workers in Nuxt.

Base in the Vite documentation:

A web worker script can be directly imported by appending ?worker or ?sharedworker to the import request. The default export will be a custom worker constructor:

import MyWorker from './worker?worker'

const worker = new MyWorker()
Enter fullscreen mode Exit fullscreen mode

The worker script can also use ESM import statements instead of importScripts(). Note: During development this relies on browser native support, but for the production build it is compiled away.

By default, the worker script will be emitted as a separate chunk in the production build. If you wish to inline the worker as base64 strings, add the inline query:

import MyWorker from './worker?worker&inline'
Enter fullscreen mode Exit fullscreen mode

If you wish to retrieve the worker as a URL, add the url query:

import MyWorker from './worker?worker&url'
Enter fullscreen mode Exit fullscreen mode

See Worker Options for details on configuring the bundling of all workers.


How to create a web worker in your nuxt project:

Nuxt v4 Example:

  1. Create a customWebWorker.js in the app/assets folder, or you can create a folder specifically for the workers : app/assets/workers/customWebWorker.js
  2. Create a composable or import the worker in the component, but will recommend to used in a composable app/composables/useCustomWorker.ts
  3. import the web worker in the composable
// This assume that you created a folder for all the workers
import customWebWorker from "@/assets/workers/customWebWorker?worker";

Enter fullscreen mode Exit fullscreen mode
  1. Now you can create a ref for that worker
//useCustomWorker.ts
import customWebWorker from "@/assets/workers/customWebWorker?worker";

const useCustomWorker = () => {
    //...other functions

    const worker = ref<Worker | null>(null);


    const startWorker = ()=>{
        worker.value = new customWebWorker();
        worker.value.onmessage = (event) => {
                const { 
                type, // -> This will depend on you if you are emmiting from the web worker
                //...other data params emmited from the worker
                } = event.data;

                switch (type) {
                    case 'status':
                        //...Handle something here
                        break;
                    case 'error':
                        //...Handle error here
                        break;
                    case 'result':
                        // ...
                        break;
                }
            };

    }

    const postMessageToWorker = ()  =>{

        //Remember that the object sended to the worker is on you 
        // this is just a example
        worker.value?.postMessage({ type: 'START', payload: { //...payload } });
    }

    return {
        startWorker,
        postMessageToWorker
        //...other exports  
    }
}
Enter fullscreen mode Exit fullscreen mode

Here is an example of web worker that I use for voice to text transcription for https://human-ideas.giessen.dev/tools/audio-text-notes

//...import if you are using a package for some background work

import { pipeline } from "@huggingface/transformers";


const BASE_MODEL = 'Xenova/whisper-tiny.en';
let transcriber = null;
let isEnglishModel = true;

self.onmessage = async (event) => {
    //This will be base on the event that you send 
    const { type, payload } = event.data;

    switch (type) {
        case 'loadModel':
            try {
                self.postMessage({ type: 'status', status: 'loading', progress: 0 });
                if (payload.model.includes('.en')) {
                    isEnglishModel = true;
                }
                else {
                    isEnglishModel = false;
                }
                console.log('Loading model:', payload.model || BASE_MODEL);
                console.log('Is English:', isEnglishModel);

                transcriber = await pipeline('automatic-speech-recognition', payload.model || BASE_MODEL);
                self.postMessage({ type: 'status', status: 'loaded', progress: 100 });
            } catch (error) {
                self.postMessage({ type: 'error', error: error.message });
            }
            break;

        case 'transcribe':
            if (!transcriber) {
                self.postMessage({ type: 'error', error: 'Model not loaded' });
                return;
            }
            try {
                self.postMessage({ type: 'status', status: 'transcribing', progress: 0 });
                const { audio, language, model } = payload;
                console.log('Transcribing audio:', audio, 'with language:', language, 'and model:', model);
                const settings = {
                    language,
                    return_timestamps: true
                };

                const result = await transcriber(audio, !isEnglishModel ? settings : {});
                self.postMessage({ type: 'status', status: 'done', progress: 100 });
                self.postMessage({ type: 'result', result });
            } catch (error) {
                self.postMessage({ type: 'error', error: error.message });
            }
            break;

        case 'unloadModel':
            transcriber = null;
            self.postMessage({ type: 'status', status: 'unloaded', progress: 100 });
            break;

        default:
            self.postMessage({ type: 'error', error: 'Unknown message type' });
            break;
    }
};

Enter fullscreen mode Exit fullscreen mode

Happy hacking!

view raw socials.md hosted with ❤ by GitHub

Working on the audio version

The Loop VueJs Podcast

Podcast Episode


Projects:

NUXTZZLE

The base for your Nuxt/ BetterAuth &
Drizzle ORM

Must-know resources for devs
Resources to: Learn, Grow,
and Stay Updated as a Developer

Level up your computer science skills with our curated list of top websites for tips, tools, and insights. Got a favorite? Share it and grow our CS resource hub

HUMAN IDEAS

Explore the Best
Ideas created by Humans, not AI BS...

Text behind Image

Image description

Image description

Image description

Image description

Image description


Heroku

Amplify your impact where it matters most — building exceptional apps.

Leave the infrastructure headaches to us, while you focus on pushing boundaries, realizing your vision, and making a lasting impression on your users.

Get Started

Top comments (0)

Image of Stellar post

Check out Episode 1: How a Hackathon Project Became a Web3 Startup 🚀

Ever wondered what it takes to build a web3 startup from scratch? In the Stellar Dev Diaries series, we follow the journey of a team of developers building on the Stellar Network as they go from hackathon win to getting funded and launching on mainnet.

Read more

👋 Kindness is contagious

Engage with a wealth of insights in this thoughtful article, valued within the supportive DEV Community. Coders of every background are welcome to join in and add to our collective wisdom.

A sincere "thank you" often brightens someone’s day. Share your gratitude in the comments below!

On DEV, the act of sharing knowledge eases our journey and fortifies our community ties. Found value in this? A quick thank you to the author can make a significant impact.

Okay