En este artículo, compartiré cómo puedes evitar algunos de los errores que cometí al aprender sobre Electron.js? ♂️. ¡Espero que ayude!
Nota : Este no será un tutorial de codificación, sino más bien una discusión sobre mis conclusiones personales.
Hace un par de meses, decidí concentrarme más en construir mi producto secundario, taggr . Me inspiré para construirlo por la cantidad de fotos que tengo en mi computadora.
Para aquellos de nosotros que mantenemos una copia de seguridad de sus imágenes, esas colecciones a menudo se vuelven tan grandes y complejas que se convierten en un trabajo de tiempo completo para administrar. Una combinación de carpetas y subcarpetas puede contener copias de seguridad de imágenes de mensajería instantánea, imágenes de alta resolución de su viaje a Bali, la boda de su tío o la despedida de soltero del año pasado.
Mantener siempre ordenadas estas colecciones es tedioso (créanme, lo he intentado durante años). Tambien es dificilpara descubrir las fotos que más le gustan, escondidas en el fondo de las carpetas.
Tan taggres una aplicación de escritorio que resuelve ese problema. Permite a los usuarios redescubrir sus recuerdos manteniendo su privacidad .
Estoy construyendo taggr como una aplicación de escritorio multiplataforma. Aquí compartiré algunas de las cosas que he aprendido sobre el desarrollo de aplicaciones multiplataforma con Electron.js que desearía saber desde el principio. ¡Empecemos!
Antecedentes
Antes de presentar mis conclusiones sobre este viaje en curso con Electron, me gustaría dar un poco más de información sobre mí y los requisitos de taggr .
Cada desarrollador proviene de una experiencia diferente, al igual que los requisitos de las aplicaciones que desarrollan.
Contextualizar las elecciones que tomé para este proyecto puede ayudar a los futuros desarrolladores a seleccionar las herramientas adecuadas en función de sus necesidades y experiencia (en lugar de lo que se promociona, ¿GitHub ?, te estoy mirando).

