Lo que aprendí mientras trabajaba en mi primer proyecto a gran escala

Hace ocho meses, comencé a escribir una aplicación en Electron. Para dominar esta tarea, tuve que desarrollar tres sub-aplicaciones separadas que se ejecutan en diferentes entornos. A continuación hablaré sobre lo que hice para mí en el camino.



Carpeta en su forma original

Contexto


Antes de profundizar en los detalles, comenzaré brindando información general necesaria para comprender la situación. A principios de 2019, comencé a buscar una pasantía, como lo requiere el programa cooperativo para mi título. En abril, envié docenas de currículums, cada uno de los cuales estaba diseñado para un empleador específico, y en total recibí exactamente cero respuestas. Puedes imaginar cómo reaccioné a esto: mis manos cayeron, parecía que no era apto para nada y que no valía la pena trabajar en absoluto. Pero en lugar de dejar que estos sentimientos prevalezcan, decidí probarme a mí mismo que todavía sé algo y que puedo solicitar algunas publicaciones. Al final, descubrí que, de hecho, sé menos de lo que esperaba.

Comencé a revisar mis proyectos en busca de uno que pudiera convertirse en algo a gran escala y complejo, que pudiera estimularme. Finalmente, opté por Binder, en ese momento una aplicación web simple que le permitía administrar archivos de Onedrive, Google Drive y Dropbox al mismo tiempo. El objetivo era desarrollar un servicio de respaldo comparable en funcionalidad a esta trinidad, menos la capacidad de transferir archivos a otros usuarios.

El comienzo del camino


Probablemente, no habría completado el proyecto si no me hubiera fijado algunas metas delirantes desde el principio. El primer hito que determiné por mí mismo fue la creación de una versión alfa en funcionamiento para mi cumpleaños, que celebro a mediados de julio. Empecé a trabajar de inmediato. A principios de mayo, creé un clon de Binder y comencé a desarmarlo en partes, eliminando muchas funciones que ya no necesitaba. En general, tomé una aplicación completamente decente y la convertí en un código simple en algún lugar del nivel tutorial.

Me decidí por el hecho de que escribiré cuatro solicitudes separadas. El primero es un cliente que funcionará de forma nativa en la computadora del usuario. El segundo es una API con un backend, facilitará el envío de solicitudes seguras. En tercer lugar, el servicio en la nube, que es responsable de la integridad de todos los datos almacenados en él. Y finalmente, una página web de "marketing", porque un producto no puede funcionar sin un sitio web brillante.

Y ahora comienza la diversión.


Bueno, bueno, bueno, lo admito: todo lo que he dicho hasta ahora no tiene nada que ver con Electron, mucho menos el desarrollo de aplicaciones a gran escala. Pero necesitaba aclarar el contexto para que entiendas de dónde obtuve mi conocimiento. Aquí hay cinco lecciones clave que aprendí por mí mismo:

# 1 Asegúrese de usar estructuras tradicionales para el frontend y el backend, porque la comunicación entre procesos es una estupidez.

Más a menudo de lo que me gustaría, me asusté por la forma en que se implementa la comunicación entre procesos primitiva en Electron (y ahora nuevamente en psicópata). Sí, la comunicación entre procesos no está diseñada para llevar a cabo la abstracción de datos en el espíritu de Javascript, con la representación de funciones como objetos, etc. ¡Pero cuánto más fácil sería! Y así, en lugar de crear una aplicación cliente minimalista, mientras que la matriz principal de código se ubicaría en el proceso principal, me vi obligado a separar claramente qué interactuará con el usuario y qué no. El criterio por el cual determiné qué iría al proceso principal, y qué al proceso de renderizado, se formuló como una simple pregunta: ¿este código sirve para algo? El tamaño del fragmento no importaba. Si sirvió otras piezas de código,luego fue al proceso principal. La única excepción fue el punto final del sistema de pago Stripe: por razones de seguridad, quería que se ubicara lo más cerca posible del usuario.

No. 2 Hacer que los datos mantengan la integridad es muy, muy difícil.

Hasta que comencé a trabajar en Binder, no entendía lo difícil que era conseguir que todos los datos provenientes de un número arbitrario e impresionante de usuarios permanecieran siempre correctos y accesibles. ¡Y simplemente proporcionarles un almacenamiento seguro no es una tarea fácil, pero ahora todavía quieren que valide todo esto y me asegure de que no haya contradicciones con otros datos, sin tener idea de cuáles son los datos?!

