2

I am trying to build ionic app that uses tensorflowjs with coco-ssd model to detect objects on images from camera. Also, I need to be able to toggle flashlight while using camera. When I use model's detection function just as promise call with await, it stops another 'threads' until detection is done. This is preventing flashlight to toggle instantly, and after button press (button that toggles flashlight), it has to wait for like half of a second to switch on or off.

I've decided to use coco-ssd in web worker, but I found out that I can't import node modules in web workers because of this error:

SyntaxError: import declarations may only appear at top level of a module   worker-test.js:1

I've searched for some similar questions, but almost nobody imports modules in web workers, and the ones that do - they do it in javascript. To enable module importing in js you just have to pass another param to worker constructor: new Worker('url/to/script.js', {type: 'module'}) But the thing is, you can't pass second parameter to worker constructor in typescript, so I can't create a worker like that.

Relevant files:
test.page.ts

...
ionViewDidEnter() {
    this.testWorker();
  }

  testWorker() {
    const worker = new Worker('assets/worker-test/worker-test.js');

    worker.onmessage = function(event) {
      console.log('onmessage');
      console.log(event.data);
    };

    worker.postMessage('From main thread');
  }
...

worker-test.js

import * as cocoSsd from '@tensorflow-models/coco-ssd';

postMessage("posting message");

onmessage = function(data) {
    console.log('In worker');
    console.log(data.data);
    console.log(model);
};

let model;

cocoSsd.load().then((res) => {
    model = res;
});

ionic info:

   ionic (Ionic CLI)             : 4.12.0 (~/.nvm/versions/node/v12.4.0/lib/node_modules/ionic)
   Ionic Framework               : @ionic/angular 4.6.2
   @angular-devkit/build-angular : 0.13.9
   @angular-devkit/schematics    : 7.3.9
   @angular/cli                  : 7.3.9
   @ionic/angular-toolkit        : 1.5.1

Thanks for help in advance.

XoMute
  • 41
  • 1
  • 5
  • Can you please add your ts.config.json to the question ? I think you might need to change the compilation option of typescript to target either `es2015` or `esnext` – edkeveked Sep 03 '19 at 14:33
  • I have previously used the solution [described here](https://stackoverflow.com/questions/40130142/run-angular-2-app-in-web-worker-using-webpack) to run a web worker with Angular. The solution works fine in an Ionic setup too and definitely helps to improve performance. – andypotato Sep 03 '19 at 18:51
  • I've just posted an answer to a similar question. It covers how to import a library inside a web worker generally, It covers parcel, webpack and mentions Angular CLI and projects managed with webpack - https://stackoverflow.com/questions/48931878/import-librarymoment-js-into-a-web-worker – kidroca Nov 23 '19 at 01:23

1 Answers1

3

The compilation option of typescript should target either es2015 or esnext.

{
  ...
  "compilerOptions": {
    "lib": ["esnext", "webworker"],
  }
}

Additionnaly adding "webworker" will indicate that the project will use the webworker api.

edkeveked
  • 17,989
  • 10
  • 55
  • 93
  • That's wrong, because 'webworker' and 'dom' libs are mutually excluded, and I need 'dom' for sure – XoMute Sep 04 '19 at 12:09
  • You can use "lib": ["esnext", "webworker"] for the webworker folder and "lib": ["esnext", "dom"] for the main folder. See how to structure one's project [here](https://stackoverflow.com/questions/56356655/structuring-a-typescript-project-with-workers) – edkeveked Sep 04 '19 at 12:24