El panel de inicio del usuario en nuestra aplicación, Alinear

Cómo creamos nuestra primera aplicación web JavaScript de pila completa en tres semanas

Una guía simple paso a paso para pasar de la idea a la aplicación implementada

Mis tres meses de programación de bootcamp en el Programa Grace Hopper han llegado a su fin, y el título de este artículo en realidad no es del todo cierto: ahora he creado tres aplicaciones de pila completa: una tienda de comercio electrónico desde cero, un personal proyecto de hackathon de mi elección, y finalmente, un proyecto final de tres semanas. Ese proyecto final fue, con mucho, el más intensivo, un viaje de tres semanas con dos compañeros de equipo, y es mi logro más orgulloso de bootcamp. Es la primera aplicación robusta y compleja que he construido y diseñado completamente.

Como la mayoría de los desarrolladores saben, incluso cuando "sabe codificar", puede ser realmente abrumador embarcarse en la creación de su primera aplicación full-stack. El ecosistema de JavaScript es increíblemente vasto: con administradores de paquetes, módulos, herramientas de construcción, transpiladores, bases de datos, bibliotecas y decisiones a tomar sobre todos ellos, no es de extrañar que tantos codificadores en ciernes nunca creen nada más allá de los tutoriales de Codecademy. Es por eso que quiero guiarlo a través de una guía paso a paso de las decisiones y pasos que mi equipo tomó para crear nuestra aplicación en vivo, Align.

Primero, un poco de contexto. Align es una aplicación web que utiliza una interfaz de línea de tiempo intuitiva para ayudar a los usuarios a establecer objetivos a largo plazo y administrarlos con el tiempo. Nuestra pila incluye Firebase para servicios de back-end y React en el front-end. Mis compañeros de equipo y yo explicamos más en este breve video:

Entonces, ¿cómo pasamos del Día 1, cuando nos asignaron nuestros equipos, a la aplicación final en vivo? Aquí hay un resumen de los pasos que tomamos:

Paso 1: Idear

El primer paso fue descubrir qué es exactamente lo que queríamos construir. En mi vida pasada como consultor en IBM, dirigí talleres de ideación con líderes corporativos. A partir de eso, le sugerí a mi grupo la clásica estrategia de lluvia de ideas post-it, en la que todos garabateamos tantas ideas como podamos, incluso 'estúpidas', para que los cerebros de las personas sigan moviéndose y nadie evite expresar sus ideas. temor.

Después de generar unas pocas docenas de ideas de aplicaciones, las clasificamos en categorías para comprender mejor qué temas nos entusiasmaron colectivamente. En nuestro grupo, vimos una clara tendencia hacia las ideas relacionadas con la superación personal, el establecimiento de objetivos, la nostalgia y el desarrollo personal. A partir de eso, eventualmente nos centramos en una idea específica: un tablero personal para establecer y administrar objetivos a largo plazo, con elementos de mantenimiento de la memoria y visualización de datos a lo largo del tiempo.

A partir de ahí, creamos un conjunto de historias de usuarios (descripciones de las características que queríamos tener, desde la perspectiva del usuario final) para dilucidar qué es exactamente lo que queríamos que hiciera nuestra aplicación.

Paso 2: Wireframe UX / UI

A continuación, en una pizarra blanca, dibujamos las vistas básicas que imaginamos en nuestra aplicación. Incorporamos nuestro conjunto de historias de usuarios para comprender cómo funcionarían estas vistas en un marco esquemático de aplicaciones.

Estos bocetos aseguraron que todos estuviéramos en la misma página, y proporcionaron un plan visual en el futuro de lo que estábamos trabajando exactamente.

Paso 3: elija una estructura de datos y un tipo de base de datos

Había llegado el momento de diseñar nuestra estructura de datos. Con base en nuestros wireframes e historias de usuarios, creamos una lista en un documento de Google de los modelos que necesitaríamos y qué atributos debería incluir cada uno. Sabíamos que necesitábamos un modelo de "objetivo", un modelo de "usuario", un modelo de "hito" y un modelo de "registro", así como eventualmente un modelo de "recurso" y un modelo de "carga".

Nuestro bosquejo inicial de nuestros modelos de datos.

Después de esbozar informalmente los modelos, necesitábamos elegir un tipo de base de datos: "relacional" versus "no relacional" (también conocido como "SQL" versus "NoSQL"). Mientras que las bases de datos SQL están basadas en tablas y necesitan un esquema predefinido, las bases de datos NoSQL están basadas en documentos y tienen un esquema dinámico para datos no estructurados.

