A medida que los marcos de JavaScript como jQuery hacen que las aplicaciones web del lado del cliente sean más ricas y funcionales, comencé a notar un problema ...
¿Cómo demonios mantienes esto organizado?
- ¿Poner todos sus controladores en un solo lugar y escribir funciones para todos los eventos?
- ¿Crear funciones / clases para envolver toda su funcionalidad?
- ¿Escribir como loco y solo esperar que funcione mejor?
- ¿Renunciar y obtener una nueva carrera?
Menciono jQuery, pero en realidad es cualquier código JavaScript en general. Estoy descubriendo que a medida que las líneas comienzan a acumularse, se hace más difícil administrar los archivos de script o encontrar lo que está buscando. Posiblemente, el mayor problema que he encontrado es que hay tantas maneras de hacer lo mismo, que es difícil saber cuál es la mejor práctica actual comúnmente aceptada.
¿Hay alguna recomendación general sobre la mejor manera de mantener sus archivos .js tan bonitos y ordenados como el resto de su aplicación? ¿O es solo una cuestión de IDE? ¿Hay una mejor opción por ahí?
EDITAR
Esta pregunta pretendía ser más sobre la organización del código y no sobre la organización de archivos. Ha habido algunos ejemplos realmente buenos de fusión de archivos o división de contenido.
Mi pregunta es: ¿cuál es la forma de práctica recomendada actual comúnmente aceptada para organizar su código real? ¿Cuál es su manera, o incluso una forma recomendada de interactuar con los elementos de la página y crear código reutilizable que no entre en conflicto?
Algunas personas han incluido espacios de nombres, lo cual es una buena idea. ¿De qué otras maneras se trata más específicamente con elementos en la página y mantener el código organizado y ordenado?
Respuestas:
Sería mucho mejor si JavaScript tuviera espacios de nombres integrados, pero creo que organizar cosas como las que describe Dustin Díaz aquí me ayuda mucho.
Puse diferentes "espacios de nombres" y, a veces, clases individuales en archivos separados. Por lo general, comienzo con un archivo y cuando una clase o espacio de nombres se vuelve lo suficientemente grande como para garantizarlo, lo separo en su propio archivo. Usar una herramienta para combinar todos sus archivos para la producción también es una excelente idea.
fuente
module pattern
y se basa en elIIFE pattern
.createNewSomething()
en el objeto de retorno, por lo que la creación de objetos ocurre únicamente dentro del módulo? Hm ... esperaría que las clases (constructores) sean visibles desde el exterior.Intento evitar incluir JavaScript con el HTML. Todo el código está encapsulado en clases y cada clase está en su propio archivo. Para el desarrollo, tengo etiquetas <script> separadas para incluir cada archivo js, pero se fusionan en un solo paquete más grande para la producción para reducir la sobrecarga de las solicitudes HTTP.
Normalmente, tendré un solo archivo js 'principal' para cada aplicación. Entonces, si estaba escribiendo una aplicación de "encuesta", tendría un archivo js llamado "survey.js". Esto contendría el punto de entrada en el código jQuery. Creo referencias de jQuery durante la creación de instancias y luego las paso a mis objetos como parámetros. Esto significa que las clases javascript son 'puras' y no contienen referencias a identificadores CSS o nombres de clases.
También encuentro que la convención de nomenclatura es importante para la legibilidad. Por ejemplo: antepongo 'j' a todas las instancias de jQuery.
En el ejemplo anterior, hay una clase llamada DimScreen. (Suponga que esto atenúa la pantalla y abre un cuadro de alerta). Necesita un elemento div que se pueda ampliar para cubrir la pantalla, y luego agregar un cuadro de alerta, por lo que paso un objeto jQuery. jQuery tiene un concepto de complemento, pero parecía limitante (por ejemplo, las instancias no son persistentes y no se puede acceder a ellas) sin una ventaja real. Entonces, la clase DimScreen sería una clase estándar de javascript que simplemente usa jQuery.
He creado algunas aplicaciones bastante complejas utilizando este enfoque.
fuente
$
como prefijo de nombre de variable es una práctica más común, pero podría estar equivocado. Entonces, en$s = $('...')
lugar dejS = $('...')
, solo es una cuestión de preferencia, supongo. Sin embargo, es interesante, ya que se cree que la notación húngara es un olor a código. Es extraño cuán diferentes son algunas de mis convenciones / preferencias de código JavaScript para mis convenciones de codificación C # / Java.Systems Hungarian
como un olor de código yApps Hungarian
como una práctica a partir de ahora :)var
, ahora que lo pienso. La mayoría de los argumentos en contra del usovar
es donde no estará seguro del 'tipo' de lo que se devuelve, pero supongo que el argumento debería estar en contra de no conocer la 'clase' de lo que se devuelve. Si usa Apps Hungarian, entonces no debería tener esa preocupación ... interesante.Puede dividir sus scripts en archivos separados para el desarrollo, luego crear una versión de "lanzamiento" donde los reúna todos y ejecute YUI Compressor o algo similar en él.
fuente
Inspirado en publicaciones anteriores, hice una copia de Rakefile y directorios de proveedores distribuidos con WysiHat (un RTE mencionado por changelog) e hice algunas modificaciones para incluir la verificación de código con JSLint y la minificación con YUI Compressor .
La idea es usar Sprockets (de WysiHat) para fusionar múltiples JavaScripts en un solo archivo, verificar la sintaxis del archivo combinado con JSLint y minimizarlo con YUI Compressor antes de la distribución.
Prerrequisitos
Ahora haz
Ahora cree un archivo llamado "Rakefile" en el directorio raíz del proyecto JavaScript y agregue el siguiente contenido:
Si hizo todo correctamente, debería poder usar los siguientes comandos en su consola:
rake merge
- para combinar diferentes archivos JavaScript en unorake check
- para verificar la sintaxis de su código (esta es la tarea predeterminada , por lo que simplemente puede escribirrake
)rake minify
- para preparar una versión reducida de su código JSEn fusión de fuente
Usando Sprockets, el preprocesador de JavaScript puede incluir (u
require
) otros archivos JavaScript. Use la siguiente sintaxis para incluir otros scripts del archivo inicial (llamado "main.js", pero puede cambiar eso en el Rakefile):Y entonces...
Eche un vistazo a Rakefile proporcionado con WysiHat para configurar la unidad automatizada de pruebas. Lindas cosas :)
Y ahora por la respuesta
Esto no responde muy bien la pregunta original. Lo sé y lo siento, pero lo he publicado aquí porque espero que pueda ser útil para que otra persona organice su desorden.
Mi enfoque del problema es hacer todo el modelado orientado a objetos que pueda y separar las implementaciones en diferentes archivos. Entonces los manejadores deben ser lo más cortos posible. El ejemplo con
List
singleton también es agradable.Y espacios de nombres ... bueno, pueden ser imitados por una estructura de objetos más profunda.
No soy un gran admirador de las imitaciones, pero esto puede ser útil si tiene muchos objetos que le gustaría mover fuera del alcance global.
fuente
La organización del código requiere la adopción de convenciones y estándares de documentación:
1. Código de espacio de nombres para un archivo físico;
2. Clases de grupo en estos espacios de nombres javascript;
3. Establecer prototipos o funciones o clases relacionadas para representar objetos del mundo real;
4. Establecer convenciones para mejorar el código. Por ejemplo, agrupe todas sus funciones o métodos internos en su atributo de clase de un tipo de objeto.
5. Realizar documentación de espacios de nombres, clases, métodos y variables. Cuando sea necesario, también discuta parte del código (algunas FI y Fors, generalmente implementan una lógica importante del código).
Estos son solo algunos consejos, pero eso ha ayudado enormemente a organizar el código. ¡Recuerde que debe tener disciplina para tener éxito!
fuente
Seguir buenos principios de diseño OO y patrones de diseño ayuda mucho a que su código sea fácil de mantener y comprender. Pero una de las mejores cosas que he descubierto recientemente son las señales y las ranuras también conocidas como publicación / suscripción. Eche un vistazo a http://markdotmeyer.blogspot.com/2008/09/jquery-publish-subscribe.html para una implementación simple de jQuery.
La idea se usa bien en otros idiomas para el desarrollo de GUI. Cuando sucede algo significativo en algún lugar de su código, publica un evento sintético global al que pueden suscribirse otros métodos en otros objetos. Esto proporciona una excelente separación de los objetos.
Creo que Dojo (¿y Prototype?) Tiene una versión integrada de esta técnica.
ver también ¿Qué son las señales y las ranuras?
fuente
Pude aplicar con éxito el Patrón del Módulo Javascript a una aplicación Ext JS en mi trabajo anterior. Proporcionó una manera simple de crear código bien encapsulado.
fuente
Dojo tenía el sistema de módulos desde el primer día. De hecho, se considera una piedra angular de Dojo, el pegamento que lo mantiene unido:
Utilizando módulos, Dojo logra los siguientes objetivos:
dojo.declare()
): no contamine el espacio global, coexista con otras bibliotecas y el código del usuario que no sea Dojo.dojo.require()
).fuente
Echa un vistazo a JavasciptMVC .
Usted puede :
divide tu código en capas de modelo, vista y controlador.
comprimir todo el código en un solo archivo de producción
autogenerar código
crear y ejecutar pruebas unitarias
y mucho más ...
Lo mejor de todo es que utiliza jQuery, por lo que también puede aprovechar otros complementos de jQuery.
fuente
¡Mi jefe todavía habla de los tiempos en que escribieron código modular (lenguaje C), y se queja de lo malo que es el código hoy en día! Se dice que los programadores pueden escribir ensamblados en cualquier marco. Siempre hay una estrategia para superar la organización del código. El problema básico es con los chicos que tratan el script java como un juguete y nunca intentan aprenderlo.
En mi caso, escribo archivos js en un tema de UI o en una pantalla de aplicación, con un init_screen adecuado (). Utilizando la convención de nomenclatura de identificación adecuada, me aseguro de que no haya conflictos de espacio de nombres en el nivel del elemento raíz. En la discreta ventana.load (), ato las cosas según la identificación de nivel superior.
Uso estrictamente los patrones y cierres de script java para ocultar todos los métodos privados. Después de hacer esto, nunca se enfrentó a un problema de propiedades en conflicto / definiciones de funciones / definiciones de variables. Sin embargo, cuando se trabaja con un equipo, a menudo es difícil imponer el mismo rigor.
fuente
Me sorprende que nadie haya mencionado los marcos MVC. He estado usando Backbone.js para modularizar y desacoplar mi código, y ha sido invaluable.
Existen bastantes de estos tipos de frameworks, y la mayoría de ellos también son bastante pequeños. Mi opinión personal es que si vas a escribir más que solo un par de líneas de jQuery para cosas llamativas de la interfaz de usuario, o si quieres una aplicación rica de Ajax, un marco MVC te hará la vida mucho más fácil.
fuente
"¿Escribir como loco y solo espero que funcione de la mejor manera?", He visto un proyecto como este que fue desarrollado y mantenido por solo 2 desarrolladores, una gran aplicación con mucho código javascript. Además de eso, había diferentes accesos directos para cada posible función jquery que se te ocurra. Sugerí que organizaran el código como complementos, ya que es el equivalente jquery de clase, módulo, espacio de nombres ... y todo el universo. Pero las cosas se pusieron mucho peor, ahora comenzaron a escribir complementos reemplazando cada combinación de 3 líneas de código utilizadas en el proyecto. Personalmente, creo que jQuery es el demonio y no debería usarse en proyectos con muchos javascript porque te alienta a ser flojo y no pensar en organizar el código de ninguna manera. Prefiero leer 100 líneas de JavaScript que una línea con 40 funciones jQuery encadenadas (I ' No estoy bromeando). Contrariamente a la creencia popular, es muy fácil organizar el código javascript en equivalentes a espacios de nombres y clases. Eso es lo que hacen YUI y Dojo. Puede rodar fácilmente el suyo si lo desea. Encuentro el enfoque de YUI mucho mejor y eficiente. Pero generalmente necesita un buen editor con soporte para fragmentos para compensar las convenciones de nomenclatura de YUI si desea escribir algo útil.
fuente
Creo singletons para cada cosa que realmente no necesito instanciar varias veces en la pantalla, una clase para todo lo demás. Y todos ellos se colocan en el mismo espacio de nombres en el mismo archivo. Todo está comentado y diseñado con UML, diagramas de estado. El código javascript no contiene html, por lo que no hay javascript en línea y tiendo a usar jquery para minimizar los problemas entre navegadores.
fuente
En mi último proyecto -Viajeros.com- he usado una combinación de varias técnicas. No sabría cómo organizar una aplicación web: Viajeros es un sitio de redes sociales para viajeros con secciones bien definidas, por lo que es fácil separar el código de cada área.
Utilizo la simulación del espacio de nombres y la carga diferida de módulos de acuerdo con la sección del sitio. En cada carga de página, declaro un objeto "vjr", y siempre le cargo un conjunto de funciones comunes (vjr.base.js). Luego, cada página HTML decide qué módulos necesita con un simple:
Vjr.base.js obtiene cada uno comprimido del servidor y los ejecuta.
Cada "módulo" tiene esta estructura:
Dado mi limitado conocimiento de Javascript, sé que debe haber mejores formas de administrar esto, pero hasta ahora está funcionando muy bien para nosotros.
fuente
Organizar su código de una manera NameSpace centrada en Jquery puede verse de la siguiente manera ... y no chocará con otras API de Javascript como Prototype, Ext tampoco.
Espero que esto ayude.
fuente
jQuery.fn
es un puntero ajQuery.prototype
, porque en$()
realidad devuelve una nueva instancia de la función constructora jQuery. Agregar un 'complemento' a jQuery significa simplemente extender su prototipo. Pero lo que está haciendo no es eso, y hay formas más limpias de lograr lo mismo.Un buen principio de OO + MVC definitivamente ayudaría mucho a administrar una aplicación javascript compleja.
Básicamente estoy organizando mi aplicación y javascript para el siguiente diseño familiar (que existe desde mis días de programación de escritorio hasta la Web 2.0)
Descripción de los valores numéricos en la imagen:
En el pasado, separaba los archivos en sus propios js y usaba la práctica común para crear principios OO en Javascript. El problema que pronto descubrí es que hay múltiples formas de escribir JS OO y no es necesariamente que todos los miembros del equipo tengan el mismo enfoque. A medida que el equipo se hizo más grande (en mi caso, más de 15 personas), esto se complica porque no hay un enfoque estándar para Javascript orientado a objetos. Al mismo tiempo, no quiero escribir mi propio marco y repetir parte del trabajo que estoy seguro de que son personas más inteligentes de las que he resuelto.
jQuery es increíblemente agradable como Javascript Framework y me encanta, sin embargo, a medida que el proyecto crece, claramente necesito una estructura adicional para mi aplicación web, especialmente para facilitar la práctica estandarizada de OO. Para mí, después de varios experimentos, encuentro que la infraestructura YUI3 Base and Widget ( http://yuilibrary.com/yui/docs/widget/ y http://yuilibrary.com/yui/docs/base/index.html ) proporciona exactamente lo que necesito Pocas razones por las que los uso.
Contrariamente a muchas vistas, no necesariamente tengo que elegir entre jQuery y YUI3. Estos dos pueden coexistir pacíficamente. Si bien YUI3 proporciona la plantilla de OO necesaria para mi aplicación web compleja, jQuery todavía proporciona a mi equipo una abstracción JS fácil de usar que todos amamos y conocemos.
Usando YUI3, he logrado crear un patrón MVC separando las clases que extienden la Base como el Modelo, las clases que extienden el Widget como una Vista y, por supuesto, tiene clases de Controlador que están haciendo la lógica necesaria y las llamadas del lado del servidor.
Widget puede comunicarse entre sí utilizando un modelo basado en eventos y escuchando el evento y haciendo la tarea necesaria basada en una interfaz predefinida. En pocas palabras, poner la estructura OO + MVC a JS es una alegría para mí.
Solo un descargo de responsabilidad, no trabajo para Yahoo! y simplemente un arquitecto que intenta hacer frente al mismo problema que plantea la pregunta original. Creo que si alguien encuentra un marco OO equivalente, esto también funcionaría. Principalmente, esta pregunta también se aplica a otras tecnologías. Gracias a Dios por todas las personas que idearon los Principios OO + MVC para hacer que nuestros días de programación sean más manejables.
fuente
Utilizo la administración de paquetes de Dojo (
dojo.require
ydojo.provide
) y el sistema de clases (dojo.declare
que también permite una herencia múltiple simple) para modularizar todas mis clases / widgets en archivos separados. No solo dosificar esto mantiene su código organizado, sino que también le permite cargar pereza / justo a tiempo las clases / widgets.fuente
Hace unos días, los chicos de 37Signals lanzaron un control RTE , con un giro. Crearon una biblioteca que agrupa archivos javascript utilizando una especie de comandos de preprocesador.
Lo he estado usando desde entonces para separar mis archivos JS y luego, al final, fusionarlos como uno. De esa manera, puedo separar las preocupaciones y, al final, solo tengo un archivo que pasa por la tubería (comprimido, nada menos).
En sus plantillas, verifique si está en modo de desarrollo e incluya los archivos separados, y si está en producción, incluya el último (que tendrá que "construir" usted mismo).
fuente
Cree clases falsas y asegúrese de que todo lo que se pueda incluir en una función separada que tenga sentido se haga así. También asegúrate de comentar mucho, y no escribir código spagghetti, sino mantenerlo todo en secciones. Por ejemplo, un código sin sentido que representa mis ideales. Obviamente en la vida real también escribo muchas bibliotecas que básicamente abarcan su funcionalidad.
fuente
Use patrones de herencia para organizar grandes aplicaciones jQuery.
fuente
Creo que esto se relaciona, quizás, con DDD (diseño impulsado por dominio). La aplicación en la que estoy trabajando, aunque carece de una API formal, da indicios de ello a través del código del lado del servidor (nombres de clase / archivo, etc.). Armado con eso, creé un objeto de nivel superior como contenedor para todo el dominio del problema; luego, agregué espacios de nombres en donde sea necesario:
fuente
Para la organización de JavaScript he estado usando lo siguiente
fuente
Estoy usando esta pequeña cosa. Le da la directiva 'incluir' para las plantillas JS y HTML. Elimina el desorden por completo.
https://github.com/gaperton/include.js/
fuente
Puede usar jquery mx (usado en javascriptMVC), que es un conjunto de scripts que le permite usar modelos, vistas y controladores. Lo he usado en un proyecto y me ayudó a crear JavaScript estructurado, con tamaños mínimos de script debido a la compresión. Este es un ejemplo de controlador:
También puede usar solo el lado del controlador de jquerymx si no está interesado en la vista y las partes del modelo.
fuente
Su pregunta es una que me atormentó a fines del año pasado. La diferencia: entregar el código a los nuevos desarrolladores que nunca habían oído hablar de métodos privados y públicos. Tuve que construir algo simple.
El resultado final fue un marco pequeño (alrededor de 1 KB) que traduce literales de objetos en jQuery. La sintaxis es visualmente más fácil de escanear, y si su js crece demasiado, puede escribir consultas reutilizables para encontrar elementos como selectores utilizados, archivos cargados, funciones dependientes, etc.
Publicar un pequeño marco aquí no es práctico, así que escribí una publicación en el blog con ejemplos (Mi primero. ¡Fue una aventura!). Eres bienvenido a echar un vistazo.
Para cualquier otro aquí con unos minutos para verlo, agradecería mucho sus comentarios.
Se recomienda FireFox ya que admite toSource () para el ejemplo de consulta de objeto.
¡Salud!
Adán
fuente
Utilizo un script personalizado inspirado en el comportamiento de Ben Nolan (por desgracia, ya no puedo encontrar un enlace actual para esto) para almacenar la mayoría de mis controladores de eventos. Estos controladores de eventos son activados por los elementos className o Id, por ejemplo. Ejemplo:
Me gusta incluir la mayoría de mis bibliotecas Javascript sobre la marcha, excepto las que contienen un comportamiento global. Utilizo el asistente de marcador de posición headScript () de Zend Framework para esto, pero también puede usar JavaScript para cargar otros scripts sobre la marcha con Ajile, por ejemplo.
fuente
No mencionas cuál es el idioma del lado del servidor. O, más pertinente, qué marco está utilizando, si lo hay, en el lado del servidor.
IME, organizo las cosas en el lado del servidor y dejo que todo se agite en la página web. El marco tiene la tarea de organizar no solo JS que cada página debe cargar, sino también fragmentos JS que funcionan con el marcado generado. Tales fragmentos que generalmente no desea emitir más de una vez, es por eso que se abstraen en el marco para que ese código se ocupe de ese problema. :-)
Para las páginas finales que tienen que emitir su propio JS, generalmente encuentro que hay una estructura lógica en el marcado generado. Tal JS localizado a menudo se puede ensamblar al comienzo y / o al final de dicha estructura.
¡Tenga en cuenta que nada de esto lo absuelve de escribir JavaScript eficiente! :-)
fuente
Lazy Carga el código que necesitas a pedido. Google hace algo así con su google.loader
fuente