Como se mencionó anteriormente, desde el principio imaginé taggr como una aplicación multiplataforma. La aplicación realizaría todos los cálculos necesarios de preprocesamiento y aprendizaje automático en el lado del cliente debido al enfoque en la privacidad.
Como programa para una sola persona, quería poder escribir mi aplicación una vez y enviarla a diferentes sistemas sin perder la cordura.
Por mi parte, soy un ingeniero front-end enamorado de la web y JavaScript. Anteriormente trabajé con Java y C #, pero disfruto de la flexibilidad que ofrece la web y su ecosistema vibrante.
Habiendo experimentado de primera mano el dolor de usar herramientas como Eclipse RCP para crear aplicaciones del lado del cliente antes, sabía que no quería volver a trabajar con esa tecnología.
En resumen, mis requisitos de pila para taggr se redujeron a algo como lo siguiente:
- Debe proporcionar soporte multiplataforma, idealmente a nivel de marco. ?
- Debería permitirme escribir el código una vez y modificarlo para cada plataforma si es necesario. ? ️
- Debería permitir el acceso a las capacidades de aprendizaje automático , independientemente del entorno del host, sin que se instalen tiempos de ejecución específicos. Debe ser sencillo de configurar. ?
- Si es posible, debería utilizar tecnologías web . Sería genial aprovechar mis conocimientos actuales. ?
Como puede ver, los requisitos no se leen como: Debería usar React con Redux, observables y WebSockets . Estos son detalles de implementación de nivel inferior, y deben decidirse cuando y si surge la necesidad.
Elija la herramienta adecuada para el trabajo en lugar de elegir una pila desde el principio, sin tener en cuenta los problemas en cuestión.
Entonces, después de buscar en Google, decidí darle una oportunidad a Electron. No había usado ese marco antes, pero sabía que muchas empresas lo estaban usando con éxito en productos como Atom, VS Code, Discord, Signal, Slack y más.
De código abierto y con compatibilidad inmediata con los ecosistemas JS y Node (Electron se construye usando Chromium y Node), Electron.js era una herramienta atractiva para el trabajo en cuestión.
No entraré en demasiados detalles con respecto al resto de la pila, ya que cambié repetidamente las partes principales (persistencia y capas de vista) cuando fue necesario, y queda fuera del alcance de este artículo.
Sin embargo, me gustaría mencionar Tensorflow.js, que permite ejecutar el entrenamiento e implementar modelos de ML directamente en el navegador (con WebGL) y Node (con enlaces C), sin instalar tiempos de ejecución específicos para ML en el host.
Así que volviendo a Electron, pensando que era perfecto, comenzó la diversión. ??
Ya basta de hablar de los antecedentes. Vamos a sumergirnos en las conclusiones.
1. ¿Empezar con algo pequeño (y lento)?
Este no es un concepto nuevo, pero vale la pena mencionarlo periódicamente. El hecho de que haya un montón de proyectos iniciales increíbles con Electron disponibles no significa que deba elegir uno de inmediato.
Espere. ¿Qué?
Lento es suave y suave es rápido. - Dicho de la MarinaCon la conveniencia viene la complejidad
Si bien esos principiantes incluyen muchas integraciones útiles (Webpack, Babel, Vue, React, Angular, Express, Jest, Redux), también tienen sus problemas.
Como novato de Electron, decidí optar por una plantilla ajustada que incluyera los conceptos básicos para 'crear, publicar e instalar aplicaciones de Electron' sin las campanas y silbidos adicionales. Ni siquiera Webpack al principio.
Recomiendo comenzar con algo similar a la forja de electrones para comenzar a funcionar rápidamente.Configure su gráfico de dependencia y estructura en la parte superior para aprender los entresijos de Electron.
Cuando surjan los problemas (y lo harán), estará mejor si crea su proyecto de inicio personalizado en lugar de elegir uno con scripts de +30 npm y dependencias de +180 para empezar.
Dicho esto, una vez que se sienta cómodo con la base de Electron, siéntase libre de intensificar el juego con Webpack / React / Redux / TheNextHotFramework. Lo hice de forma incremental y cuando fue necesario. No agregue una base de datos en tiempo real a su aplicación de tareas pendientes solo porque haya leído un artículo interesante al respecto en alguna parte.
2. ¿Estructura tu aplicación de forma consciente? ♂️
Este tardó un poco más en hacerlo bien de lo que estoy feliz de admitir. ?
Al principio, puede ser tentador mezclar la interfaz de usuario y el código backend (acceso a archivos, operaciones extendidas de la CPU), pero las cosas se vuelven complejas bastante rápido. A medida que mi aplicación crecía en características, tamaño y complejidad, mantener una interfaz de usuario enredada + base de código backend se volvió más complicado y propenso a errores. Además, el acoplamiento dificultaba probar cada parte de forma aislada.
Al crear una aplicación de escritorio que hace más que una página web integrada (acceso a la base de datos, acceso a archivos, tareas intensivas de la CPU…), recomiendo dividir la aplicación en módulos y reducir el acoplamiento. Las pruebas unitarias se vuelven muy sencillas y hay un camino claro hacia las pruebas de integración entre los módulos. Para taggr , seguí vagamente la estructura propuesta aquí.
Además de eso, está el rendimiento . Los requisitos y las expectativas de los usuarios sobre este tema pueden variar enormemente según la aplicación que esté creando. Pero bloquear los hilos principales o de procesamiento con llamadas costosas nunca es una buena idea.
3. ¿Diseñar teniendo en cuenta el modelo de roscado?
No entraré demasiado en detalles aquí, solo estoy doblando principalmente lo que se explica asombrosamente en los documentos oficiales.
En el caso específico de taggr , hay muchas operaciones intensivas de CPU, GPU e IO de larga duración. Al ejecutar esas operaciones en el hilo principal o del renderizador de Electron, el recuento de FPS desciende de 60, lo que hace que la interfaz de usuario se sienta lenta.
Electron ofrece varias alternativas para descargar esas operaciones de los subprocesos principal y del renderizador , como WebWorkers, Node Worker Threads o instancias de BrowserWindow. Cada uno tiene sus ventajas y advertencias, y el caso de uso al que se enfrente determinará cuál es el más adecuado.
Independientemente de la alternativa que elija para descargar las operaciones de los subprocesos principal y del renderizador (cuando sea necesario), considere cómo será la interfaz de comunicación . Me tomó un tiempo encontrar una interfaz con la que estaba satisfecho, ya que tiene un gran impacto en cómo está estructurada y funciona su aplicación. Encontré útil experimentar con diferentes enfoques antes de elegir uno.
Por ejemplo, si cree que la interfaz de paso de mensajes de WebWorkers puede no ser la más fácil de depurar, pruebe comlink.

