Calling Papa.parse in worker with _config.worker = false calls postMessage

446 Views Asked by At

I am calling Papa.parse in my own worker and in _config.worker is set false. When process completes it calls postMessage still that triggers a message to my own worker. Shouldn't this

if (IS_PAPA_WORKER)
{
    global.postMessage({
        results: results,
        workerId: Papa.WORKER_ID,
        finished: finishedIncludingPreview
    });
}

Should also check if config.worker is set to true then only call global.postMessage I don't want to send results to main thread any idea how can i achieve it ?

2

There are 2 best solutions below

1
Kaiido On BEST ANSWER

They do define IS_PAPA_WORKER to

var IS_WORKER = !global.document && !!global.postMessage,
    IS_PAPA_WORKER = IS_WORKER && /blob:/i.test((global.location || {}).protocol);

This means they do check is there is no document property, a postMessage property, and if the current realm has been loaded from a blob: URI.

The best solution in your case is probably to not load your script from a blob: URI, but instead use a dedicated script file.

const worker = new Worker( '/a_real_file.js' );

Here is a demo using a data: URI, since StackSnippets don't allow storage of files, but don't use data: URIs yourself, it's just for demo the protocol matters:

const worker_script = document.querySelector( '[type="worker-script"]' ).textContent;
const worker_url = 'data:text/javascript,' + encodeURIComponent( worker_script );
const worker = new Worker( worker_url );
worker.onmessage = ({data}) => console.log( data );
worker.onerror = console.error;
<script type="worker-script">
  importScripts( 'https://cdnjs.cloudflare.com/ajax/libs/PapaParse/5.1.0/papaparse.min.js' );
  
  const csv = `col1,col2,col3
a,1,z
b,2,y
c,3,x`;
  Papa.parse( csv, { header: true } );
  postMessage( 'worker done' );
</script>

Now if you absolutely need to use a blob: URI, the simplest solution is to define document as a truthy global property before you import the library:

const worker_script = document.querySelector('[type="worker-script"]').textContent;
const worker_url = URL.createObjectURL( new Blob( [ worker_script ], { type: 'text/javascript' } ) );
const worker = new Worker( worker_url );
worker.onmessage = ({data}) => console.log( data );
<script type="worker-script">
  self.document = {};
  importScripts( 'https://cdnjs.cloudflare.com/ajax/libs/PapaParse/5.1.0/papaparse.min.js' );
  
  const csv = `col1,col2,col3
a,1,z
b,2,y
c,3,x`;
  Papa.parse( csv, { header: true } );
  postMessage( 'worker done' );
</script>

0
Shubhanu Sharma On

Who is using worker-loader in webapck don't use inline import

this.worker = await import(/* webpackChunkName: "MyWorker" */ 'workers/MyWorker') this import it as BLOB

import it using import MyWorker from 'worker-loader!./MyWorker.js'; this imports it as file and won't cause issue.