javascript - ¿Tiene sentido usar Require.js con Angular.js?
requirejs angularjs (14)
Aquí está el enfoque que utilizo: http://thaiat.github.io/blog/2014/02/26/angularjs-and-requirejs-for-very-large-applications/
La página muestra una posible implementación de AngularJS + RequireJS, donde el código se divide por características y luego por tipo de componente.
Soy un novato en Angular.js y trato de entender en qué se diferencia de Backbone.js ... Solíamos administrar las dependencias de nuestros paquetes con Require.js mientras usábamos Backbone. ¿Tiene sentido hacer lo mismo con Angular.js?
Como @ganaraj mencionó, AngularJS tiene la inyección de dependencia en su núcleo. Al crear aplicaciones de semillas de juguete con y sin RequireJS, personalmente descubrí que RequireJS probablemente era una exageración en la mayoría de los casos de uso.
Eso no significa que RequireJS no sea útil por sus capacidades de carga de scripts y mantener limpio su código base durante el desarrollo. La combinación del optimizador r.js ( https://github.com/jrburke/r.js ) con almond ( https://github.com/jrburke/almond ) puede crear una historia de carga de scripts muy delgada. Sin embargo, debido a que sus funciones de administración de dependencias no son tan importantes con angular en el núcleo de su aplicación, también puede evaluar otras soluciones de carga de guiones del lado del cliente (HeadJS, LABjs, ...) o incluso del lado del servidor (MVC4 Bundler, ...) para su aplicación particular.
Creo que depende de la complejidad de su proyecto, ya que angular está prácticamente modularizado. Sus controladores pueden ser asignados y usted puede importar esas clases de JavaScript en su página index.html.
Pero en caso de que tu proyecto crezca. O anticipa tal escenario, debe integrar angular con requirejs. En this artículo puede ver una aplicación de demostración para dicha integración.
Creo que esta es una pregunta subjetiva, por lo que proporcionaré mi opinión subjetiva.
Angular tiene un mecanismo de modularización incorporado. Cuando creas tu aplicación, lo primero que harías es
var app = angular.module("myApp");
y entonces
app.directive(...);
app.controller(...);
app.service(...);
Si echa un vistazo a la semilla angular que es una aplicación de inicio limpia para angular, se han separado las directivas, servicios, controladores, etc. en diferentes módulos y luego se cargan esos módulos como dependencias en su aplicación principal.
Algo como :
var app = angular.module("myApp",["Directives","Controllers","Services"];
Angular también carga perezosamente estos módulos (en memoria) no sus archivos de script.
En términos de carga lenta de archivos de script, para ser franco, a menos que esté escribiendo algo extremadamente grande, sería una exageración porque angular por su propia naturaleza reduce la cantidad de código que escribe. Una aplicación típica escrita en la mayoría de los otros marcos podría esperar una reducción de alrededor del 30-50% en LOC si se escribe en ángulo.
La respuesta corta es que tiene sentido. Recientemente, esto se discutió en ng-conf 2014. Aquí está la charla sobre este tema:
Para reafirmar lo que creo que la pregunta del OP realmente es:
Si estoy creando una aplicación principalmente en Angular 1.x, y (implícitamente) haciendo eso en la era de Grunt / Gulp / Broccoli y Bower / NPM, y tal vez tenga un par de dependencias adicionales de la biblioteca, ¿es necesario agregar, claro, específico Valor más allá de lo que obtengo al usar Angular sin Requerir?
O, dicho de otra manera:
"¿Vanilla Angular necesita Requerir administrar la carga básica de componentes Angular de manera efectiva, si tengo otras formas de manejar la carga básica de scripts? "
Y creo que la respuesta básica a eso es: "no a menos que tenga algo más en juego y / o no pueda usar herramientas más nuevas y modernas".
Seamos claros desde el principio: RequireJS es una gran herramienta que resolvió algunos problemas muy importantes y nos inició en el camino en el que estamos, hacia aplicaciones de JavaScript más escalables y más profesionales. Es importante destacar que fue la primera vez que muchas personas encontraron el concepto de modularización y de sacar las cosas fuera del alcance global. Entonces, si vas a construir una aplicación de Javascript que necesita escalar, entonces Require y el patrón de AMD no son herramientas malas para hacerlo.
Pero, ¿hay algo en particular acerca de Angular que haga que Require / AMD sea particularmente bueno? No. De hecho, Angular le proporciona su propio patrón de modularización y encapsulación, que en muchos aspectos hace que las funciones básicas de modularización de AMD sean redundantes. Y, integrar módulos Angular en el patrón AMD no es imposible, pero es un poco ... complicado. Definitivamente pasarás tiempo consiguiendo que los dos patrones se integren bien.
Para obtener una perspectiva del equipo Angular, aquí está Brian Brian, autor de Angular Batarang y ahora miembro del equipo central Angular:
No recomiendo usar RequireJS con AngularJS. Aunque es ciertamente posible, no he visto ningún caso en el que RequireJS fuera beneficioso en la práctica.
Por lo tanto, en la pregunta muy específica de AngularJS: Angular y Require / AMD son ortogonales, y en lugares se superponen. Puede usarlos juntos, pero no hay ninguna razón específicamente relacionada con la naturaleza / los patrones de Angular.
Pero ¿qué pasa con la administración básica de dependencias internas y externas para aplicaciones de JavaScript escalables? ¿No requiere hacer algo realmente crítico para mí allí?
Recomiendo revisar Bower y NPM, y particularmente NPM. No estoy tratando de iniciar una guerra santa sobre los beneficios comparativos de estas herramientas. Simplemente quiero decir: hay otras formas de pelar a ese gato, y esas formas pueden ser incluso mejores que las de AMD / Require. (Sin duda, tienen un impulso mucho más popular a fines de 2015, especialmente NPM, combinado con los módulos ES6 o CommonJS. Consulte la pregunta SO relacionada ).
¿Qué pasa con la carga perezosa?
Tenga en cuenta que la carga perezosa y la descarga perezosa son diferentes. La carga perezosa de Angular no significa que los extraiga directamente del servidor. En una aplicación de estilo Yeoman con automatización de javascript, estás concatenando y minimizando todo el shebang en un solo archivo. Están presentes, pero no se ejecutan / instancian hasta que se necesitan. Las mejoras en la velocidad y el ancho de banda que obtiene al hacer esto superan ampliamente cualquier supuesta mejora de la descarga perezosa de un controlador particular de 20 líneas. De hecho, la latencia de red y la sobrecarga de transmisión para ese controlador serán un orden de magnitud mayor que el tamaño del controlador.
Pero digamos que realmente necesita descargas diferidas, tal vez para partes de su aplicación que no se utilizan con frecuencia, como una interfaz de administración. Ese es un caso muy legítimo. Require puede hacer eso por ti. Pero también hay many other options potentially more flexible que logran lo mismo. Y, al parecer, Angular 2.0 se encargará de esto, integrado en el router . ( Details .)
Pero ¿qué pasa durante el desarrollo en mi local dev boxen?
¿Cómo puedo cargar todas mis docenas / cientos de archivos de script sin necesidad de adjuntarlos a index.html manualmente?
Eche un vistazo a los sub-generadores en el generador angular de Yeoman, o en los patrones de automatización incorporados en generator-gulp-angular , o en la automatización de paquetes web estándar para React. Estos le brindan una forma limpia y escalable de adjuntar automáticamente los archivos en el momento en que los componentes están estructurados, o simplemente tomarlos todos automáticamente si están presentes en ciertas carpetas / coinciden con ciertos patrones globales. Nunca más tendrá que pensar en la carga de su propio script una vez que tenga las últimas opciones.
¿Línea de fondo?
Requerir es una gran herramienta, para ciertas cosas. Pero vaya con el grano siempre que sea posible, y separe sus preocupaciones siempre que sea posible. Deje que Angular se preocupe por el propio patrón de modularización de Angular, y considere usar módulos ES6 o CommonJS como un patrón de modularización general. Deje que las herramientas de automatización modernas se preocupen por la carga de scripts y la gestión de dependencias. Y cuídese de la carga perezosa asíncrona de forma granular, en lugar de enredarla con las otras dos preocupaciones.
Dicho esto, si está desarrollando aplicaciones Angular pero no puede instalar Node en su máquina para usar herramientas de automatización de Javascript por alguna razón, Require puede ser una buena solución alternativa. Y he visto configuraciones realmente elaboradas en las que las personas desean cargar dinámicamente los componentes de Angular para que cada uno declare sus propias dependencias o algo así. Y aunque probablemente trataría de resolver ese problema de otra manera, puedo ver los méritos de la idea, para esa situación tan particular.
Pero por lo demás ... al comenzar de cero con una nueva aplicación Angular y flexibilidad para crear un entorno de automatización moderno ... tienes muchas otras opciones más flexibles y modernas.
(Actualizado repetidamente para mantenerse al día con la evolución de la escena JS).
Respuesta de Brian Ford
AngularJS tiene su propio sistema de módulos y generalmente no necesita algo como RJS.
Referencia: https://github.com/yeoman/generator-angular/issues/40
Sí, lo hace, especialmente para grandes SPA.
En algún escenario, RequireJS es una necesidad. Por ejemplo, desarrollo aplicaciones de PhoneGap usando AngularJS que también usa Google Map API. Sin el cargador de AMD como RequireJS, la aplicación simplemente se bloquearía al iniciarse sin conexión, ya que no puede obtener los scripts de la API de Google Map. Un cargador de AMD me da la oportunidad de mostrar un mensaje de error al usuario.
Sin embargo, la integración entre AngularJS y RequireJS es un poco difícil. Creé angularAMD para hacer de este un proceso menos doloroso:
Sí, tiene sentido utilizar requireJS con Angular, pasé varios días para probar varias soluciones técnicas.
Hice una semilla angular con RequireJS en el lado del servidor. Muy simple. Utilizo la notación SHIM para ningún módulo de AMD y no para AMD porque creo que es muy difícil lidiar con dos sistemas de inyección de dependencia diferentes.
Uso grunt y r.js para concatenar archivos js en el servidor depende del archivo de configuración (dependencia) de SHIM. Así que solo remito un archivo js en mi aplicación.
Para obtener más información, vaya a mi github Angular Seed: https://github.com/matohawk/angular-seed-requirejs
Sí, tiene sentido.
Los módulos angulares no intentan resolver el problema del orden de carga del script o la obtención de scripts perezosos. Estos objetivos son ortogonales y ambos sistemas de módulos pueden convivir y cumplir sus objetivos.
Fuente: sitio web oficial de Angular JS
Tiene sentido utilizar requirejs con angularjs si planea controladores y directivas de carga diferida, etc., al mismo tiempo que combina múltiples dependencias diferidas en archivos de un solo script para una carga diferida mucho más rápida. RequireJS tiene una herramienta de optimización que facilita la combinación. Ver http://ify.io/using-requirejs-with-optimisation-for-lazy-loading-angularjs-artefacts/
Usar RequireJS con AngularJS tiene sentido, pero solo si entiende cómo funciona cada uno de ellos con respecto a la inyección de dependencia , ya que si bien ambos inyectan dependencias, inyectan cosas muy diferentes.
AngularJS tiene su propio sistema de dependencia que le permite inyectar módulos de AngularJS a un módulo recién creado para reutilizar las implementaciones. Digamos que creó un "primer" módulo que implementa un filtro "saludar" de AngularJS:
angular
.module(''first'', [])
.filter(''greet'', function() {
return function(name) {
return ''Hello, '' + name + ''!'';
}
});
Y ahora digamos que desea utilizar el filtro "saludo" en otro módulo llamado "segundo" que implementa un filtro de "adiós". Puede hacerlo inyectando el "primer" módulo al "segundo" módulo:
angular
.module(''second'', [''first''])
.filter(''goodbye'', function() {
return function(name) {
return ''Good bye, '' + name + ''!'';
}
});
El problema es que para que esto funcione correctamente sin RequireJS, debe asegurarse de que el "primer" módulo de AngularJS esté cargado en la página antes de crear el "segundo" módulo de AngularJS. Citando documentación:
Dependiendo de un módulo, implica que el módulo requerido debe cargarse antes de que se cargue el módulo requerido.
En ese sentido, aquí es donde RequireJS puede ayudarlo, ya que RequireJS proporciona una manera limpia de insertar secuencias de comandos en la página y ayudarlo a organizar las dependencias de las secuencias de comandos entre sí.
Volviendo a los "primeros" y "segundos" módulos de AngularJS, aquí se explica cómo puede hacerlo utilizando RequireJS separando los módulos en diferentes archivos para aprovechar las dependencias de scripts que se cargan:
// 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 + ''!'';
}
});
});
Puede ver que dependemos del archivo "FirstModule" que se va a inyectar antes de que se pueda ejecutar el contenido de la devolución de llamada RequireJS que necesita que se cargue el "primer" módulo AngularJS para crear el "segundo" módulo AngularJS.
Nota al margen: inyectar "angular" en los archivos "firstModule" y "secondModule" ya que se requiere dependencia para usar AngularJS dentro de la función de devolución de llamada RequireJS y debe configurarse en la configuración de RequireJS para asignar "angular" al código de la biblioteca. Es posible que también tenga AngularJS cargado en la página de una manera tradicional (etiqueta de script), aunque vence los beneficios de RequireJS.
Más detalles sobre la compatibilidad con RequireJS desde el núcleo de AngularJS de la versión 2.0 en mi publicación de blog.
Basado en mi blog "Haciendo sentido a RequireJS con AngularJS" , aquí está el link .
Yo evitaría usar Require.js. Las aplicaciones que he visto que hacen esto terminan con un montón de múltiples tipos de arquitectura de patrones de módulos. AMD, Revelación, diferentes sabores de IIFE, etc. Hay otras formas de cargar bajo demanda, como el mod de LoadOnDemand Angular . Agregar otras cosas simplemente llena tu código lleno de cruft y crea una baja relación señal / ruido y hace que tu código sea difícil de leer.
Sí, tiene sentido utilizar angular.js
junto con require.js
en el que puede usar require.js
para modularizar componentes.
Puedo señalarle un proyecto semilla que usa both angular.js and require.js
. ¡Espero que ayude!