Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

web worker onmessage - Uncaught SyntaxError: Unexpected token <

Following this example I wrote the following function:

var rasterToVectorWorker = new Worker(
  "../../../services/canvas/rasterToVectorWorker.js"
);

rasterToVectorWorker.postMessage("message");

rasterToVectorWorker.onmessage = e => {
  console.log("this is the return from the worker: ", e);
};

rasterToVectorWorker.js:

onmessage = function(e) {
  console.log("Message received from main script");
  var workerResult = "Result: " + e;
  console.log("Posting message back to main script");
  postMessage(workerResult);
};

But I am getting the following error message:

rasterToVectorWorker.js:1 Uncaught SyntaxError: Unexpected token <

Using window.onmessage did not solve the problem as well.

EDIT: I am using create-react-app without ejecting and adding webpack loaders

What am I doing wrong?

like image 899
Miha Šušteršič Avatar asked Mar 08 '18 11:03

Miha Šušteršič


3 Answers

I guess you can try one of those options:

The first one is to put your rasterToVectorWorker inside public folder, then your WebWorker may be loaded properly.

const rasterToVectorWorker = new Worker('rasterToVectorWorker.js');

The another option is to load your WebWorker "dynamically":


import rasterToVectorWorker from '../../../services/canvas/rasterToVectorWorker.js'

function loadWebWorker(worker) {
    const code = worker.toString();
    const blob = new Blob(['('+code+')()']);
    return new Worker(URL.createObjectURL(blob));
}

const rasterToVectorWorker = loadWebWorker(rasterToVectorWorker);

rasterToVectorWorker.postMessage("message");

like image 112
Washington Braga Avatar answered Dec 08 '22 06:12

Washington Braga


I also had the same problem with a React project when I was trying to load the web worker file and pass it to my new worker.

While I have not used the fix in create-react-app, the solution should be similar.

I found I needed to use the web worker loader, which can be found here: https://www.npmjs.com/package/worker-loader

I then updated my webpack config to inline the worker like so:

{
  test: /\.worker\.js$/,
  use: {
    loader: 'worker-loader',
    options: {
      inline: true
    }
  }
},

This then let me use my web worker.

like image 28
zeros and ones Avatar answered Dec 08 '22 08:12

zeros and ones


A solution to use web workers with create-react-app without using worker-loader is https://github.com/alewin/useWorker.

Example:

import React from "react";
import { useWorker } from "@koale/useworker";

const rasterToVector = () => {
  ...
}

const Example = () => {
  const [rasterToVectorWorker] = useWorker(rasterToVector);

  const run = async () => {
    const result = await rasterToVectorWorker(); 
    console.log("End.");
  };

  return (
    <button type="button" onClick={run}>
      Run rasterToVectorWorker
    </button>
  );
};
like image 40
Alessio Koci Avatar answered Dec 08 '22 07:12

Alessio Koci