¿Existen bibliotecas para javascript en el navegador que brinden la misma flexibilidad / modularidad / facilidad de uso que las de Node require
?
Para proporcionar más detalles: la razón require
es tan buena es que:
- Permite que el código se cargue dinámicamente desde otras ubicaciones (lo cual es estilísticamente mejor, en mi opinión, que vincular todo su código en el HTML)
- Proporciona una interfaz coherente para la construcción de módulos.
- Es fácil que los módulos dependan de otros módulos (por lo que podría escribir, por ejemplo, una API que requiera jQuery para poder usar
jQuery.ajax()
- El javascript cargado tiene un alcance , lo que significa que podría cargar
var dsp = require("dsp.js");
y podría accederdsp.FFT
, lo que no interferiría con mivar FFT
Todavía tengo que encontrar una biblioteca que haga esto de manera efectiva. Las soluciones alternativas que suelo usar son:
coffeescript-concat : es bastante fácil requerir otros js, pero debe compilarlo, lo que significa que es menos bueno para un desarrollo rápido (por ejemplo, compilar API en la prueba)
RequireJS : es popular, sencillo y resuelve 1-3, pero la falta de alcance es un verdadero factor decisivo (creo que head.js es similar porque carece de alcance, aunque nunca he tenido la oportunidad de usarlo. De manera similar, los LABj pueden cargar y mitigar los
.wait()
problemas de dependencia, pero aún no tiene alcance)
Por lo que puedo decir, parece haber muchas soluciones para la carga dinámica y / o asíncrona de javascript, pero tienden a tener los mismos problemas de alcance que simplemente cargar js desde HTML. Más que cualquier otra cosa, me gustaría una forma de cargar javascript que no contamine el espacio de nombres global en absoluto, pero que aún me permita cargar y usar bibliotecas (tal como lo hacen los requisitos del nodo).
ACTUALIZACIÓN 2020: Los módulos ahora son estándar en ES6 y, a partir de mediados de 2020, la mayoría de los navegadores los admiten de forma nativa . Los módulos admiten carga síncrona y asincrónica (usando Promise). Mi recomendación actual es que la mayoría de los proyectos nuevos deben usar módulos ES6 y usar un transpilador para recurrir a un solo archivo JS para navegadores heredados.
Como principio general, el ancho de banda de hoy también suele ser mucho más amplio que cuando hice esta pregunta originalmente. Por lo tanto, en la práctica, podría elegir razonablemente usar siempre un transpilador con módulos ES6 y concentrar su esfuerzo en la eficiencia del código en lugar de la red.
EDICIÓN ANTERIOR (o si no le gustan los módulos ES6): desde que escribí esto, he usado ampliamente RequireJS (que ahora tiene una documentación mucho más clara). RequireJS realmente fue la elección correcta en mi opinión. Me gustaría aclarar cómo funciona el sistema para las personas que están tan confundidas como yo:
Puede utilizarlo require
en el desarrollo diario. Un módulo puede ser cualquier cosa devuelta por una función (normalmente un objeto o una función) y tiene un alcance como parámetro. También puede compilar su proyecto en un solo archivo para su implementación r.js
(en la práctica, esto es casi siempre más rápido, aunque require
puede cargar scripts en paralelo).
La principal diferencia entre RequireJS y el estilo de nodo require como browserify (un proyecto genial sugerido por tjameson) es la forma en que se diseñan y requieren los módulos:
- RequireJS usa AMD (Definición de módulo asíncrono). En AMD,
require
toma una lista de módulos (archivos javascript) para cargar y una función de devolución de llamada. Cuando ha cargado cada uno de los módulos, llama a la devolución de llamada con cada módulo como parámetro para la devolución de llamada. Por lo tanto, es realmente asincrónico y, por lo tanto, se adapta bien a la web. - Node usa CommonJS. En CommonJS,
require
es una llamada de bloqueo que carga un módulo y lo devuelve como un objeto. Esto funciona bien para Node porque los archivos se leen fuera del sistema de archivos, que es lo suficientemente rápido, pero funciona mal en la web porque cargar archivos sincrónicamente puede llevar mucho más tiempo.
En la práctica, muchos desarrolladores han usado Node (y por lo tanto CommonJS) antes de ver AMD. Además, muchas bibliotecas / módulos están escritos para CommonJS (agregando cosas a un exports
objeto) en lugar de para AMD (devolviendo el módulo desde la define
función). Por lo tanto, muchos desarrolladores de Node convertidos en web quieren usar bibliotecas CommonJS en la web. Esto es posible, ya que <script>
se bloquea la carga desde una etiqueta. Soluciones como browserify toman módulos CommonJS (Node) y los envuelven para que pueda incluirlos con etiquetas de script.
Por lo tanto, si está desarrollando su propio proyecto de múltiples archivos para la web, le recomiendo encarecidamente RequireJS, ya que es realmente un sistema de módulos para la web (aunque, en términos justos, creo que AMD es mucho más natural que CommonJS). Recientemente, la distinción se ha vuelto menos importante, ya que RequireJS ahora le permite usar esencialmente la sintaxis CommonJS. Además, RequireJS se puede usar para cargar módulos AMD en Node (aunque prefiero node-amd-loader ).