'Melhor' maneira de declarar um módulo
Como o angular está no próprio escopo global e os módulos são salvos em sua variável, você pode acessar os módulos via angular.module('mymod'):
// one file
// NOTE: the immediately invoked function expression
// is used to exemplify different files and is not required
(function(){
// declaring the module in one file / anonymous function
// (only pass a second parameter THIS ONE TIME as a redecleration creates bugs
// which are very hard to dedect)
angular.module('mymod', []);
})();
// another file and/or another anonymous function
(function(){
// using the function form of use-strict...
"use strict";
// accessing the module in another.
// this can be done by calling angular.module without the []-brackets
angular.module('mymod')
.controller('myctrl', ['dep1', function(dep1){
//..
}])
// appending another service/controller/filter etc to the same module-call inside the same file
.service('myservice', ['dep2', function(dep2){
//...
}]);
// you can of course use angular.module('mymod') here as well
angular.module('mymod').controller('anothermyctrl', ['dep1', function(dep1){
//..
}])
})();
Nenhuma outra variável global é necessária.
Claro que depende tudo das preferências, mas acho que essa é a melhor prática, pois
- você não tem que poluir o escopo global
- você pode acessar seus módulos em qualquer lugar e classificá-los e suas funções em diferentes arquivos à vontade
- você pode usar a forma de função "use strict";
- a ordem de carregamento dos arquivos não importa tanto
Opções para classificar seus módulos e arquivos
Esta forma de declarar e acessar os módulos torna você muito flexível. Você pode classificar os módulos via tipo de função (como descrito em outra resposta) ou via rota, por exemplo:
/******** sorting by route **********/
angular.module('home')...
angular.module('another-route')...
angular.module('shared')...
Como você classifica isso no final é uma questão de gosto pessoal e da escala e tipo do projeto. Eu pessoalmente gosto de agrupar todos os arquivos de um módulo dentro da mesma pasta (ordenados em subpastas de diretivas, controladores, serviços e filtros), incluindo todos os arquivos de teste diferentes, pois torna seus módulos mais reutilizáveis. Assim, em projetos de médio porte acabo com um módulo-base, que inclui todas as rotas básicas e seus controladores, serviços, diretivas e submódulos mais ou menos complexos, quando acho que poderiam ser úteis para outros projetos também, por exemplo :
/******** modularizing feature-sets **********/
/controllers
/directives
/filters
/services
/my-map-sub-module
/my-map-sub-module/controllers
/my-map-sub-module/services
app.js
...
angular.module('app', [
'app.directives',
'app.filters',
'app.controllers',
'app.services',
'myMapSubModule'
]);
angular.module('myMapSubModule',[
'myMapSubModule.controllers',
'myMapSubModule.services',
// only if they are specific to the module
'myMapSubModule.directives',
'myMapSubModule.filters'
]);
Para projetos muito grandes, às vezes acabo agrupando módulos por rotas, como descrito acima ou por algumas rotas principais selecionadas ou mesmo uma combinação de rotas e alguns componentes selecionados, mas realmente depende.
EDIT:
Só porque está relacionado e me deparei com isso muito recentemente: Tome cuidado para criar um módulo apenas uma vez (adicionando um segundo parâmetro à função angular.module). Isso bagunçará seu aplicativo e pode ser muito difícil de detectar.
EDITAR 2015 sobre módulos de classificação:
um ano e meio de experiência angular depois, posso acrescentar que os benefícios de usar módulos com nomes diferentes em seu aplicativo são um tanto limitados, pois a AMD ainda não funciona bem com Angular e serviços, diretivas e filtros estão globalmente disponíveis dentro do contexto angular de qualquer maneira ( conforme exemplificado aqui ). No entanto, ainda há um benefício semântico e estrutural e pode ser útil ser capaz de incluir / excluir um módulo com uma única linha de código comentada dentro ou fora.
Também quase nunca faz muito sentido separar submódulos por tipo (por exemplo, 'myMapSubModule.controllers'), pois geralmente dependem uns dos outros.