4. Prueba ❌, prueba ❌ y prueba ✔️
Viejas noticias, ¿verdad? Quería agregar esto como último punto, debido a un par de 'problemas' anecdóticos que enfrenté recientemente. Fuertemente vinculado al primer y segundo punto, construir su proyecto inicial personalizado y cometer errores desde el principio le ahorrará un valioso tiempo de depuración en el desarrollo.
Si siguió mis recomendaciones para dividir la interfaz de usuario y el backend de la aplicación en módulos con una interfaz limpia entre los dos, configurar pruebas automatizadas de unidad e integración debería ser fácil. A medida que la aplicación madura, es posible que también desee agregar soporte para las pruebas de e2e.
¿Extracción de ubicación GPS? ️
Hace dos días, mientras implementaba la función de extracción de ubicación GPS para taggr , una vez que las pruebas unitarias estaban en verde y la función funcionaba en desarrollo (con Webpack), decidí probarla en el entorno de producción.
Si bien la función funcionó bien en el desarrollo, falló estrepitosamente en la producción. La información EXIF de las imágenes se leyó como binaria y fue procesada por una biblioteca de terceros. Si bien la información binaria se cargó correctamente en ambos entornos (verificada con diff), la biblioteca de terceros falló al analizar dichos datos en la compilación de producción. Disculpe, ??
Solución : descubrí que la configuración de codificación en los entornos de desarrollo y producción establecidos por Webpack no era la misma. Esto provocó que los datos binarios se analizaran como UTF-8 en desarrollo pero no en producción. El problema se solucionó configurando los encabezados de codificación adecuados en los archivos HTML cargados por Electron.
¿Fotos funky?
Al manipular y trabajar con imágenes, puede pensar que si un JPEG "simplemente funciona" en su computadora, es un JPEG válido. Equivocado .
Mientras trabajaba con la biblioteca de procesamiento de imágenes de Node nítida , el cambio de tamaño de algunas imágenes JPEG bloqueó la aplicación. Después de mirar de cerca, la causa fueron imágenes JPEG incorrectas generadas por el firmware de Samsung. ? ♂️
Solución : configurar límites de error mejorados en la aplicación (por ejemplo, bloques try-catch), modificar el módulo de análisis de JPEG y sospechar de todo. ? ️
Resumen
Los ecosistemas de Node y JavaScripts están floreciendo, con muchas herramientas poderosas que se crean y comparten todos los días.
La cantidad de opciones hace que sea difícil elegir un camino claro para comenzar a construir su nueva y asombrosa aplicación Electron. Independientemente de los marcos que elija, le recomendaría centrarse en lo siguiente:
- Empiece poco a poco y agregue complejidad de forma incremental.
- Estructure su aplicación con atención , manteniendo modularizados los problemas de backend y UI.
- Diseñe teniendo en cuenta el modelo de subprocesos , incluso al crear aplicaciones pequeñas.
- Pruebe y vuelva a probar para detectar la mayoría de los errores desde el principio y evitar dolores de cabeza.
¡Gracias por quedarte hasta el final! ?
taggr es una aplicación de escritorio multiplataforma que permite a los usuarios redescubrir sus recuerdos digitales manteniendo su privacidad . Open-alpha llegará pronto a Linux, Windows y Mac OS. Así que esté atento a Twitter e Instagram, donde publico actualizaciones de desarrollo, próximas funciones y noticias.