Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Empty Worker returned after hot-reloading #24

Closed
janbaykara opened this issue Feb 24, 2018 · 16 comments · Fixed by #61
Closed

Empty Worker returned after hot-reloading #24

janbaykara opened this issue Feb 24, 2018 · 16 comments · Fixed by #61
Labels
bug Something isn't working help wanted Extra attention is needed

Comments

@janbaykara
Copy link

janbaykara commented Feb 24, 2018

For some reason, no methods are being exposed.

After I run webpack, and then make changes to a file imported into Worker.js, the Worker file returns an empty Worker with no methods. I think hot-reloading chunks doesn't play well with this loader. Restarting Yarn and refreshing the browser seems to fix the issue.

Worker.js
import someCostlyFunction from './here'

export function labelGeofences (data) {
    return someCostlyFunction(data)
}
App.js
import Worker from 'workerize-loader?inline=true!./worker'
const worker = new Worker()
console.log(worker)
// => Worker {onmessage: null, onerror: null}
worker.labelGeofences(...)
// => Error, no such property
@janbaykara janbaykara changed the title Empty Worker has no methods Worker has no exported methods Feb 25, 2018
@janbaykara janbaykara changed the title Worker has no exported methods Empty Worker returned after hot-reloading Feb 25, 2018
@developit
Copy link
Owner

Strange! What version of Webpack?

@janbaykara
Copy link
Author

@developit v3.10

I'm using a very basic setup. babel followed by workerize-loader

@willhoney7
Copy link

I'm also experiencing this all of a sudden. v1.0.2 seems to have broken webpack 3. I've set v1.0.1 in my package.json for now.

@developit
Copy link
Owner

Ah interesting 1.0.1 works - I'll see if there's anything fishy in the diff.

@developit
Copy link
Owner

developit commented Apr 13, 2018

Looks like #26 is the culprit:
71b1df8#diff-1fdf421c05c1140f6d71444ea2b27638R20

@developit developit added bug Something isn't working help wanted Extra attention is needed labels Apr 13, 2018
@exarus
Copy link

exarus commented Oct 5, 2018

@developit I think that is might be related to #32

UPD: I've tried v1.1 (before 71b1df8) and still facing the issue

It seems that issue is related to HMR. I'll try to describe my enviroment so that you could suggest where we may start bug detection.

I'm using vue-cli@2 "webpack" template (it's Vue version of create-react-app, but already ejected).

Used workerize loader like that:
src/my.js

import MyWorker from 'workerize-loader!./MyWorker';
const worker = new MyWorker();

No changes to default webpack config were made

.babelrc

{
  "presets": [
    ["env", {
      "modules": false,
      "useBuiltIns": true
    }],
    "stage-2"
  ],
  "plugins": ["transform-vue-jsx", "transform-runtime"],
}

In some time after few HMR updates MyWorker constructor always returns:
Worker {onmessage: null, onerror: null}

Hope that can help to identify issue. In near future I'll try to create a repository that reproduces the issue.

@exarus
Copy link

exarus commented Oct 30, 2018

Based on @developit suggestion to play around with webpack.hot tried this solution.

In the file that proxies the worker getWorker.js:

import MyWorker from './MyWorker.worker';

let cache;

if (module.hot) {
  module.hot.accept(['./MyWorker.worker'], () => {
    if (cache) {
      // eslint-disable-next-line global-require
      const MyWorkerLatest = require('./MyWorker.worker');
      cache = new MyWorkerLatest();
    }
  });
}

export default () => {
  if (!cache) {
    cache = new MyWorker();
  }
  return cache;
};

@exarus
Copy link

exarus commented Nov 12, 2018

I forgot to mention a detail: once the "bad" worker is returned for first time the environment is spoiled forever. Even after reloading page the worker is "bad". Only webpack-dev-server restart helps. Any ideas?

@danieldunderfelt
Copy link
Contributor

I'm also experiencing this issue. Even if I disable HMR in my project (hot: false for the dev server, remove the babel plugin and the HotModuleReplacementPlugin), the methods are still undefined after any recompile. Using workerize-loader requires me to restart the build after every change which is not sustainable. And since I am using Webpack 4 I cannot downgrade to 1.0.1.

@danieldunderfelt
Copy link
Contributor

danieldunderfelt commented Jan 2, 2019

@exarus @developit @janbaykara I found the issue! Turning off babel-loader's cacheDirectory option (set it to false) does the trick. This is enabled in CRA, and I assume most CRA derivatives like vue-cli.

Nevermind, turning off cacheDirectory worked for my simple test worker, but as soon as I started implementing what I really want to do I'm back to the same old behavior where no methods are present on the worker object after any recompile. The investigation continues...

@danieldunderfelt
Copy link
Contributor

Now I found the root fo the problem: the __workerizeExports property is not persisted on the compilation object between recompiles, resulting in an empty list of methods after the first compile. I know next to nothing about Webpack loader development, so this might not be the right way to do it, but when I save the list of methods to workerize in the parse hook on the CACHE object which is local to this loader, everything works. I'll make a PR with the change so you can see exactly what I mean.

danieldunderfelt added a commit to danieldunderfelt/workerize-loader that referenced this issue Jan 2, 2019
…e, instead of using the compilation object. Fixes developit#24 where worker methods are undefined after a recompile.
@wclr
Copy link

wclr commented Feb 26, 2019

I have the follwing situation:

const worker = require('workerize-loader!./worker')
  1. Something of the dependencies of ./worker is modified
  2. the "empty" worker is hot-reloaded (Uncaught TypeError: Object(...) is not a function).
  3. Then if I modify ./woker itself (just put comment). It hot-reloads ok.

Is it this bug? Is it going to be fixed?

@PeterEsenwa
Copy link

Now I found the root fo the problem: the __workerizeExports property is not persisted on the compilation object between recompiles, resulting in an empty list of methods after the first compile. I know next to nothing about Webpack loader development, so this might not be the right way to do it, but when I save the list of methods to workerize in the parse hook on the CACHE object which is local to this loader, everything works. I'll make a PR with the change so you can see exactly what I mean.

I tried this (edited the index.js file in the dist/ folder locally) and it works. I haven't had to change the code in my worker to see if there are any side effects but the annoying issue is gone for now. I don't have to re-run my serve script on every change. Thanks.

@shayke
Copy link

shayke commented Nov 30, 2019

I'm having the same issue (no babel) when using together with ts-loader:
{ test: /\.worker\.ts$/, loaders: [ 'workerize-loader', 'ts-loader' ] }

test.worker.ts

export async function getArray() {
    const arr: number[] = [ 1, 2, 3 ];
    return arr;
}

the methods array is empty and doesn't contain my getArray function.
I'm not using babel or hot reload, any idea how to make this work with typescript compilation?
Once i remove ts-loader from the list it works fine (without typescript of course).

@yonib05
Copy link

yonib05 commented Dec 2, 2019

Any updates on a solution for this? I am having this issue as well. It seems to only happen when I set webpack to production configuration.

@troyeagle
Copy link

@shayke Maybe it is not your ts-loader plugin but your tsconfig.json causes commonJS transform as described in the [About Babel] section in readme. Check if you have "module": "commonJS", in tsconfig.json. I encountered the same issue and make it work by modify this option to es6 (which requires additional modification because of ts check rule changed...)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working help wanted Extra attention is needed
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants