Faz sentido usar o Require.js com Angular.js?

Sou novato no Angular.js e tentando entender como ele é diferente do Backbone.js … Usamos para gerenciar nossas dependencies de pacotes com o Require.js enquanto usamos o Backbone. Faz sentido fazer o mesmo com o Angular.js?

Sim, faz sentido usar o angular.js junto com o require.js em que você pode usar o require.js para modularizar os componentes.

Eu posso te apontar para um projeto de semente que usa both angular.js and require.js . Espero que ajude!

Para reafirmar o que eu acho que a pergunta do OP realmente é:

Se eu estou construindo uma aplicação principalmente em Angular 1.x, e (implicitamente) fazendo isso na era do Grunt / Gulp / Broccoli e Bower / NPM, e eu talvez tenha algumas dependencies adicionais de bibliotecas, requer Exceção clara e específica valor além do que eu recebo usando angular sem exigir?

Ou, em outras palavras:

“Será que o baunilha angular precisa ser gerenciado de maneira básica e eficaz, se eu tiver outras maneiras de lidar com o carregamento básico de scripts?

E eu acredito que a resposta básica para isso é: “não a menos que você tenha alguma outra coisa acontecendo, e / ou seja incapaz de usar ferramentas mais novas e modernas”.

Vamos ser claros desde o início: RequireJS é uma ótima ferramenta que resolveu alguns problemas muito importantes, e nos iniciou na estrada em que estamos, em direção a aplicativos JavaScript mais escaláveis ​​e mais profissionais. É importante notar que foi a primeira vez que muitas pessoas encontraram o conceito de modularização e de tirar as coisas do escopo global. Então, se você for construir um aplicativo Javascript que precise escalar, então o Require e o padrão AMD não são ferramentas ruins para fazer isso.

Mas, há algo de especial sobre o Angular que faz com que o Require / AMD seja particularmente adequado? Não. Na verdade, o Angular fornece a você seu próprio padrão de modularização e encapsulamento, que de muitas maneiras torna redundantes os resources básicos de modularização da AMD. E integrar os módulos Angulares ao padrão AMD não é impossível, mas é um pouco … complexo. Você definitivamente estará gastando tempo fazendo com que os dois padrões se integrem bem.

Para alguma perspectiva da própria equipe Angular, há isso , de Brian Ford, autor do Angular Batarang e agora membro da equipe principal Angular:

Eu não recomendo usar o RequireJS com o AngularJS. Embora seja certamente possível, não vi nenhuma instância em que o RequireJS fosse benéfico na prática.

Assim, na questão muito específica de AngularJS: Angular e Require / AMD são ortogonais e, em alguns lugares, se sobrepõem. Você pode usá-los juntos, mas não há razão especificamente relacionada à natureza / padrões do próprio Angular.

Mas e o gerenciamento básico de dependencies internas e externas para aplicativos JavaScript escaláveis? Não requer algo realmente crítico para mim?

Eu recomendo verificar Bower e NPM, e particularmente NPM. Eu não estou tentando começar uma guerra santa sobre os benefícios comparativos dessas ferramentas. Eu apenas quero dizer: há outras maneiras de esfolar esse gato, e essas maneiras podem ser ainda melhores do que a AMD / Require. (Eles certamente têm um impulso muito mais popular no final de 2015, particularmente o NPM, combinado com os módulos ES6 ou CommonJS. Veja a pergunta SO relacionada .)

E quanto ao carregamento lento?

Note que o carregamento lento e o download lento são diferentes. O carregamento lento do Angular não significa que você esteja puxando direto do servidor. Em um aplicativo no estilo Yeoman com automação de javascript, você está concatenando e diminuindo o conteúdo inteiro em um único arquivo. Eles estão presentes, mas não são executados / instanciados até que sejam necessários. As melhorias de velocidade e largura de banda que você obtém ao fazer isso vastamente, superam amplamente quaisquer melhorias alegadas do download preguiçoso de um determinado controlador de 20 linhas. De fato, a latência de rede desperdiçada e a sobrecarga de transmissão para aquele controlador será uma ordem de magnitude maior que o tamanho do próprio controlador.

Mas digamos que você realmente precise de downloads preguiçosos, talvez para partes pouco usadas do seu aplicativo, como uma interface de administração. Esse é um caso muito legítimo. Exigir pode realmente fazer isso por você. Mas também há muitas outras opções potencialmente mais flexíveis que realizam a mesma coisa. E o Angular 2.0 aparentemente cuidará disso para nós, embutido no roteador . ( Detalhes )

Mas e durante o desenvolvimento no meu boxen local?

Como posso obter todas as minhas dezenas / centenas de arquivos de script carregados sem precisar anexá-los todos a index.html manualmente?

