javascript - mismatched - Error de carga RequireJS intermitente
requirejs wikipedia (4)
Tengo un proyecto Backbone.js bastante grande que utiliza RequireJS. A medida que el tamaño del proyecto creció ("tamaño" aquí refiriéndose a la cantidad de archivos de módulos separados), los errores intermitentes comenzaron a aparecer. La mayoría de las veces, es un error de objeto:
Uncaught TypeError: object is not a function
Ocasionalmente, se queja de que un módulo no se está cargando.
Estos errores desaparecen una vez que el proyecto se ejecuta a través del optimizador r.js. Solo suceden cuando RequireJS está cargando los módulos individuales.
Lo que me lleva a mi pregunta: ¿RequireJS comienza a tener problemas con los módulos que se cargan a tiempo cuando el número de módulos alcanza un número determinado?
Este es definitivamente un error que he encontrado mucho en los últimos días. Cargar un módulo puede hacer que un segundo módulo no relacionado en otra parte de la aplicación se vuelva indefinido donde antes funcionaba perfectamente. He usado mucho RequireJS, esto no es una carga de script o un problema de dependencia circular. Al principio, encontré el error con mayor frecuencia cuando requiero un archivo de texto en una vista de segundo nivel que se itera varias veces (1800+):
domReady -calls-> new View1() -iterates-> new SubView() -depends-> text!template
-calls-> new View2() --> undefined!
Esto causaría que un módulo completamente no relacionado en otro lugar se vuelva indefinido. Lo resolví por un tiempo al integrar la funcionalidad SubView en el módulo de Vista.
domReady -calls-> new CombinedView1() -depends-> text!template
-calls-> new View2() --> ... all good ...
A medida que el proyecto ha crecido, he vuelto a golpear la pared y realmente necesito encontrar una manera de solucionarlo. La inclusión de más módulos hace que los definidos previamente se vuelvan indefinidos al azar. Requerir no arroja errores y tampoco lo hace el navegador. No estoy usando CoffeeScript ni nada de eso tampoco.
Me tomé un tiempo para crear una versión de mi aplicación que tenga el mismo módulo y la misma estructura de dependencia con las Vistas, Modelos y Colecciones dependientes eliminadas. Esto funciona perfectamente bien, ¿así que solo puedo asumir que hay algún tipo de problema de memoria? Sin embargo, Chrome tampoco arroja ningún error.
Creo que mi próximo paso será rellenar mi aplicación de esqueleto con algunos bucles que consumen memoria y ver qué sucede: le haré saber cómo va.
Usando Require v2.0.1, por lo que no hay plugin de orden: todas las dependencias y los paquetes se configuran usando la directiva shim config. Módulos no AMD cargados:
- Columna vertebral
- Guion bajo
- jQuery
- Bigote
- Folleto
- Oreja
PS disculpas si esto no está en el lugar correcto. Pensé que sería mejor como comentario, pero honestamente no puedo ver el botón de comentarios en ninguna parte.
Actualización: esta estructura de dependencia se rompe constantemente:
Main
- View 1
- text!...
- View 2
- text!...
Sustituir el texto con cadenas vacías funciona bien siempre:
Main
- View 1
- View 2
Entonces, ¿por qué esperar a que se cargue el texto hace que la Vista 1 se vuelva indefinida cuando se establece explícitamente como una dependencia en el módulo Principal? ¿Seguramente Main no debería llamarse hasta que se cargue todo de lo que depende?
Este problema parece tratarse en la próxima versión require.js 2.1. Mira aquí:
He estado luchando con el mismo problema los últimos días y esto es lo que descubrí:
Aparentemente, una estructura de dependencia anidada que requiere plantillas a través del complemento text.js puede causar una condición de carrera que permite que el módulo de nivel superior no esté listo cuando lo requiera. Solo me encontré con este problema cuando tenía varias estructuras de dependencia de módulos anidados de este tipo:
Router
-> View1
-> text!.../view1.html
-> View2
-> text!.../view2.html
-> View3
-> text!.../view3.html
-> View4
-> text!.../view4.html
-> View5
-> text!.../view5.html
-> View6
-> text!.../view6.html
-> View7
-> text!.../view7.html
-> View8
-> text!.../view8.html
Teniendo esta estructura, obtuve TypeErrors como ''View1 no es un constructor'' cuando el router intenta instanciar las vistas.
También requiriendo las plantillas de las vistas anidadas en las vistas de nivel superior me solucionó el problema:
Router
-> View1
-> text!.../view1.html
-> text!.../view2.html
-> View2
-> text!.../view2.html
-> View3
-> text!.../view3.html
-> text!.../view4.html
-> View4
-> text!.../view4.html
-> View5
-> text!.../view5.html
-> text!.../view6.html
-> View6
-> text!.../view6.html
-> View7
-> text!.../view7.html
-> text!.../view8.html
-> View8
-> text!.../view8.html
Realmente no sé cómo funciona require.js, ¡pero me parece que es el texto anidado! las llamadas no se consideran cuando se establece algún indicador "listo" para el módulo principal.
Verifica que tengas
- shim configurado http://requirejs.org/docs/api.html#config-shim
- propiedad ''waitSeconds'' y
- http://requirejs.org/docs/errors.html#timeout
Espero que esto ayude