Ce que j'ai appris en travaillant sur mon premier projet à grande échelle

Il y a huit mois, j'ai commencé à écrire une application sur Electron. Pour maîtriser cette tâche, j'ai dû développer trois sous-applications distinctes qui s'exécutent dans des environnements différents. Ci-dessous, je parlerai de ce que je me suis fait en cours de route.



Reliure dans sa forme originale

Le contexte


Avant d'entrer dans les détails, je commencerai par fournir quelques informations générales nécessaires pour comprendre la situation. Au début de 2019, j'ai commencé à rechercher un stage, comme l'exige le programme coopératif pour mon diplôme. En avril, j'ai envoyé des dizaines de curriculum vitae, dont chacun était adapté à un employeur spécifique, et au total, je n'ai reçu exactement aucune réponse. Vous pouvez imaginer comment j'ai réagi à cela - mes mains sont tombées, il semblait que je n'étais pas apte à quoi que ce soit et que je ne méritais aucun travail. Mais au lieu de laisser ces sentiments prévaloir, j'ai décidé de me prouver que je sais encore quelque chose et que je peux postuler pour certains postes. Au final, j'ai découvert qu'en fait j'en sais moins que ce à quoi je m'attendais.

J'ai commencé à réviser mes projets à la recherche de celui qui pourrait être transformé en quelque chose de vaste et complexe, ce qui pourrait me stimuler. Enfin, j'ai opté pour Binder - à l'époque une simple application web qui vous permettait de gérer des fichiers depuis Onedrive, Google Drive et Dropbox en même temps. L'objectif était de développer un service de sauvegarde comparable en fonctionnalités à cette trinité, sans la possibilité de transférer des fichiers vers d'autres utilisateurs.

Le début du chemin


Je n'aurais probablement pas du tout terminé le projet si je ne m'étais pas fixé des objectifs délirants dès le début. La première étape que j'ai déterminée pour moi-même a été la création d'une version alpha fonctionnelle pour mon anniversaire, que je célèbre à la mi-juillet. J'ai commencé à travailler immédiatement. Au début du mois de mai, j'ai créé un clone Binder et j'ai commencé à le démonter en parties, jetant de nombreuses fonctions dont je n'avais plus besoin. En général, j'ai pris une application complètement décente et l'ai transformée en un simple morceau de code quelque part au niveau du tutoriel.

J'ai décidé de rédiger quatre candidatures distinctes. Le premier est un client qui fonctionnera nativement sur l'ordinateur de l'utilisateur. La seconde est une API avec un backend, elle facilitera l'envoi de requêtes sécurisées. Troisièmement, le service cloud, qui est responsable de l'intégrité de toutes les données qui y sont stockées. Et enfin, une page Web «marketing», car un produit ne peut se passer d'un site Web chatoyant.

Et maintenant le plaisir commence


Eh bien, eh bien, j'avoue: tout ce que j'ai dit jusqu'à présent n'a rien à voir avec Electron, encore moins le développement d'applications à grande échelle. Mais j'avais besoin de clarifier le contexte pour que vous compreniez d'où j'ai tiré mes connaissances. Voici cinq leçons clés que j'ai apprises par moi-même:

n ° 1 Assurez-vous d'utiliser des structures traditionnelles pour le frontend et le backend, car la communication interprocessus est une chose stupide

Plus souvent que je ne le souhaiterais, j'ai paniqué à cause de la façon dont la communication interprocessus primitive est mise en œuvre dans Electron (et maintenant à nouveau dans le psycho). Oui, la communication interprocessus n'est généralement pas conçue pour effectuer l'abstraction de données dans l'esprit de Javascript, avec la représentation de fonctions en tant qu'objets et toutes sortes d'autres choses. Mais comme ce serait plus facile! Et donc, au lieu de créer une application client minimaliste, alors que le tableau principal de code serait situé dans le processus principal, j'ai été obligé de séparer clairement ce qui va interagir avec l'utilisateur et ce qui ne le sera pas. Le critère par lequel j'ai déterminé ce qui irait au processus principal, et quoi au processus de rendu, a été formulé comme une question simple: ce code sert-il quelque chose? La taille du fragment n'avait pas d'importance. S'il a servi d'autres morceaux de code,est ensuite passé au processus principal. La seule exception a été le point de terminaison du système de paiement Stripe - pour des raisons de sécurité, je voulais qu'il soit situé le plus près possible de l'utilisateur.

№2 Assurer l'intégrité des données est très, très difficile.

Jusqu'à ce que je commence à travailler sur Binder, je ne comprenais pas combien il était difficile de garantir que toutes les données provenant d'un nombre arbitraire et impressionnant d'utilisateurs restent toujours correctes et accessibles. Et juste pour leur fournir un stockage sûr n'est pas une tâche facile, mais maintenant vous voulez toujours que je valide tout et m'assure qu'il n'y a pas de contradiction avec d'autres données, sans aucune idée de ce que sont les données?!

