Skip to content

How to work with web workers (use a web worker IN cli project) #5885

Closed

Description

@jbgarr

Bug Report or Feature Request (mark with an x)

- [ ] bug report -> please search issues before submitting
- [X] feature request

Versions.

@angular/cli: 1.0.0
node: 6.9.1
os: darwin x64 (macOS Sierra 10.12.3)

Is there a way to import and use a web worker in a component using angular-cli? I'm trying to incorporate a web worker that I wrote into my project, but I'm not having any luck. The web worker worked fine in my project before attempting to convert it to use the CLI (previous version was based on System.js). I'm trying to import my web worker code like this:

import * as MyWorker from 'assets/workers/dropdown.worker.js';

and then I'm trying to create my actual worker instance like this:

let blob = new Blob(['(this.onmessage=', MyWorker.toString(), ')'], { type: "text/javascript" });
let dropdownWorker = new Worker((<any>window).URL.createObjectURL(blob));

The above does not work though, and if I log MyWorker right after I try to import it I see it's just an empty object instead of a function (which is what it is in my other app). Any help on this would be much appreciated!

UPDATE

I just want to clarify what I'm trying to do: I want to use an existing web worker IN my Angular app, not run my whole app IN a web worker. I know there is separate issue already that relates to the trying to run an entire app in a web worker. These are similar, but very different issues.

