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


Playwright CLI Flags Tutorial

5 Playwright CLI Flags That Will Transform Your Testing Workflow

  • 0:56 --last-failed
  • 2:34 --only-changed
  • 4:27 --repeat-each
  • 5:15 --forbid-only
  • 5:51 --ui --headed --workers 1

Learn how these powerful command-line options can save you time, strengthen your test suite, and streamline your Playwright testing experience. Click on any timestamp above to jump directly to that section in the tutorial!

Watch Full Video 📹️

Top comments (0)

Playwright CLI Flags Tutorial

5 Playwright CLI Flags That Will Transform Your Testing Workflow

  • --last-failed: Zero in on just the tests that failed in your previous run
  • --only-changed: Test only the spec files you've modified in git
  • --repeat-each: Run tests multiple times to catch flaky behavior before it reaches production
  • --forbid-only: Prevent accidental test.only commits from breaking your CI pipeline
  • --ui --headed --workers 1: Debug visually with browser windows and sequential test execution

Learn how these powerful command-line options can save you time, strengthen your test suite, and streamline your Playwright testing experience. Practical examples included!

Watch Video 📹️

👋 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