2
votes

I'm trying to load in audiosprite in my React app which is running on a Webpack server and I'm getting the following error:

Module not found: 'child_process' in C:\Users\BenLi\Desktop\development projects\app\node_modules\audiosprite

Have no idea what this could be or why it's occurring with this module as apparently, Webpack should not throw child_process errors as it comes with it.

I'm including it in my app like so:

import audiosprite from 'audiosprite';

The error in coming from here in the file:

function spawn(name, opt) {
  opts.logger.debug('Spawn', { cmd: [name].concat(opt).join(' ') })
  return require('child_process').spawn(name, opt)
}

How do I fix this error?

2
Very tricky question (hard to debug code that you cannot see). Thanks for putting out the bounty and choosing right answer.HoldOffHunger

2 Answers

7
votes

TL;DR

There is no way around this unless you (maybe) switch to Browserify (need to test this myself) which offers a browserify-fs module. Since the browser has no access to the file system or child processes anyways, the module audiosprite can't be used in this usecase. The browser cannot do what it's incapable of.

Explanation

This is because of Webpack. Webpack, by default, is designed to compile code to run in a web-browser environment. The whole reason it exists is to bundle everything up to be browser-friendly (hence the name "web pack").

Node offers some built-in modules such as child_process, path, os, fs, etc. that only exist in a Node environment. When Webpack comes along and tries to bundle code for the browser, the browser does not have access to these modules. Thus, when modules such as audiosprite use child_process, Webpack bundles them for the web by default and you no longer have access to these modules. This explains why the error reports that the "module is not found".

"Solutions"

A "fix" is to specify your Webpack configuration to compile for usage in a Node-like environment, where you do have access to these built-in modules. That way, Webpack won't mess with the built-in modules and child_process can be used. You can do this by specifying the target option. From the Webpack Configuration documentation:

target

  • "web" Compile for usage in a browser-like environment (default)
  • "node" Compile for usage in a node.js-like environment (use require to load chunks)

(documentation cut for brevity)

But there's a consequence. Because of you setting your target as a Node environment, require will not work when using the browser as there is no require in the browser environment.

What you can do is keep the target environment the same ("web" by default) and try to mock the module for what you need. With the node option:

node

Include polyfills or mocks for various node stuff:

  • <node buildin>: true, "mock", "empty" or false

And apply it to the Webpack configuration file:

node: {
    fs: "mock"
}

But this will error out telling you:

Error: No browser version for node.js core module 'fs' available

So this is just by design. There is nothing you can do because bundling for the browser environment will inevitably forbid you from accessing the file system because it can't. You can't provide a browser mock for a module which does things that are impossible in the browser. The same goes for child_process and others.

Edit: I've been looking for some alternatives, and Browserify may or may not work. They do offer a browserify-fs module as a replacement to Node's fs. I have yet to test this so I'm not sure if it could be useful but it looks better than what Webpack does now.

-1
votes

I guess you have to let NPM install the dependency just

npm install --save autiosprite