Search code examples
webpackmodulenotfounderrortransitive-dependency

How to fix webpack "Module not found" error for optional transitive dependency?


I have come across the following issue, one of the software libraries I'm using has an optional dependency on 'web-worker'. If the web-worker package is available it will use it, if it cannot find the web-worker package, it will use an alternative code path that does not use the web-worker package.

The problem I run into is that when trying to create an angular build, it will give the following error.

Module not found: Error: Can't resolve 'web-worker' in 'C:\Gitdata\project\dev\angular\node_modules\elkjs\lib'

If I check the main.js file from this package, almost the first thing it does is check if web-worker is available, if it's not it will not try to load web-worker.

    var workerThreadsExist = false;
    try {
      require.resolve('web-worker');
      workerThreadsExist = true;
    } catch (e) {}

    // user requested a worker
    if (options.workerUrl) {
      if (workerThreadsExist) {
        var Worker = require('web-worker');
        optionsClone.workerFactory = function (url) {
          return new Worker(url);
        };
      } else {
        console.warn('Web worker requested but \'web-worker\' package not installed. \nConsider installing the package or pass your own \'workerFactory\' to ELK\'s constructor.\n... Falling back to non-web worker version.');
      }
    }

So even though the code flow will never require('web-worker') when it's not available, for some reason I still get the error when trying to build my application.

If I change

if (options.workerUrl)

into

if (false)

It still gives me the Module not found error, the only way to get rid of the error is to install the package or remove the

var Worker = require('web-worker');

line.

How can I tell angular or webpack to ignore this 1 missing package?


Solution

  • You can tell webpack to ignore the web-worker module that elkjs is trying to require with the webpack.IgnorePlugin.

    Inside your webpack.config.js:

    {
      plugins: [
        new webpack.IgnorePlugin({
          resourceRegExp: /web-worker/,
          contextRegExp: /elkjs\/lib$/,
        })
      ]
    }
    

    Which should tell webpack to ignore any require statement for web-worker within a directory path ending in elkjs/lib.