pedalpete pedalpete -4 years ago 229
Javascript Question

webpack 2 expose webworker as global

I'm trying to write tests for a react/redux app, and we have a bunch of webworkers which are currently imported via

require('worker-loader?inline!downloadTrackWorker')


I've been going in circles trying to figure out how to separate out this code so I can run tests in node.js without having trouble with loading the webworker.

One solution I came up with was to expose the webworker globally in my webpack, which would mean I could define a stub or mock in my tests.

In my webpack config, I've added

module: {
loaders: [...],
rules: [{
test: require.resolve(APP_DIR + '/helpers/downloadTrackWorkerLoader'),
loader: 'expose-loader',
options: 'DownloadTrackWorker'
}]
}


my trackWorkerLoader is simply

const DownloadTrackWorker = require('worker-loader?inline!./downloadTrackWorker.js');

module.export = DownloadTrackWorker;


I've also tried the above without
inline
, but no luck.

I'm experiencing two problems.


  1. when I look for
    DownloadTrackWorker
    in my console, it is undefined

  2. with my updated webpack.config, I get an error that webpack can't parse
    may need appropriate loader
    at

    ReactDOM.render(
    <Provider store={store}>
    <Player />
    </Provider>,
    document.getElementById('root')
    );



Any suggestions on what I'm doing wrong? It appears to me the issues I'm seeing are related.

Answer Source

when I look for DownloadTrackWorker in my console, it is undefined

As the expose-loader notes in Readme - Usage, you need to import it in order to be included in the bundle and therefore exposed. The rules are not including anything but are applied to the imports in your app which satisfy the test. Besides that you're also not applying the loader to the correct file. You want to apply the expose-loader to trackWorkerLoader.js, so the correct rule would be:

{
    test: require.resolve(APP_DIR + '/helpers/trackWorkerLoader'),
    loader: 'expose-loader',
    options: 'DownloadTrackWorker'
}

Now you need to import it somewhere in your app with:

require('./path/to/helpers/trackWorkerLoader');

This will correctly expose DownloadTrackWorker as a global variable, but you have a typo in trackWorkerLoader.js instead of module.exports you have module.export. Currently you're not actually exporting anything. It should be:

module.exports = DownloadTrackWorker;

Instead of inlining the worker-loader in the require (not talking about its option) you can also define it as a rule:

{
    test: require.resolve(APP_DIR + '/helpers/downloadTrackWorker'),
    loader: 'worker-loader',
    options: {
        inline: true
    }
}

And now you can simply require it without needing to specify the loaders in trackWorkerLoader.js:

const DownloadTrackWorker = require('./downloadTrackWorker');

module.exports = DownloadTrackWorker;

with my updated webpack.config, I get an error that webpack can't parse may need appropriate loader

You're defining both module.loaders and module.rules at the same time. Although module.loaders still exists for compatibility reasons, it will be ignored completely if module.rules is present. Hence the loaders you configured before, are not being applied. Simply move all rules to module.rules.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download