When it comes to using AngularJS and browserify together, the compatibility isn't ideal. Unlike React with browserify, which seems to work well in comparison, AngularJS requires a different approach.
What I've found effective is structuring each file as an AngularJS module (since each file is already a CommonJS module) and having these files export their respective AngularJS module names.
For example, your project directory might look like this:
app/
app.js
follow/
controllers.js
directives.js
services.js
index.js
The `app.js` file would contain something similar to this:
var angular = require('angular');
var app = angular.module('mnm', [
require('./follow')
]);
// more code here
angular.bootstrap(document.body, ['mnm']);
The `follow/index.js` file would look something like this:
var angular = require('angular');
var app = angular.module('mnm.follow', [
require('./controllers'),
require('./directives'),
require('./services')
]);
module.exports = app.name;
And so on for `follow/controllers.js` and other files within the structure of your application.
This approach helps keep dependencies explicit and maintains a one-to-one mapping between CommonJS module paths and AngularJS module names, thus reducing any unexpected issues.
One potential downside of another approach lies in separating dependencies from the functions that need them, resulting in having to modify multiple files if a function's dependencies change. This could be considered a code smell.
For testability purposes, either method should suffice as Angular's module system allows importing two modules defining the same name to override each other.
In retrospect, some individuals have proposed alternative methods over the years, which I'll address below along with their trade-offs:
Utilize one global AngularJS module for the entire application and employ requires for side-effects rather than sub-modules exporting anything but manipulating the global angular object.
While common, this approach somewhat goes against the idea of modularization. Nevertheless, given AngularJS' intrinsic use of globals, focusing on side-effect based modules may seem pragmatic amidst architectural challenges.
Concatenate your AngularJS app code prior to passing it to Browserify.
This direct solution combines AngularJS and Browserify effectively from a starting point where simply concatenating app files prevails in AngularJS projects. While valid, this doesn't necessarily enhance app structure post-implementation of Browserify.
Similar to 1 but with each `index.js` defining its own AngularJS sub-module.
Following Brian Ogden's boilerplate approach, this method inherits the drawbacks of the first option while creating a semblance of hierarchy within AngularJS modules corresponding to directory structures. However, managing two sets of namespaces without consistency enforcement makes refactoring cumbersome and less desirable.
If deciding today, I'd opt for the second option considering it relinquishes any attempt to unify AngularJS and Browserify, allowing each to function independently. Additionally, integrating Browserify into an existing AngularJS build system merely entails adding an extra step.
For new projects not tied to an AngularJS codebase, it's advisable to explore alternatives such as Angular2 with native support for a proper module system or transitioning to React or Ember to bypass this particular issue altogether.