Dê uma olhada nos subgeradores do gerador angular do Yeoman, ou nos padrões de automação incorporados no gerador-gulp-angular , ou na automação padrão do Webpack para o React. Eles fornecem uma maneira limpa e escalonável para: append automaticamente os arquivos no momento em que os componentes são colocados no scaffold ou simplesmente para pegá-los automaticamente se estiverem presentes em determinadas pastas / combinar determinados padrões glob. Você nunca mais precisará pensar sobre o seu próprio script de carregamento, uma vez que você tenha as últimas opções.

Bottom-line

Exigir é uma ótima ferramenta, para certas coisas. Mas vá com o grão sempre que possível e separe suas preocupações sempre que possível. Deixe o Angular se preocupar com o próprio padrão de modularização do Angular e considere o uso de módulos ES6 ou CommonJS como um padrão geral de modularização. Deixe que as ferramentas de automação modernas se preocupem com o carregamento de scripts e o gerenciamento de dependencies. E tome cuidado com o carregamento lento asynchronous de maneira granular, em vez de lidar com as outras duas preocupações.

Dito isso, se você estiver desenvolvendo aplicativos Angular, mas não puder instalar o Node em sua máquina para usar ferramentas de automação Javascript, por algum motivo, o Require pode ser uma boa solução alternativa. E eu já vi configurações realmente elaboradas, onde as pessoas querem carregar dinamicamente os componentes angulares que cada um declara suas próprias dependencies ou algo assim. E enquanto eu provavelmente tentaria resolver esse problema de outra maneira, eu posso ver os méritos da ideia, para aquela situação muito particular.

Mas por outro lado … quando começar do zero com uma nova aplicação Angular e flexibilidade para criar um ambiente de automação moderno … você tem muitas outras opções, mais flexíveis e mais modernas.

(Atualizado repetidamente para acompanhar a cena JS em evolução).

Sim, faz sentido.

Os módulos angulares não tentam resolver o problema de ordenação de carregamento de scripts ou busca de scripts preguiçosos. Essas metas são ortogonais e ambos os sistemas de módulos podem viver lado a lado e cumprir seus objectives.

Fonte: site oficial do Angular JS

Isso eu acredito que é uma questão subjetiva, então vou fornecer minha opinião subjetiva.

Angular tem um mecanismo de modularização embutido. Quando você cria seu aplicativo, a primeira coisa que você faria seria

 var app = angular.module("myApp"); 

e depois

 app.directive(...); app.controller(...); app.service(...); 

Se você der uma olhada no angular-seed que é puro aplicativo inicial para angular, eles separaram as diretivas, serviços, controladores etc. em módulos diferentes e então carregaram esses módulos como dependencies em seu aplicativo principal.

