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?
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.
I guess you have to let NPM install the dependency
just
npm install --save autiosprite