¿Cuál es la diferencia entre usar Require.JS y simplemente crear un <script>
elemento en el DOM?
Entiendo que Require.JS es que ofrece la capacidad de cargar dependencias, pero ¿no puede hacerse simplemente creando un <script>
elemento que cargue el archivo JS externo necesario?
Por ejemplo, supongamos que tengo la función doStuff()
, que requiere la función needMe()
. doStuff()
está en el archivo externo do_stuff.js
, mientras needMe()
está en el archivo externo need_me.js
.
Haciendo esto de la manera Require.JS:
define(['need_me'],function(){
function doStuff(){
//do some stuff
needMe();
//do some more stuff
}
});
Hacer esto simplemente creando un elemento de script:
function doStuff(){
var scriptElement = document.createElement('script');
scriptElement.src = 'need_me.js';
scriptElement.type = 'text/javascript';
document.getElementsByTagName('head')[0].appendChild(scriptElement);
//do some stuff
needMe();
//do some more stuff
}
Ambos de estos trabajos. Sin embargo, la segunda versión no requiere que cargue toda la biblioteca Require.js. Realmente no veo ninguna diferencia funcional ...
javascript
requirejs
dynamic-script-loading
js-amd
maxedison
fuente
fuente
Respuestas:
Aquí está el buen artículo en ajaxian.com sobre por qué usarlo:
RequireJS: carga asincrónica de JavaScript
fuente
En su ejemplo, está creando la etiqueta de script de forma asincrónica, lo que significa que su
needMe()
función se invocará antes de que el archivo need_me.js termine de cargarse. Esto da como resultado excepciones no detectadas donde su función no está definida.En cambio, para hacer que lo que sugieres realmente funcione, deberías hacer algo como esto:
Podría decirse que puede o no ser mejor usar un administrador de paquetes como RequireJS o utilizar una estrategia de JavaScript puro como se demostró anteriormente. Si bien su aplicación web puede cargar más rápido, invocar la funcionalidad y las características en el sitio sería más lenta, ya que implicaría esperar a que se carguen los recursos antes de que se pueda realizar esa acción.
Si una aplicación web se crea como una aplicación de una sola página, considere que las personas no volverán a cargar la página con mucha frecuencia. En estos casos, precargar todo ayudaría a que la experiencia parezca más rápida cuando se usa la aplicación. En estos casos, tiene razón, uno simplemente puede cargar todos los recursos simplemente al incluir las etiquetas de script en el encabezado o cuerpo de la página.
Sin embargo, si se crea un sitio web o una aplicación web que sigue el modelo más tradicional en el que se realiza una transición de una página a otra, lo que hace que los recursos se vuelvan a cargar, un enfoque de carga diferida puede ayudar a acelerar estas transiciones.
fuente
Algunas otras razones muy importantes por las que usar RequireJS tiene sentido:
Tomado de los comentarios de rmurphey aquí en este Gist .
Las capas de abstracción pueden ser una pesadilla para aprender y adaptarse, pero cuando cumple un propósito y lo hace bien, tiene sentido.
fuente
Aquí hay un ejemplo más concreto.
Estoy trabajando en un proyecto con 60 archivos. Tenemos 2 modos diferentes de ejecutarlo.
Cargue una versión concatenada, 1 archivo grande. (Producción)
Cargue los 60 archivos (desarrollo)
Estamos usando un cargador, así que solo tenemos un script en la página web
El valor predeterminado es el modo n. ° 1 (cargar el archivo concatenado grande). Para ejecutar el modo in # 2 (archivos separados) configuramos alguna bandera. Podría ser cualquier cosa. Una clave en la cadena de consulta. En este ejemplo solo hacemos esto
loader.js se parece a esto
El script de compilación es solo un archivo .sh que se ve así
etc ...
Si se agrega un nuevo archivo, probablemente
injectScript("somenewfile.js")
usaremos el modo n. ° 2, ya que estamos desarrollando, tenemos que agregar una línea a loader.jsLuego, para la producción, también tenemos que agregar somenewfile.js a nuestro script de compilación. Un paso que a menudo olvidamos y luego recibimos mensajes de error.
Al cambiar a AMD no tenemos que editar 2 archivos. El problema de mantener loader.js y el script de compilación sincronizado desaparece. Usando
r.js
owebpack
simplemente puede leer el código para construirlarge-concantinated.js
También puede tratar dependencias, por ejemplo, teníamos 2 archivos lib1.js y lib2.js cargados así
lib2 necesita lib1. Tiene código dentro que hace algo como
Pero como los scripts inyectados se cargan de forma asincrónica, no hay garantía de que se carguen en el orden correcto. Estas 2 secuencias de comandos no son secuencias de comandos AMD, pero utilizando require.js podemos decirle sus dependencias
Yo nuestro módulo que usa lib1 hacemos esto
Ahora require.js inyectará los scripts por nosotros y no inyectará lib2 hasta que lib1 se haya cargado, ya que dijimos que lib2 depende de lib1. Tampoco iniciará nuestro módulo que usa lib1 hasta que se hayan cargado lib2 y lib1.
Esto hace que el desarrollo sea agradable (sin paso de compilación, sin preocuparse por el orden de carga) y hace que la producción sea agradable (no es necesario actualizar un script de compilación para cada script agregado).
Como beneficio adicional, podemos usar el complemento babel de webpack para ejecutar babel sobre el código de los navegadores más antiguos y, de nuevo, tampoco tenemos que mantener ese script de compilación.
Tenga en cuenta que si Chrome (nuestro navegador de elección) comenzó a admitirlo
import
de verdad, probablemente cambiaríamos a eso para el desarrollo, pero eso realmente no cambiaría nada. Todavía podríamos usar webpack para hacer un archivo concatenado y podríamos usarlo para ejecutar babel sobre el código para todos los navegadores.Todo esto se obtiene al no usar etiquetas de script y usar AMD
fuente