Bien sûr, j'exagère un peu ici, mais l'essence du problème n'est pas déformée. La validation devrait avoir lieu le plus tôt possible aux premiers stades, puis être répétée (à une échelle plus modeste) à mesure que le flux de données progresse. Le maintien de la cohérence devient plus facile si vous utilisez un modèle transactionnel à chaque fois que vous modifiez les données. Pour vous dire la vérité, avec les données elles-mêmes, il y a aussi une masse de métadonnées, ce qui n'est pas beaucoup plus facile à gérer. Cela a toujours semblé une bonne idée d'écrire une fonction qui lit les données utilisateur et effectue ensuite des vérifications d'intégrité. Mais après de longues délibérations, je suis arrivé à la conclusion que les entrées secrètes ne sont pas différentes des portes d'entrée - toute la différence est de savoir qui les utilise.

Interfaces n ° 3 - comme des chaussures cousues sur commande



Une excellente façon de créer une belle interface qui fonctionne bien est de la regarder comme une paire de chaussures de couture individuelles (ou un costume adapté à la forme, peu importe). La première question que je me suis posée quand j'ai commencé la conception de Binder: qui va regarder l'interface de l'application? Remarque: je n'ai pas parlé de qui utilisera l'interface. Cela devrait être la deuxième question, car tout est lié précisément à l'apparence. Dans le passé, j'ai mené de nombreux projets et je peux vous le dire en toute confiance: les gens voulaient cracher sur votre application si elle ne se présente pas comme il se doit.



J'ai commencé par faire de petits brouillons dans un cahier (avec un stylo à bille, car j'ai l'habitude de constamment douter de mes idées). Dans les premières ébauches, l'accent était mis sur la structure générale de l'interface, et c'est seulement à ce moment-là, plus loin, que j'ai détaillé en détail à quoi devaient ressembler chacune des «pages». À mon avis, l'information présentée n'est pas aussi importante que sa lisibilité.

N ° 4 Il n'y a pas beaucoup de tolérance aux pannes

Je ne sais pas pour vous, mais moi de la pensée que l'API va planter après avoir accepté le paiement, une sueur froide s'infiltre. Commençant à travailler sur le système de paiement, je me suis dit: "Maintenant, vous ne pouvez pas vous permettre de manquer une seule erreur." J'ai veillé à mettre en place des mécanismes de sécurité tout au long du processus: à partir du moment où l'API reçoit une demande d'achat d'un package de services, et jusqu'à ce que Stripe transmette les informations de paiement au système de notification d'événements et que le package soit activé. Ce type de paranoïa ralentit bien sûr le processus de développement, mais je ne regrette rien. Mais j'ai toujours des informations complètes sur le moment où le paiement est arrivé, quel est son but et quel est le statut des actions qui devraient le suivre.

N ° 5 Pas parfait? Pas effrayant

Je suis un perfectionniste, et mes tentatives pour créer quelque chose d'étourdissant deviennent souvent incontrôlables et tournent à bout de souffle sans fin à chaque ligne de code et doute qu'elles aient le droit d'exister. Je dois endurer des batailles avec moi-même encore et encore sur ce qui est encore plus important - l'efficacité ou la lisibilité. Au cours des premiers mois, je n'avais pas encore reçu ma vue et je ne comprenais pas qu'une grande partie de ce sur quoi j'avais gaspillé mon énergie n'avait aucun avantage pratique - le but est de fabriquer un produit qui peut être utilisé avec un esprit calme et sans blesser pour un prix prestigieux. C'est drôle que ma cinquième leçon soit en partie contre la quatrième, mais c'est quand même bien. La quatrième leçon me rappelle la prudence et l'attention aux attentes des utilisateurs, et la cinquième définit des limites pour que je ne sois pas coincé,améliorer une fonction à l'infini.

Avant de dire au revoir


Vous avez lu mon article jusqu'au bout et vous avez peut-être remarqué (enfin ou non) que Binder n'est pas encore pleinement opérationnel. Au moment d'écrire ces lignes, je sortais juste la première version publique (beta 4). Je ne suis pas particulièrement enclin à faire de Binder un produit à part entière, mais je l'ai néanmoins développé pour qu'il fonctionne comme une application normale - tout d'un coup, des ambitions me succéderont. Une page Web irisée peut être admirée ici .

Tout ce que je pensais sûr pour un accès libre a été publié sur la page du projet sur GitHub. Là, je publierai des mises à jour (et là, vous pouvez télécharger le client pour qu'il se mette à jour). Ah, eh bien, voici les statistiques que j'ai compilées sur quatre sous-applications pour flatter ma vanité:

binder-local (client sur Electron)



binder-web (page web de joliesse)



Dans les deux autres, je n'ai pas commencé à compter automatiquement les lignes de code pour des raisons de sécurité.

liant api

  • JavaScript: 21 fichiers, 4117 lignes
  • Autres fichiers: ~ 150 lignes

binder-mongo (service de vérification d'intégrité)

  • JavaScript: 16 fichiers, 2374 lignes
  • Autres fichiers: ~ 140 lignes

Nombre total de lignes de code: 30 015

All Articles