Tuesday, July 19, 2016

Browserify is Sensitive in its Entry Files Parameter - "Cannot Find Module" Error

Faced an issue today whilst using Browserify to bundle some JavaScript files. The JS files had been compiled in Visual Studio Code from Typescript TSX files via gulp, and were all stored together in a single intermediate folder.

The single JS output bundle file was created just fine by Browserify. But when used in an HTML page, that file would result in a "cannot fund module" error. This error is created in the _prelude.js module, part of the output from Browserify.

So, it was time to explore the contents of the bundled JavaScript file. That file contains sections for each of the bundled modules. The last of those modules is generally the one that executes after loading. If that module needs to reference methods or properties exported by other modules, then there should be a mapping between the exported module name and that module key in the bundled modules array. Looking at the end of my output file, that mapping was as follows:

},{"./AppHeader":undefined}]},{},[1,2,3,4])

This means that the "AppHeader" module was not reachable, leading to that "cannot find module" error. After plenty of research into the bundling tool (during which I came across this useful article by Ben Clinkinbeard that describes the Browserify actions), I went back to look at the calling task in gulp. There I found that the Entry Files parameter was using a glob to point at all the JS files in the intermediate folder - the result of some previous testing in a project on which this set of files was based.

I changed this parameter to point just at the single root JS file, reran the bundling task in gulp, and now the output file ended with this:
},{"./AppHeader":1}]},{},[2])

This new bundled file worked just fine in the browser. So beware the Entry Files parameter!

PS For lots more details on this tool, consult the Browserify handbook!

1 comment:

Kyle said...

I'm having this problem too, but I can't just switch to a single entry file, since my project doesn't have one. We're in the middle of converting our large app over to use es6 (and "import" syntax), but we're just doing it a bit at a time.

What's weird is that this process (having a **/*.js) worked fine for us before node 5