2

My reactjs app consists of a bunch of typescript files with a clean separation of GUI and model. The webworker needs most of model files, so maybe half of all files. I could imagine loading the webworker from exactly the same URL as the app as the model does reference neither the GUI nor React nor other unavailable stuff (At least, it shouldn't, and if so, it'd easy to clean it up).

There seem to be some problems:

  • finding the correct javascript files
  • injecting proper start up code into them

and probably others I haven't thought about yet.

The communication to the webworker is not a problem as all I need is a single async call passing and receiving some simple data.

There may be more issues like e.g., https://github.com/microsoft/TypeScript/issues/20595.

Before I learnt what I really need, I tried e.g., ttps://www.npmjs.com/package/@koale/useworker, which is nice, but seems to be able to deal with plain javascript dependencies only.

Finding the correct javascript files

What I can see in index.html is

<script src="/myapp/static/js/bundle.js"></script>
<script src="/myapp/static/js/0.chunk.js"></script>
<script src="/myapp/static/js/main.chunk.js"></script>
<script src="/myapp/main.4e45e2b4b645351b7733.hot-update.js"></script>

I guess, I could live without hot updates, however the names of the other three files change in production to something like "/myapp/static/js/2.28cf00cf.chunk.js".

Injecting proper start up code into them

When the worker loads, it executes some webpack code generated code which most probably crashes it. I'd need to avoid it somehow.

The questions

  • Is this doable at all?
  • Does it make sense or is there a better approach?
4
  • Not sure I understand the question. It sounds like you want to load all your React scripts with a webworker? I don't think is feasible as the worker does not have access to the DOM. I found this to be a helper Q&A for using Typescript with web workers. Commented Apr 30, 2020 at 17:36
  • @nrako Yes, that's what I won't. I know that any code accessing the DOM would throw, but everything should get just loaded while only the non-DOM parts should get used. I imagine it's like having function f() {return new NonExistentThingy();} in JS which can't be called, but causes no harm when only lying around. Commented May 2, 2020 at 11:31
  • I don't think this will help your app's performance as much as you think it will. Commented May 2, 2020 at 18:14
  • @RobertMoore It's not only about performance. though having a few threads should help. I need to run some expensive computation (AI) and it's surely simpler and more efficient to run it in background than trying to split the work so that the app stays responsive. Commented May 3, 2020 at 2:29

2 Answers 2

1
+50

For a seamless integration of worker code with main-thread code, I recommend using comlink-loader. For example, if you have a main.ts file and a thingy.worker.ts file, you could seamlessly load it as a worker by using TS imports:

// main.ts
import { getThing } from "./thingy.worker.ts"; // make sure the file name ends with .worker.ts

async function test() {
  console.log(`the thingy is: ${await getThing()}`);
}
// thingy.worker.ts
export async function getThing() {
  return 3;
}

You'll need to add it to your webpack config like this:

// webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.worker\.(js|ts)$/i,
        use: [{
          loader: 'comlink-loader',
          options: {
            singleton: true
          }
        }]
      }
    ]
  }
}

The best part is that your editor's intellisense will work across modules and type safety will not be compromised. More documentation is available here.

Sign up to request clarification or add additional context in comments.

4 Comments

If using CRA, this solution requires "ejecting" i guess?
I believe you could use github.com/gsoft-inc/craco or github.com/timarney/react-app-rewired and not have to eject
Sir, is there anyway to use callback or onmessage with comlink-loader? I have an interval function run in worker, I want to send a notification to the main thread each time it is run.
@EluneCrystal Maybe this could be done with asynchronous generators, but I haven't tried.
0

You need to compile a separate js file for your WebWorker. There is a React lib called react-webworker that makes this easier for you. It in turn uses WebPack’s worker-plugin.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.