Para nuestro caso de uso, no importaba mucho si usábamos una base de datos SQL o No-SQL, por lo que finalmente elegimos la base de datos de la base de datos NoSQL en la nube de Google por otras razones:

  1. Podría contener cargas de imágenes de usuario en su almacenamiento en la nube
  2. Incluía la integración de WebSocket para la actualización en tiempo real
  3. Podría manejar nuestra autenticación de usuario y ofrecer una fácil integración con OAuth

Una vez que elegimos una base de datos, llegó el momento de comprender las relaciones entre nuestros modelos de datos. Como Firebase es NoSQL, no pudimos crear tablas de unión ni establecer relaciones formales como "Los registros pertenecen a los objetivos". En cambio, teníamos que averiguar cómo se vería el árbol JSON y cómo se anidarían (o no) los objetos. Finalmente, estructuramos nuestro modelo así:

Nuestro esquema de datos final de Firebase para el objeto Goal. Tenga en cuenta que los hitos y los registros están anidados en Objetivos.

(Nota: Firebase prefiere estructuras de datos poco profundas y normalizadas para la eficiencia, pero para nuestro caso de uso, tenía más sentido anidarlo, ya que nunca estaríamos sacando un Objetivo de la base de datos sin sus Hitos e Informes secundarios).

Paso 4: configura Github y un flujo de trabajo ágil

Sabíamos desde el principio que mantenernos organizados y practicar un desarrollo ágil nos serviría mucho. Establecimos un repositorio de Github, en el que evitamos la fusión de master para obligarnos a revisar el código del otro.

También creamos un tablero ágil en Waffle.io, que es gratuito y se integra fácilmente con Github. En el tablero de Waffle, enumeramos nuestras historias de usuarios, así como los errores que sabíamos que necesitábamos corregir. Más tarde, cuando comenzamos a codificar, cada uno crearía ramas git para la historia del usuario en la que estábamos trabajando actualmente, moviéndola de la línea de natación a la de la misma a medida que avanzamos.

También comenzamos a celebrar reuniones "de pie" cada mañana para discutir el progreso del día anterior y los bloqueadores que cada uno de nosotros estaba encontrando. Esta reunión a menudo decidía el flujo del día: quién sería la programación en pareja y quién trabajaría en un tema en solitario.

Recomiendo encarecidamente algún tipo de flujo de trabajo estructurado como este, ya que nos permitió definir claramente nuestras prioridades y avanzar de manera eficiente sin ningún conflicto interpersonal.

Paso 5: Elija y descargue un repetitivo

Debido a que el ecosistema de JavaScript es tan complicado, optamos por no construir nuestra aplicación desde cero. Se sintió innecesario pasar un tiempo valioso conectando nuestros scripts y cargadores de compilación de Webpack, y nuestro enlace simbólico que apuntaba a nuestro directorio de proyectos. Mi equipo eligió el esqueleto Firebones porque se ajusta a nuestro caso de uso, pero hay muchas opciones de esqueleto de código abierto disponibles para elegir.

Paso 6: escribir rutas API de back-end (o escuchas de Firebase)

Si no estuviéramos utilizando una base de datos basada en la nube, este habría sido el momento de comenzar a escribir nuestras rutas Express de back-end para realizar solicitudes a nuestra base de datos. Pero como estábamos usando Firebase, que ya está en la nube y tiene una forma diferente de comunicarse con el código, trabajamos para configurar nuestro primer oyente de base de datos exitoso.

Para asegurarnos de que nuestro oyente estaba trabajando, codificamos un formulario de usuario básico para crear un Objetivo, y vimos que, de hecho, cuando llenamos el formulario, nuestra base de datos se estaba actualizando en vivo. Estábamos conectados!

Paso 7: Cree una "Prueba de concepto"

Nuestro siguiente paso fue crear una "prueba de concepto" para nuestra aplicación, o un prototipo de las características fundamentales más difíciles de implementar, demostrando que nuestra aplicación podría existir. Para nosotros, esto significaba encontrar una biblioteca front-end para procesar satisfactoriamente las líneas de tiempo y conectarla a Firebase con éxito para mostrar algunos datos semilla en nuestra base de datos.

Basic Victory.JS cronogramas

