¿Cómo organizar mi código en JavaScript?

Josepanaero

Llevo en el mundo del desarrollo web varios años ya, y mi fuerte es PHP. Cuando escribo código en PHP me resulta muy fácil organizarlo. Suelo crear bastantes clases, cada una con una única responsabilidad, y todas las clases se agrupan a su vez en sus respectivos namespaces. Creo interfaces cuando son necesarias, uso TypeHint en los argumentos cuando es conveniente, creo tests siguiendo la metodología TDD y, en general, intento siempre escribir un código que resulte fácil de leer para otros programadores.

Sin embargo, cuando intento hacer lo mismo en JavaScript, me resulta imposible. No digo que sea imposible, ya que JavaScript es un lenguaje con el que tengo poca experiencia, pero a día de hoy no he encontrado la forma de hacer que el poco JavaScript que escribo esté tan bien organizado como su contrapartida en PHP. A lo máximo a lo que llego es a crear varios archivos .js en los que conviven muchas funciones que tienen cierta relación entre sí, pero suelen acabar siendo archivos bastante grandes y desordenados. Además, leer JavaScript escrito por otra gente tampoco me ayuda, ya que he tenido bastantes compañeros de trabajo que escribían en JS a diario, y todos ellos sin excepción escriben del mismo modo: desorganizado, sin ningún tipo de tests, con archivos .js de varios cientos y hasta miles de líneas, en los que se mezcla de todo: clases que no tienen demasiada relación entre sí, otras funciones que mezclan la capa de presentación y la de negocio, etc.

Por supuesto, a lo largo de estos años también he visto muchísimo código PHP que es basura, código espagueti. Sin embargo en los últimos años el ecosistema de PHP ha dado un giro a mejor, y hoy por hoy es fácil escribir un código legible y bien organizado en PHP. Por ello, me gustaría preguntar a los expertos en JavaScript del foro: ¿cómo hacéis vosotros para organizar bien vuestro código en JavaScript? Me refiero a JavaScript pelado y mondado, sin utilizar frameworks. En el trabajo hace unos meses utilicé AngularJS y ciertamente ayuda en la organización del código, y estoy seguro de que otros frameworks también desempeñan una buena labor en este aspecto. También usamos Jasmine para testear nuestro código.

Sin embargo, ¿cómo se organiza el código sin usar frameworks? ¿Existen los namespaces en JavaScript (o un concepto similar)? ¿Existe alguna forma de crear archivos .js pequeños los cuales solamente contengan una única clase con una única responsabilidad, distribuyéndolos a su vez en directorios que formen el espacio de nombres, tal y como se hace en otros lenguajes como Java o PHP? Y en caso de ser así, ¿cómo se referencian los unos a los otros? ¿Y cómo se incluirían tantísimos archivos en una página web? ¿Habría que usar algún tipo de procesador que los combinase en un único archivo .js?

Como veis, tengo muchísimas dudas debido a mi inexperiencia en JavaScript, así que cualquier consejo, recomendación de libro o página web, será bienvenido.

¡Salu2!

DarkSoldier

#1 no voy a poder ayudarte mucho porque no he usado o no suelo usar JS a pelo sin frameworks, pero alomejor una ayuda es leerte una guia de estilo (airbnb guide style) y ver como organizar tu código, luego a nivel de carpetas pues algo modular, del palo: common, header, profile, timeline, etc etc

PD: estaré pendiente al post que interesa

zoeshadow

Yo estoy trabajando en un proyecto JS relativamente grande, y lo primero que hice fue meter Grunt para gestionar las distintas tareas "de build". Es decir que automáticamente se pasen los test, se pase el JSHint y se concatenen todos estos ficheros en un fichero final que es el que está añadido en el HTML. Esto parece que no, pero ayuda bastante de cara a la mantenibilidad del proyecto, crear nuevos ficheros no cuesta nada, de manera que al gente se anima a crearlos en vez de reusar otros ficheros que no tengan mucho que ver.

De cara a la organización del propio código, con Javascript puedes hacer OOP, pero es más difícil, sobre todo para gente que viene de Java o C#, ya que los prototypes no ayudan mucho...

Al final la gente lo que acaba haciendo es objetos JSON que contienen funciones, los cuales los usan a modo de Namespaces, estas funciones son estáticas y trabajan sobre distintas estructuras de datos.

A la hora de testear puedes hacer monkeypatching para sustituir todas las funciones que utilices en la función a testear de manera que puedas probarla aisladamente. ( esto en OOP se resuelve haciendo inversión de dependencias y usando un contenedor de dependencias cómo Spring en Java o Symfony en PHP )

A mi lo que me funciona sobre todo es minimizar el estado global, intentar que las funciones solo trabajen con valores que reciben como parámetro y no fijar mágicamente cosas al scope global, por qué entonces se vuelve inmanejable.

Por último comentar que existe Typescript, el cual es un superset de Javascript que añade tipado opcional, lo cual en proyectos medianos/grandes es un WIN, y no añade casi overhead..

MTX_Anubis

hombre yo creo que requirejs es indispensable

B

A pelo lo único tener una estructura de archivos y utilizar algún patrón de diseño como el modular ( http://www.adequatelygood.com/JavaScript-Module-Pattern-In-Depth.html ). Con javascript es muy my fácil escribir código horrible incluso más fácil que con PHP y es otras de las razones por la que me pasé a golang.

S

Javascript es un lenguaje que te permite hacer todo, por eso mismo tienes que usar las herramientas adecuadas si quieres tener un código que se pueda mantener.
Lo primero que necesitas es un AMD loader o parecido:
http://requirejs.org/
http://addyosmani.com/writing-modular-js/
Browserfy parece que esta de moda:
http://browserify.org/

Para los tests hay muchísimas librerías, dos muy populares son estas:
http://jasmine.github.io/
https://mochajs.org/

Luego te hace falta un task manager(unir, minificar, ejecutar tests, lintear), antiguamente se usaba mucho grunt pero parece que se ha quedado anticuado con respecto a gulp:
http://gruntjs.com/
http://gulpjs.com/

Y esto sin usar ningún framework, diría que es lo mínimo indispensable.

2

Usuarios habituales