La sécurité JavaScript ou comment écrire du code sécurisé en JS. Interaction étroite entre JavaScript et DOM

Il s'agit d'un packager modulaire qui crée un graphe de dépendances avec tous les modules d'une application JavaScript. Webpack regroupe les modules en un ou plusieurs petits packages à charger par le navigateur. De plus, Webpack peut être utilisé comme exécuteur de tâches, car il analyse les dépendances entre les modules et génère des actifs. Vous pouvez en savoir plus sur l'utilisation de Webpack dans vos projets dans notre.

  • Grunt est un exécuteur de tâches conçu pour automatiser les tâches répétitives et chronophages. Il existe un grand nombre de plugins (plus de 6000) dans son écosystème logiciel.
  • Gulp n'est pas seulement un gestionnaire de tâches parmi d'autres, mais un outil avec une approche intéressante : il définit les tâches en JavaScript comme des fonctions, Gul automatise également les tâches pénibles, offrant un large écosystème logiciel (plus de 2700 plugins), et il offre une meilleure transparence et un meilleur contrôle sur les tâches. processus.
  • Browserify permet aux développeurs de logiciels d'utiliser des modules de style NodeJS dans les navigateurs. Vous définissez les dépendances et Browserify regroupe le tout dans un fichier JS soigné.
  • Brunch.io est un outil dont les idées principales sont la rapidité et la simplicité. Il est livré avec une configuration simple et une documentation détaillée pour vous permettre d’être opérationnel rapidement. Brunch génère automatiquement une carte de fichiers JS ainsi que des feuilles de style CSS, facilitant ainsi le débogage côté client.
  • Yeoman est un outil universel qui peut être utilisé avec presque tous les langages de programmation (JavaScript, Python, C#, Java et autres). Ce système de génération de code basique doté d'un écosystème logiciel riche (plus de 6 200 plugins) est utilisé pour développer des applications Web. Grâce à Yeoman, vous pouvez créer rapidement de nouveaux projets sans oublier de maintenir et d'améliorer ceux existants.
  • IDE et éditeurs de code

    • Swagger est un ensemble de règles et d'outils permettant de décrire les API. L'outil est un utilitaire indépendant du langage. Cela signifie que Swagger crée une documentation claire, lisible à la fois par les humains et les machines, vous permettant d'automatiser les processus dépendants de l'API.
    • JSDoc est un ensemble d'outils qui génèrent automatiquement une documentation texte multipage (HTML, JSON, XML, etc.) à partir de commentaires du code source JavaScript. Cette application peut être utile pour gérer des projets à grande échelle.
    • jGrouseDoc (jGD) est un outil flexible et open source qui permet aux développeurs de générer des API à partir de commentaires du code source JavaScript. jGD documente non seulement les variables et les fonctions, mais également les espaces de noms, les interfaces, les packages et quelques autres éléments.
    • YUIDoc est une application écrite en NodeJS. Il utilise une syntaxe similaire à celle utilisée dans Javadoc et Doxygen. L'outil prend également en charge les aperçus en temps réel, la prise en charge linguistique avancée et le balisage avancé.
    • Docco est un outil de documentation gratuit écrit dans le langage littéraire CoffeeScript. Il crée un document HTML pour afficher vos commentaires entrecoupés de code. Il convient de noter que l'outil prend en charge non seulement JavaScript, mais également d'autres langages. Par exemple, Python, Ruby, Clojure et autres.

    Outils de test

    Les outils de test pour JavaScript sont conçus pour détecter les erreurs pendant le développement afin d'éviter les erreurs des utilisateurs à l'avenir. À mesure que la complexité des applications utilisateur augmente, les tests automatisés améliorent non seulement les performances des applications, mais aident également les entreprises à économiser leur budget.

    • Jasmine est un framework BDD (Behavior-driven Development) utilisé pour tester le code JS. Il n'a aucune dépendance externe et ne nécessite pas le DOM pour s'exécuter. Jasmine a une syntaxe claire et compréhensible qui rend les tests plus rapides et plus faciles. Le framework peut également être utilisé pour tester le code Python et Ruby.
    • Mocha est un framework de tests fonctionnels exécutant Node.js dans le navigateur. Il exécute les tests de manière séquentielle pour fournir des rapports flexibles et précis, rendant ainsi les tests asynchrones amusants et faciles. Moka est souvent utilisé en conjonction avec Chai pour vérifier les résultats des tests.
    • PhantomJS est souvent utilisé pour les tests frontaux et les tests unitaires. Étant donné qu'il s'agit d'une sorte de WebKit sans tête, les scripts s'exécutent beaucoup plus rapidement. Il inclut également une prise en charge intégrée de diverses normes Web. Par exemple, JSON, Canvas, traitement DOM, sélecteurs SVG et CSS.
    • Protractor est un framework de test de bout en bout écrit en Node.js pour tester les applications AngularJS et Angular. Il a été construit sur WebDriverJS et valide les applications comme un utilisateur final à l'aide de pilotes personnalisés et d'événements intégrés.

    Outils de débogage

    Le débogage du code est un processus plutôt laborieux et chronophage pour les développeurs JavaScript. Les outils de débogage de code seront particulièrement utiles lorsque vous travaillerez avec des milliers de lignes de code. De nombreux outils de débogage fournissent des résultats assez précis.

    • JavaScript Debugger est un outil du Mozilla Developer Network (MDN) qui peut être utilisé comme application Web autonome pour déboguer le code sur différents navigateurs. Firefox offre des fonctionnalités locales et distantes, ainsi que la possibilité de déboguer du code sur un appareil Android à l'aide de Firefox pour Android.
    • Chrome Dev Tools est un ensemble d'outils qui comprend plusieurs utilitaires permettant de déboguer le code JavaScript, de modifier le CSS et de tester les performances des applications.
    • ng-inspector est une extension multi-navigateurs conçue pour aider les développeurs à écrire, comprendre et déboguer des applications AngularJS. L'utilitaire est livré avec des mises à jour en temps réel, une mise en évidence du DOM, un accès direct aux régions, modèles et autres éléments d'application.
    • Augury est une extension pour le navigateur Google Chrome et le débogage des applications Angular 2. Il permet aux développeurs d'applications Angular 2 d'analyser directement la structure et les caractéristiques de performances des applications, et permet également la détection des modifications.

    Outils de sécurité

    • Snyk est un outil commercial permettant de détecter, corriger et prévenir les vulnérabilités connues dans les applications JavaScript, Java et Ruby. Le service possède sa propre base de données de vulnérabilités et récupère les données de NSP et NIST NVD. Les correctifs et mises à jour proposés par l'entreprise permettent aux développeurs de prévenir les risques de sécurité.
    • Le projet Node Security propose des outils utiles pour l'analyse des dépendances et la détection des vulnérabilités. NSP utilise sa propre base de données construite à partir de modules d'analyse npm, ainsi que des données provenant de bases de données communes telles que NIST NVD (National Vulnerability Database). De plus, NSP fournit une intégration avec les logiciels GitHub Pull Request et CI. Il existe également des vérifications, des alertes et des recommandations en temps réel pour éliminer les vulnérabilités des applications Node.js.
    • RetireJS est un vérificateur de dépendances open source. Comprend divers composants tels qu'un scanner de ligne de commande, un plugin Grunt, des extensions Firefox et Chrome, des plugins Burp et OWASP ZAP. Retirejs collecte des informations sur les vulnérabilités auprès du NIST NVD et d'autres sources telles que les outils de suivi des problèmes, les blogs et les listes de diffusion.
    • Gemnasium est un outil commercial avec un essai gratuit. Il prend en charge une variété de technologies et de packages, notamment Ruby, PHP, Bower (JavaScript), Python et npm (JavaScript). L'outil de sécurité Gemnasium est doté de fonctionnalités utiles telles que des mises à jour automatiques, des alertes en temps réel, des notifications de sécurité et l'intégration Slack.
    • OSSIndex prend en charge divers écosystèmes (Java, JavaScript et .NET/C#) et de nombreuses plateformes telles que NuGet, npm, Bower, Chocolatey, Maven, Composer, Drupal et MSI. Il collecte des informations sur les vulnérabilités à partir de la base de données nationale sur les vulnérabilités (NVD) et des commentaires. Il traite également les informations des membres de la communauté.

    Outils d'analyse et d'optimisation du code

    Pour vérifier la qualité du code, on se tourne généralement vers les tests fonctionnels et les tests unitaires. Il existe cependant une autre approche qui permet aux développeurs de vérifier la qualité du code et sa conformité aux normes de codage, à savoir l’analyse statique du code.

    Les logiciels modernes intègrent désormais des outils pour analyser le code statique pendant le développement afin de garantir qu'un code de mauvaise qualité n'arrive pas en production.

    • JSLint est un outil d'analyse Web permettant de vérifier la qualité du code JavaScript. Une fois qu'il détecte un problème à la source, il renvoie un message décrivant le problème et sa localisation approximative dans le code. JSLint est capable d'analyser certaines conventions de style et de découvrir des erreurs de syntaxe et des problèmes structurels.
    • JSHint est un outil flexible et communautaire permettant de détecter les bogues et les problèmes potentiels dans votre code JS, et est également un fork de JSLint. L'objectif principal de cet outil d'analyse de code statique est d'aider les développeurs JavaScript travaillant sur des programmes complexes. Il est capable de détecter les erreurs de syntaxe, la conversion implicite de types de données ou les variables manquantes. Cependant, il ne peut pas déterminer la vitesse ou l'exactitude de votre application, ni déterminer les problèmes de mémoire dans votre application. JSHint est un fork de JSLint.
    • ESLint est un linter open source pour les applications Web JSX et JavaScript. Il vous aide à repérer des modèles douteux ou à trouver du code qui ne suit pas des styles spécifiques. Cela permet aux développeurs de détecter les erreurs dans le code JS sans l'exécuter, gagnant ainsi du temps. Écrit en Node.js, l'outil offre un temps d'exécution rapide et une installation transparente via npm.
    • Flow est un contrôleur de code statique pour JavaScript développé par Facebook. Il utilise des annotations de type statique pour vérifier les erreurs dans le code. Les types sont des paramètres définis par les développeurs et Flow vérifie la conformité de votre logiciel.

    Outils de contrôle de versions

    • Ces dernières années, Git est devenu un système de contrôle de versions largement utilisé pour les petits et grands projets. Cet utilitaire gratuit offre une vitesse et une efficacité excellentes. Sa popularité est due à son système distribué et à ses différents types de contrôles, ainsi qu'à une zone de préparation où les versions peuvent être visualisées et formatées juste avant la fin de la validation.
    • L'outil Subversion ou SVN a acquis une immense popularité et est toujours largement utilisé dans des projets et des plateformes open source telles que Python Apache ou Ruby. Ce CVS est doté de nombreuses fonctionnalités qui vous permettent de gérer diverses opérations (renommer, copier, supprimer, etc.), les fusions, le verrouillage de fichiers et bien plus encore.

    Outils de gestion des packages et des dépendances

    La liste des meilleurs outils de développement JavaScript peut être longue. Dans cet article, vous n'avez vu que des outils populaires et fiables qui servent de base à des produits de qualité.

    Développer des applications sécurisées en JavaScript est une entreprise assez complexe. Mais tout à fait faisable. Dans l'article d'aujourd'hui, nous examinerons les fonctionnalités de JavaScript qui posent des problèmes de sécurité et discuterons des moyens de les éviter.

    Pourquoi est-il difficile d’écrire du code sécurisé en JS ?

    Voici donc 5 raisons pour lesquelles il est difficile d’écrire du code sécurisé en JS

    Le compilateur n'aidera pas

    JavaScript est un langage interprété. Cela signifie que le compilateur ne se plaindra pas de quelque chose tout le temps, refusant de travailler et vous poussant à corriger les erreurs et à optimiser le code.

    L'essence dynamique de JavaScript

    JavaScript est dynamique, faiblement typé et asynchrone. Et ce sont tous des signes qu’il est facile d’avoir des ennuis.

    1. Des outils linguistiques comme eval et l'inclusion de code tiers via le script src vous permettent d'exécuter des lignes directement au moment de l'exécution. En conséquence, il est difficile de donner des « garanties statiques » que le code se comportera d’une certaine manière. Cela rend également l'analyse dynamique difficile (voir travaux scientifiques).

    Utilisation d'évaluation

    2. Faible frappe Cela rend difficile l'application de techniques d'analyse statique établies, du moins par rapport aux langages typés statiquement (tels que Java).

    3. Rappels asynchrones, les appels que JavaScript autorise via des mécanismes comme setTimeout et XMLHttpRequest (le même célèbre AJAX), selon les statistiques, cachent les erreurs les plus insidieuses.

    Fonctionnalités JS complexes

    Ce qui n’a pas été introduit dans JavaScript au fil des années ! Plus précisément, il dispose de prototypes, de fonctions et de fermetures de première classe. Ils rendent le langage encore plus dynamique et l’écriture de code sécurisé plus difficile.

    1. Prototypes. Leur signification est que les programmes sont écrits dans l’esprit d’une approche orientée objet, mais sans recourir à des classes. Avec cette approche, les objets héritent des propriétés dont ils ont besoin directement d'autres objets (prototypes). De plus, dans JS, les prototypes peuvent être redéfinis directement au moment de l'exécution. Et si cette redéfinition se produit, alors l'effet s'étend immédiatement à tous les objets qui héritent des propriétés du prototype remplacé.

    Comment les prototypes sont traités

    Pour être honnête, il faut dire que les classes sont également présentes dans les nouvelles spécifications ECMAScript.

    2. Fonctions de première classe. JS a un modèle d'objets et de fonctions très flexible. Les propriétés des objets et leurs valeurs peuvent être créées, modifiées ou supprimées directement au moment de l'exécution, et toutes sont accessibles via des fonctions de première classe.

    3. Fermetures. Si vous déclarez une fonction dans une autre fonction, la première a accès aux variables et arguments de la seconde. De plus, ces variables continuent d'exister et restent disponibles pour la fonction interne, même après la fin de la fonction externe dans laquelle ces variables sont définies.

    Parce que JavaScript est très flexible et dynamique (voir points 1 et 3), déterminer l'ensemble de toutes les propriétés disponibles d'un objet lors d'une analyse statique est une tâche insoluble. Cependant, les développeurs Web utilisent partout les fonctionnalités dynamiques du langage et, par conséquent, elles ne peuvent pas être négligées lors de l’analyse du code. Sinon, quelle est la garantie de sécurité ?

    Interaction étroite entre JavaScript et DOM

    Ceci est nécessaire pour garantir une mise à jour « transparente » de la page Web, dès l’exécution. Le DOM, tel que nous le connaissons, est un modèle objet standard, indépendant de la plate-forme et du langage, pour le rendu des documents HTML et XML. Le DOM possède sa propre API pour travailler avec le document rendu : pour accéder, déplacer et mettre à jour dynamiquement le document rendu (son contenu, sa structure et son style). Les modifications apportées au DOM peuvent être apportées dynamiquement via JavaScript. Et ces changements sont immédiatement reflétés dans le navigateur.

    Grâce au DOM, les pages Web chargées dans le navigateur peuvent être mises à jour étape par étape au fur et à mesure du chargement des données depuis le serveur. Cependant, cette commodité a aussi un inconvénient : les fragments de code responsables de l'interaction dynamique entre JS et le DOM sont particulièrement sujets aux erreurs.

    Les erreurs les plus courantes dans les applications Web

    Interactions avec des événements complexes

    JavaScript est un langage événementiel. Il permet aux développeurs d'enregistrer ce qu'on appelle des écouteurs d'événements sur les nœuds DOM. Bien que la plupart des événements soient déclenchés par l'action de l'utilisateur, certains peuvent être déclenchés sans cette action, comme les événements programmés et les appels asynchrones. Dans ce cas, chaque événement peut résonner dans toute l’arborescence DOM et activer plusieurs « auditeurs » à la fois. Parfois, garder une trace de tout cela est une tâche plutôt non triviale.

    Comment les événements sont traités

    Pour ces raisons, le code JS peut être difficile à comprendre, analyser et tester. Des utilitaires spéciaux faciliteront la vie d'un développeur Web et vous aideront à écrire du code sécurisé.

    Utilitaires pour tester le code JS

    Il existe des utilitaires d'analyse (par exemple Esprima, Rhino), d'optimisation (par exemple Google Closure Compiler) et d'analyse de code statique pour les erreurs de syntaxe courantes (par exemple JSHint).

    De plus, il existe plusieurs frameworks éprouvés qui aident les développeurs Web à couvrir le code JS avec des tests. Parmi eux:

    • QUnit est un framework populaire pour les tests unitaires ;
    • Jasmine - Framework BDD (Behavior-driven Development) pour tester le code ;
    • Mocha est un framework pour tester le code, s'exécute à la fois dans Node.js et dans le navigateur ;
    • jsTestDriver est un framework qui, entre autres, peut exécuter un ensemble de tests via plusieurs navigateurs à la fois.

    De plus, il existe des frameworks de test qui émulent le comportement du navigateur et vous permettent d'exécuter automatiquement des cas de test. Ils sont particulièrement pertinents lors du débogage de sections de code responsables de l'interaction entre JS et le DOM et fournissent une infrastructure pratique pour manipuler le DOM.

    Par exemple, Selenium, PhantomJS et SlimerJS fournissent une API via laquelle vous pouvez lancer et interagir avec des instances de navigateur. Grâce à l'API, vous pouvez activer des événements et accéder aux éléments DOM directement au moment de l'exécution, c'est-à-dire tester le code dans des conditions aussi proches que possible des conditions réelles. Bien sûr, une partie considérable du travail devra être effectuée manuellement, mais même cela constitue une aide précieuse pour les tests.

    Utilitaires d'analyse statique

    Auparavant, les utilitaires permettant d'identifier les zones problématiques du code étaient des analyseurs statiques. Autrement dit, étant donné toutes les bizarreries dynamiques de JS, ils ne pouvaient fournir qu’une aide limitée. Cependant, ils peuvent également être utiles en analyse. Voici quelques exemples de base.

    WARI est un analyseur statique qui examine les dépendances entre les fonctions JS, les styles CSS, les balises HTML et les images. Le but de cet utilitaire est de rechercher les ressources inutilisées lors de l'analyse statique. Cependant, WARI, bien entendu, ne peut pas faire face à cette dynamique.

    JSLint est un utilitaire d'analyse de code statique lui-même écrit en JavaScript. Il vérifie le code par rapport aux bonnes pratiques.

    Google Closure Compiler est un optimiseur JS qui réécrit automatiquement le code pour le rendre plus rapide et plus compact. Dans le même temps, tous les commentaires et toutes les sections de code inutilisées sont perdus.

    WebScent (voir travaux scientifiques) est un analyseur statique avancé. Dans son travail, il part du fait que le code JS client (celui qui est chargé dans le navigateur) n'est pas stocké côté serveur dans son intégralité, mais est dispersé en morceaux dans tout le code serveur. Le « parfum » contenu dans ces morceaux ne peut pas être facilement détecté jusqu'à ce que le code client complet soit généré à partir d'eux. WebScent analyse le code client pour détecter les zones problématiques dans le code serveur. Dans le même temps, le travail de l'analyseur statique WebScent se résume principalement à démêler le désordre HTML, CSS et JS - afin de détecter le code en double et les erreurs dans la syntaxe HTML.

    Utilitaires d'analyse dynamique

    JSNose est un utilitaire qui combine l'analyse statique et dynamique. Il analyse le code de treize anti-modèles. Sept d'entre eux (y compris les objets paresseux et les fonctions longues) sont communs à tous les langages de programmation, et les six autres (odeurs de fermeture, variables globales excessives, rappels imbriqués et autres) sont spécifiques à JavaScript.

    DOMPletion est un utilitaire automatisé qui aide les développeurs Web à comprendre le code lorsqu'ils le révisent : explique pourquoi les structures DOM sont présentes, effectue une analyse dynamique et fournit également une saisie semi-automatique intelligente pour le code qui interagit avec le DOM.

    Clematis est un framework qui aide à démêler les interactions complexes entre événements. Clematis capture en détail tous les événements déclenchés lors de l'exécution et les visualise sous la forme d'un modèle comportemental abstrait qui reflète les relations temporelles et de cause à effet entre les composants et les événements.

    conclusions

    Ainsi, il peut être difficile de suivre ce qui se passe lors de l'exécution de scripts dans JS, mais, armé des bons outils, vous pouvez trouver et réécrire les zones problématiques même dans le code le plus déroutant. Cependant, JavaScript ne s'arrête pas : de plus en plus de fonctionnalités y apparaissent, désormais il est souvent utilisé pour écrire des applications (aussi bien mobiles que de bureau), et se retrouve également de plus en plus sur les serveurs (et pas seulement) grâce à Node.js. Cela signifie que l’art d’attraper les bugs doit être porté à un nouveau niveau.

    Et professeur de netologie, il a écrit une série d'articles sur EcmaScript6 pour le blog. Dans la première partie, nous examinerons l'analyse dynamique du code dans EcmaScript à l'aide d'Iroh.js à l'aide d'exemples.

    Analyse de code statique et dynamique

    Les outils d'analyse de code sont un outil utile qui vous permet de détecter et d'identifier les erreurs et les particularités de votre code. L'analyse du code peut être statique ou dynamique. Dans le premier cas, le code source est analysé et analysé sans l'exécuter ; dans le second, l'exécution s'effectue dans un environnement de sandboxing contrôlé, qui fournit des métainformations sur les éléments de l'application lors de son exécution.

    conclusions

    Iroh.js est un outil puissant et fonctionnel pour l'analyse dynamique de code dans EcmaScript. Cet outil peut être utilisé à la fois pour l'analyse du code, y compris la création d'un graphe d'appel, en déduisant les types et valeurs réels des variables et des objets, et pour la modification du code à la volée, y compris les corrections de code basées sur les événements.

    L'analyse dynamique est une méthode assez complexe, mais pour EcmaScript, étant donné le typage canard, la présence d'objets hôtes et de fonctions natives qui permettent de modifier le comportement du code à la volée, c'est le seul moyen d'analyser et de déboguer le code pendant l'exécution. Iroh.js peut également utiliser du code pour créer des tests fonctionnels sans avoir à le modifier au préalable pour exporter des valeurs.

    Toutes les lignes de mon code ne s'avèrent pas parfaites du premier coup. Eh bien, dans certains cas... Parfois... D'accord, presque jamais. La vérité est que je passe beaucoup plus de temps à corriger mes propres erreurs stupides que je ne le souhaiterais. C'est pourquoi j'utilise des analyseurs statiques dans presque tous les fichiers JavaScript que j'écris.

    Les analyseurs statiques examinent votre code et y trouvent des erreurs avant de l'exécuter. Ils effectuent des contrôles simples, comme la vérification de la syntaxe d'application (par exemple s'il y a des tabulations au lieu d'espaces) et des contrôles plus globaux, comme vérifier que les fonctions ne sont pas trop complexes. Les analyseurs statiques recherchent également les erreurs qui ne peuvent être trouvées lors des tests, par exemple == au lieu de ===.

    Dans les grands projets et lorsque vous travaillez dans de grandes équipes, vous pourriez avoir besoin d’un peu d’aide pour trouver ces bugs « simples » qui s’avèrent en réalité pas aussi simples qu’il y paraît.

    Compilateur JSLint, JSHint et Closure

    Il existe trois options principales pour les analyseurs statiques pour JavaScript : JSLint, JSHint et Closure Compiler.

    JSLint a été le premier analyseur statique pour JavaScript. Vous pouvez l'exécuter sur le site officiel ou utiliser l'un des modules complémentaires pouvant être exécutés dans des fichiers locaux. JSLint trouve de nombreuses erreurs importantes, mais c'est très difficile. Voici un exemple clair :

    Var s = "machaîne" ; pour (var je = 0; je< s.length; i++) { console.log(s.charAt(i)); }

    JSLint affiche deux erreurs dans ce code :

    "++" inattendu. Déplacez les déclarations "var" en haut de la fonction.

    Le premier problème est de définir la variable i dans les conditions de boucle. JSLint n'accepte pas non plus l'opérateur ++ à la fin d'une définition de boucle. Il veut que le code ressemble à ceci :

    Var s = "machaîne" ; var je; pour (je = 0; je< s.length; i = i + 1) { console.log(s.charAt(i)); }

    J'apprécie les créateurs de JSLint, mais à mon avis, c'est exagéré. Cela s'est également avéré difficile pour Anton Kovalev, alors il a créé JSHint.

    JSHint fonctionne de la même manière que JSLint, mais il est écrit en plus de Node.js et est donc plus flexible. JSHint comprend un grand nombre d'options, vous permettant d'effectuer des vérifications personnalisées en écrivant votre propre générateur de rapports.
    Vous pouvez exécuter JSHint à partir du site Web, mais dans la plupart des cas, il est préférable d'installer JSHint en tant qu'outil de ligne de commande local à l'aide de Node.js. Une fois JSHint installé, vous pouvez l'exécuter sur vos fichiers avec une commande comme celle-ci :

    Jshint test.js

    JSHint comprend également des plugins pour les éditeurs de texte populaires, afin que vous puissiez l'exécuter pendant que vous écrivez du code.

    COMPILATEUR DE FERMETURE

    Le compilateur Closure de Google est un type de programme complètement différent. Comme son nom l’indique, il ne s’agit pas seulement d’un programme de vérification, mais aussi d’un compilateur. Il est écrit en Java et est basé sur l'analyseur Rhino de Mozilla. Closure Compiler comprend un mode simple pour effectuer une vérification de code de base, et des modes plus complexes qui permettent une vérification supplémentaire et l'application de définitions de vues spécifiques.

    Closure Compiler signale les erreurs dans le code JavaScript, mais produit également des versions minifiées de JavaScript. Le compilateur supprime les espaces blancs, les commentaires et les variables inutilisées et simplifie les expressions longues, rendant le script aussi compact que possible.

    Google a mis à disposition une version très simple du compilateur en ligne, mais vous souhaiterez probablement télécharger Closure Compiler et l'exécuter localement.

    Closure Compiler, après avoir vérifié le code, génère une liste de fichiers dans un fichier minifié. Vous pouvez donc l'exécuter en téléchargeant le fichier compiler.jar.

    Java -jar compilateur.jar --js_output_file compress.js --js test1.js --js test2.js

    Choisir le bon programme de vérification

    Dans mes projets, je combine Closure Compiler et JSHint. Closure Compiler effectue une minification et une vérification de base, tandis que JSHint effectue une analyse de code plus complexe. Ces deux programmes fonctionnent bien ensemble et chacun couvre des domaines que l'autre ne peut pas couvrir. De plus, je peux utiliser les capacités de l'extension JSHint pour écrire des vérificateurs personnalisés. Un programme générique que j'ai écrit vérifie certaines fonctions dont je n'ai pas besoin, comme l'appel de fonctions qui ne devraient pas figurer dans mon projet.

    Maintenant que nous avons examiné quelques programmes à vérifier, examinons un mauvais code. Chacun de ces six exemples représente du code qui ne doit pas être écrit et des situations dans lesquelles les réviseurs de code peuvent vous sauver.

    Cet article utilise JSHint pour la plupart des exemples, mais Closure Compiler produit généralement des avertissements similaires.

    == ou === ?

    JavaScript est un langage typé dynamiquement. Vous n'êtes pas obligé de définir des types lorsque vous écrivez du code, mais ils existent au démarrage.

    JavaScript propose deux opérateurs de comparaison pour manipuler ces types dynamiques : == et ===. Regardons cela avec un exemple.

    Var n = 123 ; vars = "123" ; if (n == s) ( alert("Les variables sont égales"); ) if (n === s) ( alert("Les variables sont identiques"); )

    Opérateur de comparaison == sont des vestiges du langage C, dans lequel JavaScript a ses racines. L'utiliser est presque toujours une erreur : comparer les valeurs séparément des types est rarement ce que le développeur veut réellement faire. En fait, le nombre « cent vingt-trois » est différent de la ligne « un deux trois ». Ces déclarations sont faciles à mal orthographier et encore plus faciles à mal lire. Testez ce code avec JSHint et vous obtiendrez ce qui suit :

    Test.js : ligne 9, col 12, attendu "===" et vu à la place "==".

    Variables non définies et définitions tardives

    Commençons par un code simple :

    Fonction test() ( var maVar = "Bonjour tout le monde"; console.log(mavar); )

    Voyez-vous un bug ? Je fais cette erreur à chaque fois. Exécutez ce code et vous obtiendrez une erreur :

    ReferenceError : mavar n'est pas défini

    Rendons le problème un peu plus complexe :

    Fonction test() ( maVar = "Bonjour tout le monde"; console.log(maVar); )

    Exécutez ce code et vous obtiendrez ce qui suit :

    Bonjour le monde

    Ce deuxième exemple fonctionne, mais il entraîne des effets secondaires très inattendus. Les règles de définition des variables et de la portée JavaScript sont pour le moins déroutantes. Dans le premier cas, JSHint rapportera ce qui suit :

    Test.js : ligne 3, col 17, "myvar" n'est pas défini.

    Dans le deuxième cas, il signalera ceci :

    Test.js : ligne 2, col 5, "myVar" n'est pas défini. test.js : ligne 3, col 17, "myVar" n'est pas défini.

    Le premier exemple vous aidera à éviter une erreur d’exécution. Vous n'avez pas besoin de tester votre application - JSHint trouvera le bug pour vous. Le deuxième exemple est pire, car à la suite des tests, vous ne trouverez aucun bug.

    Le problème du deuxième exemple est insidieusement subtil et complexe. La variable myVar a désormais disparu de sa portée et est passée à la portée globale. Cela signifie qu'il existera et aura la valeur Hello, World même après l'exécution de la fonction de test. C’est ce qu’on appelle une pollution à l’échelle mondiale.

    La variable myVar existera pour toutes les autres fonctions exécutées après la fonction de test. Exécutez le code suivant après avoir exécuté la fonction de test :

    Console.log("maVar: " + maVar);

    Vous recevrez toujours Hello, World. La variable myVar traînera dans tout votre code comme un modèle qui conduit à des bogues complexes que vous rechercherez toute la nuit avant la sortie, tout cela parce que vous avez oublié d'inclure var.

    ALEXANDRE MAYOROV, programmeur, programme depuis 11 ans, dont sept ans consacrés au développement pour les appareils mobiles

    Analyse de type statique en JavaScript
    Essayer l'analyseur de flux de Facebook

    Facebook a présenté un nouveau projet open source, Flow, un analyseur de code statique pour le langage JavaScript. L'objectif principal du développement de l'analyseur est de simplifier la recherche d'erreurs

    De plus, Flow fournit une extension syntaxique de style TypeScript à JavaScript pour spécifier explicitement les types. De nombreuses nouvelles fonctionnalités introduites dans la spécification ECMAScript 6 sont prises en charge.

    Le sujet de la saisie dans les langages de programmation est fréquemment abordé. C'est le sujet des holivars et de la détermination des caractéristiques positives ou négatives d'une langue particulière. Récemment, on a beaucoup parlé de la saisie en JavaScript. Certaines personnes l’aiment tel quel. Les personnes familiarisées avec d'autres langages de programmation, en particulier ceux dotés d'un typage explicite fort, considèrent cette approche comme une « grenade entre les mains d'un singe ». Nous savons tous que JavaScript est un langage peu typé dynamiquement. Les gourous du développement frontend ont appris à utiliser cela à leur avantage, mais le code est parfois difficile à comprendre. Ceux qui viennent tout juste d’entrer dans le monde de la programmation JavaScript sont perplexes face à la magie exercée par l’interpréteur et détectent souvent des erreurs à l’improviste. Mais commençons par comprendre un peu la saisie en général. Comment est-ce ?

    Saisie dans des langages de programmation

    Basés sur le typage, les langages de programmation sont divisés en deux grands camps : typés et non typés. Les langages typés, par exemple, incluent des langages tels que C, Python, PHP, Lua, JavaScript. Exemples de langages non typés : assembleur, Forth, Brainfuck. Oui oui exactement. JavaScript, comme beaucoup d'autres langages interprétés, est typé. Par conséquent, ne dites en aucun cas qu’il n’est pas typé. Surtout lors des entretiens.

    À leur tour, les langues typées sont divisées en plusieurs catégories qui se chevauchent davantage :

    • Avec typage statique ou dynamique.
    • Avec une frappe forte ou lâche.
    • Avec typage explicite ou implicite.

    Langues typées statiquement

    Avec le typage statique, les types finaux de variables et de fonctions sont définis au moment de la compilation. Le compilateur corrige vos erreurs en cas d'incompatibilité de type avant même d'exécuter le programme. Exemples de langages : C, Java, C#.

    Langages typés dynamiquement

    En typage dynamique, tous les types sont découverts lors de l'exécution du programme. Et si vous avez commis une erreur, vous ne le découvrirez qu'en exécutant le programme. Par conséquent, lors de la saisie dynamique, il est très important d’accorder une attention particulière aux contrôles et à la détection des erreurs. Exemples de langages : JavaScript, PHP, Python, Ruby.

    Typage fort (fort)

    Les langages fortement typés ne permettent pas de mélanger différents types dans les expressions et n'effectueront pas de conversions de types implicites automatiques. Par exemple, vous ne pouvez pas soustraire d’une chaîne un nombre ou un autre type autre qu’une chaîne. Exemples de langages : Java, Python, Haskell, Lisp.

    Typage non fort (faible)

    Les langages faiblement typés effectuent automatiquement de nombreuses conversions de types implicites. Ils le font même si une perte de précision ou de conversion peut se produire de manière ambiguë. Exemples de langages : PHP, JavaScript, Visual Basic.

    Saisie explicite

    Dans les langages explicitement typés, le type des nouvelles variables/fonctions et arguments doit être spécifié explicitement. Exemples de langages : C++, D, C#.

    Saisie implicite

    Dans les langages implicitement typés, la tâche de spécifier les types est laissée au compilateur/interprète. Exemples de langages : JavaScript, PHP, Lua. Dans ces langages, en règle générale, les objets ont des méthodes spéciales qui sont appelées lorsqu'ils sont convertis en un type. Par exemple, PHP a la méthode _toString() et JavaScript a une méthode du même nom, mais sans le trait de soulignement, toString(). Ces méthodes sont appelées lorsqu'un objet est converti en type chaîne. Parfois, ces méthodes sont appelées magiques (tout processus implicite est toujours magique).

    Il est important de noter que toutes ces catégories se chevauchent. Sur la base de ces catégories, nous voyons que JavaScript a un typage implicite dynamique. Et si l'on parle de manière exagérée, la nature du langage peut être décrite ainsi : dans toute situation incompréhensible, tout réduire à des primitifs, principalement à une chaîne. Même si en réalité tout est un peu plus compliqué, nous n'entrerons pas dans les détails maintenant.

    "Pourquoi avons-nous besoin de taper?" - tu peux demander. Sans cela, JavaScript a bien vécu pendant 20 ans. La réponse est simple : les problèmes complexes au niveau de l’entreprise n’ont jamais été résolus en JavaScript auparavant. Désormais, ce langage a dépassé le cadre du navigateur et est entré sur le territoire du backend. Lors de l’écriture d’une application volumineuse, il devient difficile de détecter les erreurs, qui sont souvent spécifiquement liées à la conversion de type.

    Modules complémentaires JavaScript

    Puisque JavaScript est exécuté côté client (dans les navigateurs), l'une des solutions au problème semble être la création d'un langage - un dialecte qui sera compilé en JS. Il agit comme un assembleur.

    Des langages comme TypeScript, Dart, AtScript ont émergé et ajoutent un typage fort statique et même une vérification de type à l'exécution (bien que cela ajoute une surcharge). Tous ces langages n'ajoutent pas seulement des types, ils ajoutent également soit du sucre syntaxique, soit leur propre implémentation de VM, écrite en JS.

    Lisez l'intégralité de l'article dans le magazine « System Administrator », n° 1-2 pour 2015, pages 86-88.

    Une version PDF de ce numéro peut être achetée dans notre magasin.

    1. Site Web de Flow - http://flowtype.org.

    En contact avec