chrisguttandin / worker-timers

A replacement for setInterval() and setTimeout() which works in unfocused windows.
MIT License
590 stars 25 forks source link

How to use in a nodejs app? #281

Closed ctlkkc closed 5 years ago

ctlkkc commented 5 years ago

Hi chrisguttandin,

I've installed the package from npm and am running a nodejs app. I may be wrong but am struggling how I would be able to use worker-timers in my client pages. Does it need a reqiure() function on the client side? can you show me an example?

e.g. should it be using node_module/worker-timers/build/es5/bundle.js in the client page like: import * as workerTimers from '.libs/bundle.js'; or <script src=".libs/bundle.js"></script>

Looking forward to your reply. Thanks

chrisguttandin commented 5 years ago

Hi @ctlkkc,

worker-timers doesn't provide any file which can be dropped into a webpage directly. It is meant to be used with a bundler like webpack or Rollup.js. When using a bundler the snippet from the README should work.

If you don't want to use a bundler you can also load a prepackaged version via jspm.io like this:

<script type="module">
    import workerTimers from 'https://dev.jspm.io/worker-timers';

    workerTimers.setInterval(() => console.log('hi'), 100);
</script>
ctlkkc commented 5 years ago

Hi Chris, thanks for the jspm.io solution. I also wonder in this case the script type setting as module, instead of text/javascript, can I setInterval inside the javascript functions? e.g.

<script type="module">
    import workerTimers from 'https://dev.jspm.io/worker-timers';

    workerTimers.setInterval(() => console.log('hi'), 100);
</script>

<script type="text/javascript">
function test(){
 for (x in array){
  workerTimers.setInterval(() => console.log(x), 1000);
 }
}

test()
</script>

Would the above be suitable?

chrisguttandin commented 5 years ago

This is unfortunately not possible.

chrisguttandin commented 5 years ago

Hi @ctlkkc, sorry for the confusion. The naming is a bit misleading. It's definitely true that naming is one of the hardest problems in software development. :-) The file bundle.js is not a bundle which can be loaded with a script tag. It's called bundle because it bundles all source files, but it does NOT bundle any dependencies. In other words you need to create a bundle which contains your code, worker-timers and it's dependencies. Here is a simplified example how you could do that with webpack. But any other bundler should work as well.

Create a file with your code which imports worker-timers. Let's call it script.js.

import { setTimeout } from 'worker-timers';

setTimeout(() => {
    console.log('one second elapsed');
}, 1000);

Now you can use the webpack-cli with script.js as the entry point. webpack will look up all dependencies and create a single combined file. Just run the following command in your working directory:

webpack-cli script.js 

You can of course provide an extensive configuration but it should also work without any configuration at all. By default webpack will save the bundle as dist/main.js. This is the bundle which you can reference with a script tag.

<script type="text/javascript" src="dist/main.js"></script>

I hope this helps.

ctlkkc commented 5 years ago

Hi Chris, cool thanks. I've tested this and worked. Going back to the previous question about leaking - the bundle main.js will/will not be able to access the webpage's variable x? The main.js executes itself well but we can input variables into it that would be perfect.

<script type="text/javascript">
function test(){
 for (x in array){
  workerTimers.setInterval(() => console.log(x), 1000);
 }
}

test()
</script>
chrisguttandin commented 5 years ago

If you really want you can attach workerTimers to the window and make it a globally accessible variable. Your script.js file could than look like this:

import * as workerTimers from 'worker-timers';

window.workerTimers = workerTimers;

Maybe I'm missing something obvious, but why isn't it possible to bundle your code instead of the imaginary script.js file. Just bundle a file which contains all your code and the import statement.

import * as workerTimers from 'worker-timers';

function test(){
 for (x in array){
  workerTimers.setInterval(() => console.log(x), 1000);
 }
}

test()
chrisguttandin commented 5 years ago

Hi @ctlkkc, did you manage to find a way to import worker-timers? Or in other words, can I close the issue? :-)

ctlkkc commented 5 years ago

Hi Chris, can close the issue. I put the setTimeout into web workers dynamically and got the timed out action correctly, all is good now! Thanks

chrisguttandin commented 5 years ago

Alright, I'm happy to hear that you found a solution.