Table of contents
  1. Abstracted WebWorker
    1. worker builder file
    2. handle worker messaging file
    3. using working in compoenent
  2. Self Contained WebWorker
    1. used in a context
  3. resources
    1. react web workers walkthrough
    2. web worker with sockec




Abstracted WebWorker

set content security policy if needed in index.html


<meta http-equiv="Content-Security-Policy" content="default-src 'self'; worker-src 'self' blob:;/>

worker builder file

//worker-builder.js
export default class WorkerBuilder extends Worker {
    constructor(worker) {
        super(worker);
        const code = worker.toString();
        const blob = new Blob([`(${code})()`]);
        return new Worker(URL.createObjectURL(blob));
    }
}

handle worker messaging file

//ppt.worker.js
// eslint-disable-next-line import/no-anonymous-default-export
export default () => {
    // eslint-disable-next-line no-restricted-globals
    self.onmessage = (message) => {
        postMessage("rebuild-ppt");
    };
};

using working in compoenent

//use relative path from document baseURL
// can be set in jsconfig.js
//{
/*  "compilerOptions": {      
 "baseUrl": "src"      
 },      
 "include": ["src"]      
 }      
 */

import Worker from "containers/pptx/util/ppt.worker";

const myWorker = new WorkerBuilder(Worker);

export const MyWorkerComponent = () => {
    useEffect(() => {
        myWorker.postMessage("table-resize");
    }, []);

    useEffect(() => {
        if (window.Worker) {
            myWorker.onmessage = (message) => {
                //do work
            };
        }
    }, []);
};

Self Contained WebWorker

// worker.js
// import api from "./testModule";
// eslint-disable-next-line no-restricted-globals
const workercode = () => {
    // eslint-disable-next-line no-restricted-globals
    self.onmessage = function (event) {
        // self.importScripts("./testModule"); // eslint-disable-line no-restricted-globals
        // eslint-disable-line no-restricted-globals
        const {data} = event;
        if (data === "table-resize") {
            // self.postMessage(api.message()); // eslint-disable-line no-restricted-globals
            self.postMessage("rebuild-ppt"); // eslint-disable-line no-restricted-globals
        }
    };
};

let code = workercode.toString();
code = code.substring(code.indexOf("{") + 1, code.lastIndexOf("}"));

const blob = new Blob([code], {type: "application/javascript"});
const worker_script = URL.createObjectURL(blob);

module.exports = worker_script;

used in a context

export function TalentGridPPTXProvider({value, children}) {
    const {setLoadingExportData, isCached, setIsCached} = value;
    const myWorker = useMemo(function () {
        return new Worker(worker_script);
    }, []);

    const handleMessage = (event) => {
        if (event.data.hasOwnProperty("show_more")) {
            if (!isCached) setLoadingExportData(true);

            if (myWorker) myWorker.postMessage("table-resize");
        }
    };

    useEffect(() => {
        window.addEventListener("message", handleMessage);

        return () => {
            window.removeEventListener("message", handleMessage);

            //make sure webworker is released when component unmounts
            console.log("terminate worker");
            if (myWorker) myWorker.terminate();
        };
    }, []);
}

resources

react web workers walkthrough

web worker with sockec