Encontramos Victory.JS, una biblioteca React construida en D3, y pasamos un día leyendo la documentación y reuniendo un ejemplo muy básico de un componente VictoryLine y un componente VictoryScatter para mostrar visualmente los datos de la base de datos. De hecho, funcionó! Estábamos listos para construir.

Paso 8: codifique las funciones

Finalmente, llegó el momento de desarrollar toda la funcionalidad emocionante de nuestra aplicación. Este es un paso gigante que obviamente variará ampliamente dependiendo de la aplicación que esté creando personalmente. Observamos nuestros wireframes y comenzamos a codificar las historias de usuarios individuales en nuestro Waffle. Esto a menudo incluía tocar tanto el código front-end como el back-end (por ejemplo, crear un formulario front-end y también conectarlo a la base de datos). Nuestras características iban de mayor a menor e incluían cosas como:

  • capacidad de crear nuevas metas, hitos y registros
  • capacidad de eliminar objetivos, hitos y registros
  • capacidad de cambiar el nombre, el color y los detalles de una línea de tiempo
  • capacidad de ampliar las líneas de tiempo
  • capacidad de agregar enlaces a recursos
  • capacidad de subir medios
  • capacidad de burbujear recursos y medios desde hitos y registros hasta sus objetivos asociados
  • integración de editor de texto enriquecido
  • registro de usuario / autenticación / OAuth
  • popover para ver las opciones de la línea de tiempo
  • pantallas de carga

Por razones obvias, este paso tomó la mayor parte de nuestro tiempo: esta fase es donde sucedió la mayor parte del código carnoso, y cada vez que terminamos una función, ¡siempre había más para construir!

Paso 9: elija y codifique el esquema de diseño

Una vez que tuvimos un MVP de la funcionalidad que deseábamos en nuestra aplicación, llegó el momento de limpiarla y hacerla bonita. Mi equipo usó Material-UI para componentes como campos de formulario, menús y pestañas de inicio de sesión, lo que garantizó que todo se viera elegante, pulido y coherente sin un conocimiento profundo del diseño.

Esta fue una de mis características favoritas para codificar. ¡Su belleza es tan satisfactoria!

Pasamos un tiempo eligiendo un esquema de color y editando el CSS, lo que nos proporcionó un buen descanso de la codificación en las trincheras. También diseñamos un logotipo y subimos un favicon.

Paso 10: Encuentra y elimina errores

Si bien deberíamos haber estado utilizando el desarrollo basado en pruebas desde el principio, las limitaciones de tiempo nos dejaron con muy poco tiempo para nada más que funciones. Esto significó que pasamos los últimos dos días simulando cada flujo de usuarios que pudimos pensar y buscando errores en nuestra aplicación.

Este proceso no fue el más sistemático, pero encontramos muchos errores para mantenernos ocupados, incluido un error en el que la pantalla de carga duraría indefinidamente en ciertas situaciones, y uno en el que el componente de recursos había dejado de funcionar por completo. Arreglar errores puede ser molesto, pero cuando finalmente funciona, es extremadamente satisfactorio.

Paso 11: Implemente la aplicación en vivo

El último paso fue implementar nuestra aplicación para que esté disponible en vivo. Debido a que estábamos usando Firebase para almacenar nuestros datos, lo implementamos en Firebase Hosting, que era intuitivo y simple. Si su back-end usa una base de datos diferente, puede usar Heroku o DigitalOcean. En general, las instrucciones de implementación están disponibles en el sitio de alojamiento.

También compramos un nombre de dominio barato en Namecheap.com para hacer que nuestra aplicación sea más pulida y fácil de encontrar.

Y eso fue todo: ¡de repente fuimos los cocreadores de una aplicación real de pila completa que alguien podría usar! Si tuviéramos una pista más larga, el Paso 12 habría sido ejecutar pruebas A / B en los usuarios, para que pudiéramos entender mejor cómo los usuarios reales interactúan con nuestra aplicación y qué les gustaría ver en un V2.

Por ahora, sin embargo, estamos contentos con el producto final y con el inmenso conocimiento y comprensión que obtuvimos a lo largo de este proceso. ¡Mira Align aquí!

Team Align: Sara Kladky (izquierda), Melanie Mohn (centro) y yo.

- -
Si disfrutaste esta pieza, me encantaría que golpearas el corazón verde para que otros puedan tropezar con ella. Siéntase libre de consultar el código fuente de Align y sígame en Github, así como a los miembros de mi equipo, Sara Kladky y Melanie Mohn.