AngularJS and the browser are not, unfortunately, a great match. Of course, I don't like React and the browser, but I'm distracted.
What worked for me is that each file is an AngularJS module (because each file is already a CommonJS module) and the files export their AngularJS module name.
So your example would look like this:
app/ app.js follow/ controllers.js directives.js services.js index.js
app.js will look something like this:
var angular = require('angular'); var app = angular.module('mnm', [ require('./follow') ]);
follow/index.js will look something like this:
var angular = require('angular'); var app = angular.module('mnm.follow', [ require('./controllers'), require('./directives'), require('./services') ]); module.exports = app.name;
follow/controllers.js will look something like this:
var angular = require('angular'); var app = angular.module('mnm.follow.controllers', [ require('./services'), // internal dependency 'ui.router' // external dependency from earlier require or <script/> // more dependencies ... ]); app.controller('FollowController', ['$scope', 'FollowService', function ...]); // more code here module.exports = app.name;
And so on.
The advantage of this approach is that you keep your dependencies as clear as possible (i.e. inside the CommonJS module that they really need), and the one-to-one mapping between the CommonJS module mods and the AngularJS module names prevents unpleasant surprises.
The most obvious problem in your approach is that you keep the actual dependencies that will be inserted separately from the function that expects them, so if you change the dependencies of the functions, you need to touch two files instead of one. This is the smell of code (i.e. the Bad thing).
For testing, any approach should work as an Angular modular system, in fact, is a giant blob, and importing two modules that define the same name will override each other.
EDIT (two years later): some other people (both here and elsewhere) suggested alternative approaches, so I probably should consider them and what are the tradeoffs:
There is one global AngularJS module for your entire application and simply requires side effects (i.e. do not have submodules exporting anything other than manipulating a global Angular object).
This is apparently the most common solution, but it looks like flies in the face of modules. However, this is apparently the most pragmatic approach, and if you use AngularJS, you are already polluting global variables, so I assume that side effect modules are the least of your architectural issues.
Combine your AngularJS application code before passing it to Browserify.
This is the most literal solution to "allow the integration of AngularJS and Browserify." This is a valid approach if you start from the traditional AngularJS βjust blindly concatenate your application filesβ position and want to add Browserify for third-party libraries, so I assume that makes it valid.
As for the structure of your application, this does not improve anything by adding Browserify.
Like 1, but with each index.js defining its own AngularJS submodule.
This is a template approach proposed by Brian Ogden. This suffers from all the flaws of 1, but it creates some semblance of hierarchy inside AngularJS in that at least you have more than one AngularJS module, and the names of the AngularJS modules really match your directory structure.
However, the main drawback is that you now have two sets of namespaces that you need to worry about (your actual modules and AngularJS modules), but nothing provides consistency between the two. Not only do you need to remember that you need to import the correct modules (which again rely on side effects), but you must also remember to add them to all the correct lists and add the same template to each new file. This makes refactoring incredibly cumbersome and makes this the worst option in my opinion.
If I had to get out today, I would go with 2 because he gave up all the claims of AngularJS and Browserify that could be unified, and just left to do his job. Plus, if you already have an AngularJS build system, it literally means adding an extra step for Browserify.
If you don't inherit the AngularJS database and want to know which approach is best for starting a new project: don't start a new project in AngularJS. Either choose Angular2, which supports the real modular system out of the box, or switch to React or Ember, which do not suffer from this problem.