javascript – ¿Por qué hay una especificación para sincronización y módulos asíncronos?

Acabo de terminar de leer este artículo sobre módulos de Javascript. Puedo entender que los módulos CommonJS se cargan sincrónicamente mientras que los módulos AMD se cargan de forma asíncrona.

Lo que no entiendo es que ¿cómo puedo hacer que el módulo se convierta mágicamente sincrónico si lo escribo en el formato CommonJS, o cómo se vuelve mágicamente asincrónico si lo escribo en formato AMD ? Quiero decir que javascript no tiene una palabra clave define o require incluso. Todos ellos son especificaciones, no bibliotecas.

Me refiero a que el comportamiento de la carga del módulo depende del cargador del módulo y no de cómo está estructurado el módulo. Y si ese es el caso, ¿por qué seguir un patrón de encoding para diferentes tipos de módulos?

Estoy en lo cierto al suponer que todas las bibliotecas en el mundo NodeJS se cargan sincrónicamente, independientemente del formato en que estén escritas. Y todos los módulos en el espacio del navegador se cargan de forma asíncrona.

Si mi suposición anterior es correcta, ¿por qué hay incluso una especificación para UMD? Quiero decir, si un script se carga en función del entorno en el que está presente, ¿por qué crear una especificación para la carga universal del módulo?

¿Alguien puede ayudarme con esta confusión?

Esta es una buena pregunta. Es un tema que causó mucha discusión acalorada en la comunidad Node. Para tener una buena comprensión de lo que se trata, debes leer:

  • Node.js, TC-39 y Módulos por James M Snell de iBM
  • Interoperabilidad del módulo ES6 – Propuestas de mejora de Node.js
  • En defensa de .js – Una propuesta para módulos Node.js por Dave Herman, Yehuda Katz y Caridy Patiño
  • Discusión sobre la solicitud de extracción n. ° 3 del nodo-eps (002: interoperabilidad del módulo ES6)

Ahora, respondiendo a su pregunta: ¿Por qué hay una especificación para los módulos de sincronización y asíncrono? Porque algunas aplicaciones prefieren la carga síncrona de módulos, como los módulos del lado del servidor en Node.js donde desea cargar todo lo que necesita antes de comenzar a servir solicitudes, y algunos usos prefieren la carga asincrónica de módulos, como en el navegador cuando se usa No quiero bloquear el hilo de renderizado mientras carga las dependencias.

Realmente no hay ninguna opción para la carga sincrónica en el navegador porque haría que el navegador no responda.

Podría argumentar que podría usar carga asincrónica en el servidor, pero luego tendría que devolver las promesas en lugar de módulos por require() o podría tomar devoluciones de llamadas. De cualquier forma, haría que cualquier código complejo que usa muchos módulos sea mucho más complicado.

Otro problema es con el almacenamiento en caché y la mutación de los módulos ya cargados. Con el uso simultáneo del módulo síncrono, solo require cargar el módulo una vez y cualquier otra llamada que require para el mismo módulo en toda la base de código (para ese proceso) devolver una respuesta en caché, que es el mismo objeto cada vez. Cualquier parte del código puede modificar ese objeto y está disponible para cualquier otra parte del código. Algunas aplicaciones que usan esa característica serían mucho más complejas de implementar. Además, el orden de carga y ejecución del código sería más difícil de predecir.

Para resumir la respuesta a su pregunta, hay argumentos para ambas formas de cargar módulos y ninguna de esas formas es un ganador claro para cada escenario. Ambos son necesarios y ambos tienen algunas especificaciones para estandarizar su comportamiento.

Lea los artículos que he vinculado para una comprensión más detallada.

Me refiero a que el comportamiento de la carga del módulo depende del cargador del módulo y no de cómo está estructurado el módulo. Y si ese es el caso, ¿por qué seguir un patrón de encoding para diferentes tipos de módulos?

Si el módulo se carga de forma síncrona o asíncrona depende del cargador de módulos, pero su módulo debe poder usar un cargador de módulos, por lo tanto debe incluir una interfaz para comunicarse con el cargador. No puede cargar módulos en node.js usando la función de define amd. Tienes que usar require .

Si mi suposición anterior es correcta, ¿por qué hay incluso una especificación para UMD? Quiero decir, si un script se carga en función del entorno en el que está presente, ¿por qué crear una especificación para la carga universal del módulo?

El script no se carga en función del entorno, se carga a través de la interfaz del cargador. UMD es para bibliotecas que las personas usan tanto en el navegador como en el servidor. El autor de la biblioteca no tiene que crear dos versiones de la biblioteca, una para el navegador y otra para el nodo porque UMD sabe cómo manejar ambas.