Activity

  1. bmayen commented on Apr 14, 2017

    @bmayen

    Check out https://stackoverflow.com/questions/43276044/angular-cli-generated-app-with-web-workers

    Would be really great to get this support by default!

  2. jbgarr commented on Apr 14, 2017

    @jbgarr
    Author

    Thanks a lot for the reply! I had seen that answer on Stackoverflow, but unfortunately they are trying to actually run their whole Angular app IN a web worker. I am trying to use an existing web worker in my app, so it's a little different. I appreciate the help though. Hopefully someone else can chime in here.

  3. maxime1992 commented on Apr 14, 2017

    @maxime1992
    Contributor

    There's an opened issue here too : #2305

  4. jbgarr commented on Apr 14, 2017

    @jbgarr
    Author

    @maxime1992 I appreciate your reply. That's a similar, but different issue. It's related to the Stackoverflow question that @bmayen linked to as well. Both of those deal with trying to run an entire Angular app IN a web worker, while I just want to use and run an existing web worker in my app.

  5. bmayen commented on Apr 14, 2017

    @bmayen

    @jbgarr, just curious, why do you want to take this approach? The Angular team has done some amazing work supporting running the entire app in a worker. You might meet with less friction if your use case could allow for that approach instead.

  6. shlangus commented on Apr 18, 2017

    @shlangus
    Contributor

    We were using an inline worker-loader, but now it does not work for us (see #4773). So now we are using file-loader.
    It's a little uncomfortable since you have to build a worker before building an app, but it works.

  7. jbgarr commented on Apr 18, 2017

    @jbgarr
    Author

    @bmayen I have a section of my app that is potential performance bottleneck so I built a custom web worker to handle the heavy lifting on another thread, but I don't necessarily need/want to run my whole app in a worker. I built the original web worker for my app before converting over to the Angular CLI to build/bundle my app and I was hoping I could just use it as is without custom tailoring my build process.

    @shlangus I had seen issue #4773 and was a bit disappointed. With your new approach are you having to use ng eject and build out some custom handling of your worker? If so, would you mind sharing whatever custom code you had to add in order to get it working? I was really hoping to avoid ng eject, but it may be required if I want to reuse my web worker as is. Thanks for any insight you can share!

  8. shlangus commented on Apr 19, 2017

    @shlangus
    Contributor

    @jbgarr First of all you need to configure build process for your worker. To do that you can create a separate webpack config such as following. It uses ts-loader so you should install it too.

    const config = {
      entry: './src/worker/worker.ts',
      output: {
        filename: './src/worker/index.js'
      },
      resolve: {
        extensions: ['.ts', '.tsx', '.js']
      },
      module: {
        loaders: [
          {test: /\.tsx?$/, loader: 'ts-loader'}
        ]
      }
    };
    
    module.exports = config;
    

    Now you are able to run webpack --config path_to_worker_config. It makes sense to add this command as "prestart" script.

    Once you have done it you need to get ability to include your worker into your angular app.
    You should add "node" in types array in your tsconfig.app.json, then you can just require your worker:

    const MyWorker = require('file-loader?name=worker.[hash:20].[ext]!../worker/index.js');
    ...
    worker = new Worker(MyWorker);
    

    This solution doesn't require to perform an ejecting but it also doesn't watch for changes in the worker.

  9. jbgarr commented on Apr 25, 2017

    @jbgarr
    Author

    @shlangus Thanks a lot for the explanation! I'll have to give that a try when I've got some time. The general idea makes sense. Thanks again, I appreciate it.

  10. filipesilva commented on May 4, 2017

    @filipesilva
    Contributor

    Heya, I added some information on how to currently use webworkers in #2305. I know there's been some conversation here but that's the original issue, and it's better to concentrate discussion in a single one.

  11. jbgarr commented on May 4, 2017

    @jbgarr
    Author

    @filipesilva Thanks for the info and I had seen that issue already, but I think there is a core difference between what I'm asking/trying to do VS what that issue touches on. I am trying to use an existing web worker IN my Angular app, while that issue focuses on running an entire Angular app IN a web worker. I believe these are similar, but very different issues. Can you consider reopening this?

  12. maxime1992 commented on May 4, 2017

    @maxime1992
    Contributor

    @filipesilva in the other issue you talked about service-worker and not web-worker :
    image

    Unless it's a typo, maybe you might reopen this (+cc @jbgarr comment)

  13. filipesilva commented on May 4, 2017

    @filipesilva
    Contributor

    @jbgarr @maxime1992 you're absolutely right, reopening.

  14. 61 remaining items

  15. shlangus commented on Oct 19, 2018

    @shlangus
    Contributor
  16. mboughaba commented on Oct 20, 2018

    @mboughaba

    @shlangus Thanks very much for the suggestion! I managed to get it working using your method
    This is how I require my file

    const StorageWorker: any = require('file-loader?name=storage.[hash:20].[ext]!../../../../dist/storage.js');
    // [...]
    // ctor
       this.worker = new Worker(StorageWorker);
    

    On the config side, I have the following

    const config = {
      entry: {
        storage: './src/worker/storage.ts'
      },
      mode: 'production',
      watch: false,
      module: {
        rules: [
          {
            test: /\.ts$/,
            loader: 'awesome-typescript-loader',
            query: {
              configFileName: './src/tsconfig.worker.json'
            }
          }
        ]
      },
      output: {
        path: path.resolve(__dirname, 'dist-worker'),
        filename: '[name].[contenthash].js'
      }
    };
    

    There is a lot of magic, but hey it works!!

    I spoke too fast 😞 ... This was loading the storage.js which was left over in the dist folder... As soon as I run the prod build which uses CleanWebpackPlugin.

  17. julkue commented on Nov 9, 2018

    @julkue

    You might be interested in using inline web workers to avoid the overhead of having to create a separate Webpack configuration with Typescript etc.:
    https://www.html5rocks.com/en/tutorials/workers/basics/#toc-inlineworkers

  18. mhosman commented on Nov 15, 2018

    @mhosman

    It could be great to create a clean repository with a full working example of an Angular 7 app with Lazy-Loading, running entirely in a web-worker.

  19. dirkluijk commented on Nov 15, 2018

    @dirkluijk

    @mhosman This issue is about using web workers IN an Angular app. Not running Angular itself in a worker.

    For the latter, see https://legacy-to-the-edge.com/2018/05/01/platform-webworker-in-angular/ (I just googled for it)

  20. mhosman commented on Nov 15, 2018

    @mhosman

    Thanks @dirkluijk, my problem is that when I'm loading modules, loaders and the UI itself is stucked for a couple of seconds. I need a way to run the logic in the background in order to get the animations only working in the main thread.

  21. added this to the needsTriage milestone on Jan 24, 2019
  22. added
    featureLabel used to distinguish feature request from other issues
    on Jan 28, 2019
  23. modified the milestones: needsTriage, Backlog on Jan 28, 2019
  24. filipesilva commented on Jan 28, 2019

    @filipesilva
    Contributor
  25. mhosman commented on Jan 28, 2019

    @mhosman

    One of the problems is when you load modules and material2 animations get stuck.

  26. angular-automatic-lock-bot commented on Sep 9, 2019

    @angular-automatic-lock-bot

    This issue has been automatically locked due to inactivity.
    Please file a new issue if you are encountering a similar or related problem.

    Read more about our automatic conversation locking policy.

    This action has been performed automatically by a bot.

  27. locked and limited conversation to collaborators on Sep 9, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions