J'ai récemment consacré quelques heures à JavaScript parce que je voulais profiter de la base d'utilisateurs massive. Ce faisant, j'ai remarqué un modèle que la plupart des gens attribuent aux langages dynamiques. Les choses fonctionnent très rapidement, mais une fois que votre code atteint une certaine taille, vous perdez beaucoup de temps avec les erreurs de type, d'orthographe et de refactoring en général. Erreurs qu'un compilateur m'épargnerait normalement. Et ne me fais pas chercher d'erreurs dans la logique quand je viens de faire une faute de frappe dans un autre module.
Compte tenu de l'incroyable JavaScript suivant et d'autres langages typés dynamiquement, je suis amené à croire qu'il y a un problème avec mon approche. Ou est-ce juste le prix à payer?
Pour être plus concis:
En ce qui concerne spécifiquement JavaScript, vous pouvez utiliser TypeScript à la place. Il propose certaines des choses auxquelles vous faites référence. Citant le site Web:
Les types permettent aux développeurs JavaScript d'utiliser des outils et des pratiques de développement hautement productifs comme la vérification statique et la refactorisation de code lors du développement d'applications JavaScript.
Et ce n'est qu'un sur-ensemble de JS, ce qui signifie qu'une partie de votre code existant fonctionnera très bien avec TS:
TypeScript part de la même syntaxe et sémantique que des millions de développeurs JavaScript connaissent aujourd'hui. Utilisez du code JavaScript existant, incorporez des bibliothèques JavaScript populaires et appelez du code TypeScript à partir de JavaScript.
Il existe quelques approches qui peuvent aider:
Test unitaire
Écrivez des tests unitaires lorsque cela est possible. Se fier uniquement à des tests manuels ou trouver des bogues dans la nature est aléatoire.
tiliser des frameworks
Plutôt que de lancer le vôtre et de risquer l'introduction de bugs, utilisez des frameworks établis dans la mesure du possible.
Préférez les langages CSS/de haut nivea
Où vous pouvez céder des fonctionnalités à CSS ou à tout langage de haut niveau dans lequel vous écrivez.
Refactor
Refactoriser pour réduire la quantité de code. Moins de code = moins d'endroits pour que les choses tournent mal.
Réutiliser
Réutilisez le code existant où vous le pouvez. Même si le code n'est pas une correspondance exacte, il peut être préférable de copier, coller et modifier plutôt que d'écrire quelque chose de nouveau.
IDE
Les IDE modernes ont généralement au moins une prise en charge de Javascript. Certains éditeurs de texte sont également compatibles Javascript.
Un outil qui n'a pas encore été mentionné est simple, local ou à l'échelle du projet recherche de texte.
Cela semble simple, mais lorsque vous incluez des expressions régulières, vous pouvez effectuer un filtrage de base à avancé, par exemple rechercher des mots situés dans la documentation ou le code source.
Cela a été un outil efficace pour moi (en plus des analyseurs statiques), et compte tenu de la taille de votre projet de 2k LOC, ce qui n'est pas particulièrement important à mon avis, j'espère que cela devrait faire des merveilles.
Je refactorise actuellement plusieurs milliers de lignes de code sur un grand projet AngularJS. L'un des plus gros tracas est de déterminer le contrat exact d'une fonction donnée. J'ai parfois fini par lire la documentation de l'API car des éléments de la réponse brute de l'API ont été attribués à des variables qui ont traversé 6 couches de code avant d'être modifiées et retournées via 6 couches de code supplémentaires.
Mon premier conseil est de conception par contrat. Prenez une entrée spécifique, produisez une sortie spécifique, évitez les effets secondaires et documentez ces attentes en utilisant TypeScript ou au moins JSDoc.
Mon deuxième conseil est d'implémenter autant de contrôles que possible. Nous suivons la norme AirBnB et utilisons eslint sur l'ensemble de notre base de code. Les hooks de validation vérifient que nous respectons toujours la norme. Nous avons naturellement une batterie de tests unitaires et d'acceptation, et tous les commits doivent être examinés par un pair.
Le passage d'un éditeur de texte (Sublime Text) à un bon IDE (WebStorm) a également facilité le travail avec le code en général. WebStorm utilisera JSDoc pour donner des conseils sur les types de paramètres attendus et augmenter erreur si vous fournissez le mauvais type ou utilisez la valeur de retour de manière incorrecte.
En JavaScript, de nouvelles fonctionnalités telles que les symboles et les getter/setters peuvent aider à appliquer un certain niveau de qualité en ajoutant des assertions à l'affectation des variables (par exemple, assurez-vous que l'entier est dans la plage ou que l'objet de données a certains attributs).
Malheureusement, je ne pense pas qu'il existe une vraie solution pour éviter les erreurs de langage dynamiques, seulement une série de mesures qui peuvent aider à réduire leur fréquence.
Ma réponse à la question "Comment abordez-vous un projet JavaScript (ou tout autre langage dynamique d'ailleurs) avec ~ 2000 LOC?"
Je développe des applications de formulaire PDF. J'approche mon projet de développement de logiciel JavaScript (quelle que soit la taille du code source) en utilisant les éléments nets et les annotations de Petri. La méthode n'est liée à aucune technologie de langage de programmation particulière. peut être utilisé pour d'autres "langages de programmation".
Je crée un schéma de la logique d'application. Pour garder le diagramme épuré, j'ajoute la plupart de mes annotations à un formulaire que j'utilise avec le diagramme. Les entrées du formulaire incluent des références à des propriétés ou des fonctions. Ensuite, j'écris le code source sur la base des informations du diagramme et des entrées du formulaire. La méthode est systématique car chaque code source écrit est directement mappé à partir du diagramme et des entrées du formulaire. Le code source peut être facilement vérifié car je respecte également les conventions de dénomination et de codage lorsque j'écris le code.
Par exemple, j'ai choisi une convention selon laquelle toutes les fonctions sont des prototypes. Si les performances deviennent un problème, elles peuvent être améliorées en déclarant les fonctions dans le constructeur. Pour certaines propriétés, j'utilise des tableaux. Encore une fois, si les performances deviennent un problème, elles peuvent être améliorées en utilisant des références directes.
J'utilise également eval. Cela peut réduire considérablement la taille du code source. En raison de problèmes de performances, j'utilise eval au début ou à la partie d'initialisation de mon application; Je ne l'utilise jamais dans la "logique d'exécution" - c'est une autre convention de codage que je respecte.