Algo como :

 var app = angular.module("myApp",["Directives","Controllers","Services"]; 

Angular também preguiçoso carrega esses módulos (na memory) e não seus arquivos de script.

Em termos de arquivos de script de carregamento lento, para ser franco, a menos que você esteja escrevendo algo extremamente grande, seria um exagero, porque a sua natureza angular reduz a quantidade de código que você escreve. Um aplicativo típico escrito na maioria das outras estruturas poderia esperar uma redução em torno de 30 a 50% no LOC, se escrito em formato angular.

Usar o RequireJS com AngularJS faz sentido, mas apenas se você entender como cada um deles funciona com relação à injeção de dependência , pois, embora ambos injetem dependencies, eles injetam coisas muito diferentes.

O AngularJS possui seu próprio sistema de dependência que permite injetar módulos AngularJS em um módulo recém-criado para reutilizar implementações. Vamos dizer que você criou um módulo “primeiro” que implementa um filtro “greet” do AngularJS:

 angular .module('first', []) .filter('greet', function() { return function(name) { return 'Hello, ' + name + '!'; } }); 

E agora digamos que você queira usar o filtro “greet” em outro módulo chamado “second” que implementa um filtro “adeus”. Você pode fazer isso injetando o “primeiro” módulo no “segundo” módulo:

 angular .module('second', ['first']) .filter('goodbye', function() { return function(name) { return 'Good bye, ' + name + '!'; } }); 

O problema é que, para que isso funcione corretamente sem o RequireJS, é necessário certificar-se de que o “primeiro” módulo AngularJS seja carregado na página antes de criar o “segundo” módulo AngularJS. Citando documentação:

Dependendo de um módulo, é necessário que o módulo necessário seja carregado antes que o módulo requerido seja carregado.

Nesse sentido, aqui é onde o RequireJS pode ajudá-lo, pois o RequireJS fornece uma maneira limpa de injetar scripts na página, ajudando você a organizar dependencies de script entre si.

Voltando aos módulos “primeiro” e “segundo” do AngularJS, veja como você pode fazer isso usando o RequireJS, separando os módulos em arquivos diferentes para aproveitar o carregamento de dependencies de script:

 // firstModule.js file define(['angular'], function(angular) { angular .module('first', []) .filter('greet', function() { return function(name) { return 'Hello, ' + name + '!'; } }); }); 
 // secondModule.js file define(['angular', 'firstModule'], function(angular) { angular .module('second', ['first']) .filter('goodbye', function() { return function(name) { return 'Good bye, ' + name + '!'; } }); }); 

Você pode ver que estamos dependendo do arquivo “firstModule” a ser injetado antes que o conteúdo do callback RequireJS possa ser executado, o que precisa que o primeiro módulo AngularJS seja carregado para criar o “segundo” módulo AngularJS.

Nota: Injetar “angular” nos arquivos “firstModule” e “secondModule” como dependência é necessário para usar AngularJS dentro da function de retorno de chamada RequireJS e tem que ser configurado na configuração RequireJS para mapear “angular” para o código da biblioteca. Você pode ter o AngularJS carregado na página de maneira tradicional também (tag de script), embora derrote os benefícios do RequireJS.

Mais detalhes sobre como ter suporte ao RequireJS a partir do núcleo AngularJS da versão 2.0 na postagem do meu blog.

Baseado no meu post “Fazendo sentido de RequireJS com AngularJS” , aqui está o link .

Como o @ganaraj mencionou, o AngularJS tem injeção de dependência em seu núcleo. Ao criar aplicativos de sementes de brinquedo com e sem o RequireJS, eu pessoalmente descobri que o RequireJS era provavelmente um exagero para a maioria dos casos de uso.

Isso não significa que o RequireJS não seja útil para seus resources de carregamento de scripts e para manter sua base de código limpa durante o desenvolvimento. A combinação do otimizador r.js ( https://github.com/jrburke/r.js ) com amêndoa ( https://github.com/jrburke/almond ) pode criar uma história de carregamento de scripts muito pequena. No entanto, como seus resources de gerenciamento de dependência não são tão importantes com o angular no núcleo de seu aplicativo, você também pode avaliar outras soluções de carregamento de script do lado do cliente (HeadJS, LABjs, …) ou mesmo do lado do servidor (MVC4 Bundler, …) para sua aplicação particular.

Sim, especialmente para SPA muito grande.

Em alguns cenários, o RequireJS é obrigatório. Por exemplo, desenvolvo aplicativos PhoneGap usando o AngularJS, que também usa a API do Google Map. Sem o carregador da AMD, como o RequireJS, o aplicativo simplesmente falharia ao ser iniciado quando estiver off-line, pois não pode criar os scripts da API do Google Maps. Um carregador da AMD me dá a chance de exibir uma mensagem de erro para o usuário.

No entanto, a integração entre o AngularJS e o RequireJS é um pouco complicada. Eu criei o angularAMD para tornar isso um processo menos doloroso:

http://marcoslin.github.io/angularAMD/

Resposta curta é, faz sentido. Recentemente, isso foi discutido em ng-conf 2014. Aqui está a palestra sobre este tema:

http://www.youtube.com/watch?v=4yulGISBF8w

Faz sentido usar requirejs com angularjs se você planejar controladores e diretivas de carregamento lento etc, além de combinar várias dependencies preguiçosas em arquivos de script simples para carregamento lento muito mais rápido. O RequireJS possui uma ferramenta de otimização que facilita a combinação. Veja http://ify.io/using-requirejs-with-optimisation-for-lazy-loading-angularjs-artefacts/

Sim, faz sentido usar requireJS com Angular, passei vários dias para testar várias soluções técnicas.

Eu fiz uma semente angular com RequireJS no lado do servidor. Muito simples. Eu uso a notação SHIM para nenhum módulo AMD e não para a AMD porque acho muito difícil lidar com dois sistemas diferentes de injeção de dependência.

Eu uso grunt e r.js para concatenar arquivos js no servidor depende do arquivo de configuração SHIM (dependência). Então eu me refiro apenas um arquivo js no meu aplicativo.

Para mais informações, visite meu github Angular Seed: https://github.com/matohawk/angular-seed-requirejs

Eu evitaria usar o Require.js. Aplicativos que eu vi que fazem isso acabar uma bagunça de vários tipos de arquitetura de padrão de módulo. AMD, Revelando, diferentes sabores de IIFE, etc. Existem outras maneiras de carregar sob demanda, como o mod loadOnDemand Angular . Adicionar outras coisas apenas preenche seu código cheio de lixo e cria uma baixa relação sinal-ruído e dificulta a leitura do seu código.

Aqui está a abordagem que eu uso: http://thaiat.github.io/blog/2014/02/26/angularjs-and-requirejs-for-very- largege – applications/

A página mostra uma possível implementação do AngularJS + RequireJS, onde o código é dividido por resources e, em seguida, por tipo de componente.

Resposta de Brian Ford

O AngularJS tem seu próprio sistema de módulos e normalmente não precisa de algo como o RJS.

Referência: https://github.com/yeoman/generator-angular/issues/40

Eu acho que isso depende da complexidade do seu projeto, já que o angular é praticamente modularizado. Seus controladores podem ser mapeados e você pode apenas importar essas classs JavaScript na sua página index.html.

Mas no caso do seu projeto ficar maior. Ou você antecipa tal cenário, você deve integrar angular com requirejs. Neste artigo, você pode ver um aplicativo de demonstração para essa integração.