Por supuesto, exagero un poco aquí, pero la esencia del problema no está distorsionada. La validación debe ocurrir lo antes posible en las primeras etapas y luego repetirse (en una escala más modesta) a medida que avanza el flujo de datos. Mantener la coherencia se vuelve más fácil si usa un modelo transaccional cada vez que cambia los datos. A decir verdad, junto con los datos en sí, también hay una gran cantidad de metadatos, que no es mucho más fácil de administrar. Siempre me pareció una gran idea escribir una función que lea los datos del usuario y luego realice verificaciones de integridad. Pero después de mucha deliberación, llegué a la conclusión de que las entradas secretas no son diferentes de las puertas de entrada: la diferencia es quién las usa.

No. 3 Interfaces - como zapatos cosidos por encargo



Una excelente manera de hacer una interfaz hermosa y que funcione bien es mirarla como un par de zapatos de sastrería individuales (o un traje adaptado a la forma, no importa). La primera pregunta que me hice cuando comencé a diseñar para Binder: ¿quién mirará la interfaz de la aplicación? Nota: No hablé sobre quién usará la interfaz. Esta debería ser la segunda pregunta, porque todo está ligado precisamente a la apariencia. En el pasado, realicé muchos proyectos y puedo decirle con total confianza: la gente quería escupir en su aplicación si no se ve como debería.



Comencé haciendo pequeños borradores en un cuaderno (con un bolígrafo, porque tengo la costumbre de dudar constantemente de mis ideas). En los primeros borradores, el énfasis estaba en la estructura general de la interfaz, y solo entonces, dibujando más, detallé en detalle cómo debería verse cada una de las "páginas". En mi opinión, la información presentada no es tan importante como su legibilidad.

No. 4 No hay mucha tolerancia a fallas

No sé sobre usted, pero por la idea de que la API se bloqueará después de aceptar el pago, se abre paso un sudor frío. Comenzando a trabajar en el sistema de pago, me dije a mí mismo: "Ahora no puede permitirse perder un solo error". Me aseguré de implementar mecanismos de seguridad durante todo el proceso: desde el momento en que la API recibe una solicitud para comprar un paquete de servicio, y hasta que Stripe pasa la información de pago al sistema de notificación de eventos y el paquete se activa. Este tipo de paranoia, por supuesto, ralentiza el proceso de desarrollo, pero no me arrepiento de nada. Pero siempre tengo información completa sobre cuándo llegó el pago, cuál es su propósito y cuál es el estado de las acciones que deberían seguir.

No. 5 ¿No es perfecto? No da miedo

Soy un perfeccionista, y mis intentos de crear algo sorprendente a menudo se salgan de control y se vuelven interminables a cada línea de código y dudo si tienen derecho a existir. Tengo que soportar batallas conmigo mismo una y otra vez sobre lo que es aún más importante: eficiencia o legibilidad. En los primeros meses, aún no había recibido mi vista y no entendía que gran parte de lo que desperdiciaba mi energía no tenía ningún beneficio práctico: el punto es hacer un producto que pueda usarse con una mente tranquila y no lastimar por algún prestigioso premio. Es curioso que mi quinta lección vaya en parte contra la cuarta, pero incluso es buena. La cuarta lección me recuerda la precaución y la atención a las expectativas del usuario, y la quinta establece límites para que no me quede atascado,mejorando una función sin fin.

Antes de decir adios


Leyó mi artículo hasta el final y es posible que haya notado (bueno o no) que Binder aún no está completamente operativo. Al momento de escribir, estaba lanzando la primera versión pública (beta 4). No estoy particularmente inclinado a convertir Binder en un producto completo, pero lo desarrollé para que funcione como una aplicación normal; de repente, las ambiciones se harán cargo de mí. Aquí se puede admirar una página web iridiscente .

Todo lo que pensé que era seguro para el acceso abierto se publicó en la página del proyecto en GitHub. Allí publicaré actualizaciones (y allí puedes descargar el cliente para que se actualice solo). Ah, bueno, aquí están las estadísticas que compilé en cuatro sub-aplicaciones para halagar mi vanidad:

binder-local (cliente en Electron)



binder-web (página web de belleza)



En los dos restantes, no comencé a contar líneas de código automáticamente por razones de seguridad.

api de la carpeta

  • JavaScript: 21 archivos, 4117 líneas
  • Otros archivos: ~ 150 líneas

binder-mongo (servicio para verificar la integridad)

  • JavaScript: 16 archivos, 2374 líneas
  • Otros archivos: ~ 140 líneas

Número total de líneas de código: 30,015

All Articles