JavaScript est souvent appelé le «langage le plus populaire», mais il semble que personne ne parle du développement JS comme «le plus sûr», et le nombre de problèmes cachés dans l'écosystème est important. Comment les contourner efficacement?
Ilya Klimov y a pensé lorsque l'erreur était très chère (littéralement) - et a finalement fait une présentation sur HolyJS. Et comme les critiques du public se sont avérées excellentes, nous avons maintenant préparé une version texte de ce rapport pour Habr. Sous la coupe - à la fois du texte et de la vidéo.
Bonjour à tous. Je m'appelle Ilya Klimov, je viens de Kharkov, en Ukraine. J'ai ma propre petite entreprise de sous-traitance, jusqu'à dix personnes. Nous faisons tout ce pour quoi l'argent est payé ... en ce sens, nous programmons en JavaScript dans tous les secteurs. Aujourd'hui, en parlant de JavaScript fiable, je veux partager mes meilleures pratiques quelque part au cours de la dernière année, car ce sujet a commencé à me déranger très sérieusement.
Ceux qui travaillent dans l'externalisation comprendront le contenu de la diapositive suivante:

Tout ce dont nous allons parler, bien sûr, n'a rien à voir avec la réalité. Comme on dit dans South Park, tous les personnages sont gâtés et misérablement. Naturellement, les endroits où l'on soupçonne une violation de la NDA ont été convenus avec les représentants des clients.
Rien n'a affecté mes réflexions sur la fiabilité et autres en tant que fondement de ma propre entreprise. Lorsque vous démarrez votre propre entreprise, il s'avère soudainement que vous pouvez être un programmeur très cool, vous pouvez avoir des gars très cool, mais parfois des choses incroyables se produisent, un couple impossible et complètement fou.
J'ai un projet éducatif Ninja JavaScript. Parfois, je fais des promesses. Parfois, je les suis même. J'ai promis en 2017, dans le cadre d'un projet éducatif, d'enregistrer une vidéo sur Kubernetes. J'ai réalisé que j'avais fait cette promesse et ce serait bien de la réaliser, le 31 décembre. Et je me suis assis pour enregistrer (
voici le résultat ).
Comme j'aime enregistrer des vidéos au plus près de la réalité, j'ai profité d'exemples de vrai projet. En conséquence, dans le cluster de démonstration, j'ai déployé une chose qui a pris de vraies commandes de la production réelle et les a placées dans une base de données Kubernetes distincte dans mon cluster de démonstration.
Depuis le 31 décembre, une partie des commandes a disparu. Radié pour saisonnalité: tout le monde est allé boire du thé. Lorsque le client s'est réveillé du 12 au 13 janvier, le coût total de la vidéo était d'environ 500 000 $. Je n'avais pas encore une production aussi chère.

Exemple numéro deux: un autre cluster Kubernetes. Infrastructure d'écosystème nouvelle génération en tant que code: tout ce qui peut être décrit par du code et des configurations, Kubernetes se programme par programmation à partir de shells JavaScript, etc. Cool, tout le monde aime ça. Un petit changement dans la procédure de déploiement, et il arrive un moment où vous devez déployer un nouveau cluster. La situation suivante se présente:
const config = { // … mysql: process.env.MYSQL_URI || 'mysql://localhost:3306/foo' // ... }
Beaucoup d'entre vous ont probablement aussi cette ligne de code dans vos configurations. Autrement dit, nous prenons la configuration de la variable mysql ou prenons la base de données locale.
En raison d'une faute de frappe dans le système de déploiement, il s'est avéré que le système était à nouveau configuré comme production, mais la base de données MySQL utilisait une base de données de test - locale, qui était destinée aux tests. Cette fois, moins d'argent a été dépensé - seulement 300 000 $. Heureusement, ce n'était pas mon entreprise, mais l'endroit où je travaillais en tant que consultant engagé.

Vous pourriez penser que tout cela ne vous concerne pas en tant que front-end, car j'ai parlé de DevOps (au fait, j'admire le nom de la conférence
DevOops , il décrit parfaitement l'essence). Mais je vais vous parler d'une autre situation.
Il existe un système de contrôle des épidémies vétérinaires en Éthiopie, développé sous les auspices de l'ONU. Il contient l'un des éléments d'interface quand il s'agit d'une personne, et il entre manuellement les coordonnées: quand et où il y a eu des foyers d'une certaine maladie.
Il y a une épidémie de fièvre aphteuse régulière (je ne suis pas fort dans les maladies des vaches), et pressé, l'opérateur appuie accidentellement deux fois sur le bouton «ajouter», laissant les champs vides. Puisque nous avons JavaScript et que JavaScript et les types sont très bons, les champs vides de latitude et de longitude mènent joyeusement à des coordonnées nulles.
Non, nous n'avons pas envoyé le médecin loin dans l'océan, mais il s'est avéré que tout cela avait été précédemment calculé du point de vue du clustering à afficher sur la carte, créer des rapports, des analyses, analyser le placement des personnes sur le backend. Nous essayons d'unir les points d'épidémie.
En conséquence, le système est paralysé pendant la journée, car le backend essaie de calculer le cluster avec l'inclusion de ce point, toutes les données deviennent hors de propos, les commandes complètement irresponsables de la série des «400 kilomètres à parcourir» arrivent aux médecins. 400 kilomètres en Ethiopie est un plaisir douteux.
L'estimation de la perte totale est d'environ un million de dollars. Dans le rapport sur cette situation, il était écrit "Nous avons été victimes d'un ensemble malheureux de circonstances". Mais nous savons que le point est JavaScript!

Et le dernier exemple. Malheureusement, bien que cette histoire remonte à longtemps, je ne peux toujours pas nommer l'entreprise. Mais c'est une entreprise qui a sa propre compagnie aérienne, ses propres hôtels, etc. Elle travaille de manière très interactive avec les entreprises, c'est-à-dire qu'elle leur fournit une interface distincte pour la réservation de billets, etc.
Une fois un accident absurde, une commande de réservation de billets de New York à Los Angeles d'un montant de 999 999 pièces arrive. Le système de la compagnie a acheté tous les vols de sa propre compagnie aérienne, a découvert qu’il n’y avait pas assez de sièges et a envoyé les données au système de réservation international pour compenser la pénurie. Le système de réservation international, voyant une demande d'environ 950 000 billets, a heureusement déconnecté cette compagnie aérienne de son système.
Étant donné que l'arrêt est un événement hors du commun, le problème a ensuite été résolu en sept minutes. Cependant, au cours de ces sept minutes, le coût des amendes à payer n'était que de 100 000 $.

Heureusement, tout cela s'est produit en plus d'un an. Mais ces cas m'ont fait réfléchir aux problèmes de fiabilité et à poser deux questions russes originales: qui est à blâmer et que faire à ce sujet?
Pourquoi cela se produit: les jeunes de l'écosystème
Si vous analysez beaucoup d'histoires, vous constaterez qu'il y a plus d'histoires sur des problèmes similaires avec JavaScript qu'avec un autre langage de programmation. Ce n'est pas mon impression subjective, mais les résultats de l'analyse intelligente des nouvelles sur Hacker News. D'une part, c'est une source hipster et subjective, mais, d'autre part, il est assez difficile de trouver une source saine par fakap dans le domaine de la programmation.
De plus, il y a un an, j'ai organisé un concours où je devais résoudre tous les jours des problèmes algorithmiques. Depuis que je m'ennuyais, je les ai résolus en JavaScript en utilisant la programmation fonctionnelle. J'ai écrit une fonction complètement pure, et dans le Chrome actuel, cela a fonctionné correctement 1197 fois, et 3 fois a produit un résultat différent. Ce n'était qu'une petite erreur dans l'optimiseur TurboFan, qui vient d'entrer dans le principal Chrome.
Bien sûr, il a été corrigé, mais vous comprenez: cela signifie, par exemple, que si vos tests unitaires ont réussi une fois, cela ne signifie pas du tout qu'ils fonctionneront dans le système. Autrement dit, nous avons exécuté du code environ 1197 fois, puis l'optimiseur est venu et a dit: «Wow! Fonctionnalité chaude! Optimisons-le. " Et dans le processus d'optimisation a conduit au mauvais résultat.
En d'autres termes, nous pouvons appeler la jeunesse de l'écosystème l'une des premières raisons pour lesquelles cela se produit. JavaScript est une industrie assez jeune précisément dans le domaine de la programmation sérieuse, dans les cas où des millions tournent, où le coût d'une erreur est mesuré de cinq à six caractères.
Pendant longtemps, JavaScript a été perçu comme un jouet. Pour cette raison (pas parce que nous ne prenons pas cela au sérieux), nous avons toujours des problèmes avec le manque d'outils.
Par conséquent, afin de faire face à cette raison, qui est le principe fondamental fondamental de tout ce dont je vais parler aujourd'hui, j'ai essayé de formuler les règles de fiabilité que je pourrais imposer dans mon entreprise ou transférer en tant que consultant à d'autres. Comme dit le proverbe, «la règle numéro un est de ne pas parler de fiabilité». Mais plus sérieusement, alors ...
Règle de fiabilité n ° 1: tout ce qui peut être automatisé doit être automatisé
Y compris, en passant, et la vérification orthographique:
Texte masquéRègle de fiabilité n ° 1: tout ce qui peut être automatisé doit être automatisé
Tout commence par les choses les plus simples. Il semblerait que tout le monde écrit Prettier depuis longtemps. Mais seulement en 2018, cette chose que nous utilisons tous, bonne et saine, a appris à fonctionner avec git add -p lorsque nous ajoutons partiellement des fichiers au référentiel git, et nous voulons bien formater le code, par exemple, avant de l'envoyer au référentiel principal. L'utilitaire realinstaged assez connu, qui vous permet de vérifier uniquement les fichiers qui ont été modifiés, a exactement le même problème.

Continuer à jouer à Captain Evidence: ESLint. Je ne demanderai pas qui l'utilise ici, car cela n'a aucun sens pour tout le public de lever la main (enfin, je l'espère et je ne veux pas être déçu). Il vaut mieux lever la main qui ont leurs propres règles écrites personnalisées dans ESLint.
Ces règles sont l'un des moyens très puissants d'automatiser le désordre qui se produit dans les projets où les gens écrivent au niveau junior et autres.
Nous voulons tous un certain niveau d'isolement, mais tôt ou tard une situation se présente: «Écoutez, cet assistant Vasya s'est vendu quelque part dans le répertoire de son composant très proche. Je ne le retirerai pas en commun, alors je le ferai. » Le mot magique est "plus tard". Cela conduit au fait que les dépendances verticales ne commencent pas à apparaître dans le projet (lorsque les éléments supérieurs connectent les éléments inférieurs, les éléments inférieurs ne montent jamais derrière les éléments supérieurs), mais le composant A dépend du composant B, qui est dans une branche complètement différente. Par conséquent, le composant A n'est pas si facilement transporté vers d'autres composants.
Au fait, j'exprime mon respect à Alfa-Bank, ils ont une bibliothèque de composants très bien et magnifiquement écrite sur React, c'est un plaisir de l'utiliser précisément en termes de conception de la qualité du code.
La règle banale ESLint, qui garde la trace de l'endroit où vous importez des entités, vous permet d'augmenter considérablement la qualité du code et d'enregistrer le modèle mental lors de la révision du code.
Je suis déjà du point de vue du monde du front-end. Récemment, dans la région de Kharkov, une grande et sérieuse entreprise PricewaterhouseCoopers a achevé une étude, et l'âge moyen du vendeur frontal est d'environ 24 à 25 ans. C'est déjà difficile pour moi de penser à tout cela, je veux me concentrer sur la logique métier lors d'un examen de demande de pull. Par conséquent, je suis heureux d'écrire des règles ESLint afin de ne pas penser à de telles choses.
Il semblerait que vous puissiez ajuster les règles habituelles pour cela, mais la réalité dérange généralement beaucoup plus, car il s'avère que certains sélecteurs Redux sont nécessaires à partir du composant React (il est malheureusement toujours vivant). Et ces sélecteurs sont quelque part dans une hiérarchie complètement différente, donc "../../../ ..".
Ou, pire encore, l'alias du webpack, qui casse environ 20% des autres outils, car tout le monde ne sait pas comment l'utiliser. Par exemple, mon bien-aimé Flow.
Par conséquent, la prochaine fois avant de vouloir grogner chez un junior (et le programmeur a un passe-temps si préféré), demandez-vous si vous pouvez en quelque sorte automatiser cela afin de ne pas faire d'erreurs à l'avenir. Dans un monde idéal, bien sûr, vous écrirez des instructions que personne ne lira de toute façon. Voici les conférenciers de HolyJS - des spécialistes talentueux ayant une grande expérience, mais quand il a été proposé de rédiger des instructions pour les conférenciers lors d'un rassemblement interne, ils ont dit "oui, ils ne le liront pas". Et ce sont les gens à qui prendre un exemple!
Le dernier du banalisme, et passer à l'étain. Ce sont des outils pour exécuter des hooks de pré-validation. Nous utilisons du
husky , et je n'ai pas pu m'empêcher d'insérer cette belle photo husky, mais vous pouvez utiliser autre chose.

Si vous pensez que tout cela est très simple - comme on dit, tenez ma bière, nous comprendrons bientôt que tout est plus compliqué que vous ne le pensez. Quelques points supplémentaires:
Dactylographie
Si vous n'écrivez pas TypeScript, vous voudrez peut-être y penser. Je n'aime pas TypeScript, j'ai toujours un flux à haut débit, mais nous en parlerons plus tard, mais ici, à partir de l'étape, je ferai la promotion de la solution grand public avec dégoût.
Pourquoi Le comité du programme TC39 a récemment eu une très grande discussion sur la destination générale de la langue. Une conclusion très amusante à laquelle ils sont arrivés: dans TC39, il y a toujours un «cygne, un cancer et un brochet» qui traînent leur langue dans différentes directions, mais il y a une chose que tout le monde veut et c'est toujours la performance.
TC39 informellement, dans une discussion interne, a publié cette tirade: "Nous ferons toujours JavaScript pour qu'il reste productif, et ceux qui ne l'aiment pas prendront une sorte de langage qui se compile en JavaScript."
TypeScript est une très bonne alternative à l'écosystème adulte. Je ne peux que mentionner mon amour pour GraphQL. C'est vraiment bien, malheureusement, personne ne le laissera être mis en œuvre sur un grand nombre de projets existants où nous devons déjà travailler.

Il y avait déjà des rapports sur GraphQL lors de la conférence, donc il n'y a qu'un seul trait spécifiquement à la question de la fiabilité: si vous utilisez, par exemple, Express GraphQL, puis à chaque fois en plus d'un résolveur spécifique, vous pouvez accrocher certains validateurs qui vous permettent de resserrer les exigences de valeur par rapport à types standard de GraphQL.
Par exemple, j'aimerais que le montant du transfert entre deux représentants de certaines banques soit positif. Parce qu'au plus tard hier, la fenêtre contextuelle de mes services bancaires par Internet a joyeusement annoncé que j'avais -2 messages non lus de la banque. Et c'est un peu comme une grande banque de mon pays.
Quant à ces valideurs, qui imposent une rigueur supplémentaire: les utiliser est une bonne et bonne idée, il suffit de ne pas les utiliser comme le suggère, disons, GraphQL. Vous vous retrouvez très attaché à GraphQL en tant que plateforme. En même temps, la validation que vous faites est nécessaire à deux endroits en même temps: sur le frontend avant d'envoyer et de recevoir des données, et sur le backend.
Je dois régulièrement expliquer au client pourquoi nous avons pris JavaScript et non le langage X comme backend. De plus, le langage X est généralement une sorte de PHP, et pas beau Go et autres. Je dois expliquer que nous sommes en mesure de réutiliser le code aussi efficacement que possible, y compris entre le client et le backend, car ils sont écrits dans le même langage de programmation. Malheureusement, comme le montre la pratique, souvent cette thèse reste juste une phrase lors de la conférence et ne trouve pas d'incarnation dans la vraie vie.
Contrats
J'ai déjà parlé de la jeunesse de l'écosystème. La programmation des contrats existe depuis plus de 25 ans comme approche principale. Si vous écrivez sur TypeScript, prenez io-ts, si vous écrivez sur Flow, comme moi, prenez typed-contract, et vous obtiendrez une chose très importante: la possibilité de décrire des contrats d'exécution à partir desquels dériver des types statiques.

Il n'y a pas pire pour un programmeur que d'avoir plus d'une source de vérité. Je connais des gens qui ont perdu des montants à cinq chiffres en dollars simplement parce que leur type est décrit dans un langage de typage statique (ils ont utilisé TypeScript - eh bien, bien sûr, ce n'est qu'une coïncidence) et le type d'exécution (il semble avoir utilisé
tcomb ) légèrement différent.
Par conséquent, l'erreur n'a pas été détectée au moment de la compilation, simplement parce que pourquoi la vérifier? Il n'y avait pas de tests unitaires pour cela, car nous avons été vérifiés par un typificateur statique. Cela n'a aucun sens de tester des choses qui ont été vérifiées par la couche ci-dessous, tout le monde se souvient de la hiérarchie des tests.
Étant donné que la synchronisation entre ces deux contrats a été interrompue au fil du temps, un jour, un transfert incorrect a été effectué vers l'adresse qui a été envoyée à la mauvaise adresse. Comme il s'agissait d'une crypto-monnaie, il est impossible d'annuler une transaction un peu plus qu'en principe. Personne ne bifurquera à nouveau pour vous. Par conséquent, les contrats et les interactions dans la programmation des contrats sont les premières choses que vous devriez commencer à faire demain.
Pourquoi cela se produit: l'isolement
Le problème suivant est l'isolement. Il est multiforme et multiforme. Lorsque je travaillais pour un hôtel et une compagnie de voyages aériens, ils avaient une application sur Angular 1. C'était il y a longtemps, donc c'est excusable. Une équipe de 80 personnes a travaillé sur cette application. Tout a été couvert par des tests. tout allait bien jusqu'au jour où j'ai fait ma fonctionnalité, je ne l'ai pas figée et j'ai découvert que j'avais cassé, pendant les tests, des endroits absolument incroyables sur le système que je n'avais même pas touchés.
Il s'est avéré que j'ai des problèmes de créativité. Il s'est avéré que j'ai accidentellement appelé le service exactement comme un autre service qui existait dans le système. Puisqu'il s'agissait d'Angular 1 et que le système de service n'était pas strictement typé, mais typé de manière stricte, Angular a commencé très calmement à glisser mon service dans des endroits complètement différents et, ironiquement, deux méthodes de dénomination ont coïncidé.
Bien sûr, ce n'était pas une coïncidence: vous comprenez que si deux services sont nommés de la même manière, ils sont susceptibles de faire la même chose, plus ou moins. C'était un service lié au calcul des remises. Un seul module était occupé à calculer les remises pour les entreprises clientes, et le deuxième module avec mon nom était lié au calcul des remises sur les stocks.
Évidemment, lorsque l'application est sciée par 80 personnes, cela signifie qu'elle est grande. Le fractionnement de code a été implémenté dans l'application, ce qui signifie que la séquence de connexion des modules dépendait directement du déplacement de l'utilisateur sur le site. Pour le rendre encore plus intéressant, il s'est avéré qu'aucun test de bout en bout qui a testé le comportement et le passage des utilisateurs sur le site, c'est-à-dire un scénario commercial spécifique, n'a détecté cette erreur. Parce qu'il semble que personne ne devra jamais contacter les deux modules de réduction en même temps. Certes, cela a complètement paralysé le travail des administrateurs du site, mais avec qui cela ne se produit pas.
Le problème de l'isolement est très bien illustré par le logo de l'un des projets qui résout partiellement ce problème. Voici Lerna.

Lerna est un excellent outil pour gérer plusieurs packages npm dans un référentiel. Lorsque vous avez un marteau dans les mains, tout devient étrangement comme un clou. Lorsque vous avez un système de type Unix avec la bonne philosophie, tout devient étrangement comme un fichier. Tout le monde sait que sur les systèmes Unix, tout est un fichier. Il y a des systèmes où elle est portée au plus haut degré (j'ai presque dit "au point d'absurdité"), comme le
Plan 9 .
Je connais des organisations qui, ayant veillé à assurer la fiabilité d'une application géante, ont trouvé une idée simple: tout est un package.

Lorsque vous supprimez un élément de fonctionnalité, que ce soit un composant ou autre, dans un package séparé, vous fournissez automatiquement une couche d'isolement. Tout simplement parce que vous ne pouvez normalement pas en atteindre un autre à partir d'un seul paquet. Et aussi parce que le système de travail avec les packages collectés dans un mono-référentiel via npm-link ou Yarn Workspaces est si horrible et imprévisible en termes d'organisation interne que vous ne pouvez même pas recourir à un hack et connecter une sorte de fichier via "node_modules quelque chose", simplement parce que différentes personnes ont tout cela dans une structure différente. Cela dépend surtout de la version de Yarn. Là, dans l'une des versions, ils ont complètement changé le mécanisme de la façon dont Yarn Workspaces organise le travail avec les packages.
Le deuxième exemple d'isolement pour montrer que le problème est multiforme est le paquet que j'essaie d'utiliser partout maintenant - c'est
cls-hooked . Vous connaissez peut-être un autre package qui implémente la même chose - c'est
continuation-local-storage . Il résout un problème très important qui, par exemple, n'est pas rencontré, par exemple, par les développeurs en PHP.
Il s'agit d'isoler chaque demande spécifique. En PHP, nous avons, en moyenne, dans un hôpital, toutes les demandes sont isolées, n'interagissant entre elles que si vous n'utilisez pas de perversions comme la mémoire partagée, nous ne pouvons pas, tout va bien, paisible, beau. Essentiellement, cls-hooked ajoute la même chose, vous permettant de créer des contextes d'exécution, d'y placer des variables locales, puis, surtout, de détruire automatiquement ces contextes afin qu'ils ne continuent pas à manger votre mémoire.
Ce cls-hooked est construit sur async_hooks, qui dans node.js sont toujours en statut expérimental, mais je ne connais pas une ou deux sociétés qui les utilisent dans une production assez sévère et sont heureuses. Il y a une légère baisse des performances, mais la possibilité de collecter automatiquement les déchets est inestimable.Lorsque nous commençons à parler de problèmes d'isolement, de pousser différentes choses dans différents modules de nœuds.Règle de fiabilité n ° 2: le mauvais code et le «mauvais» doivent avoir l'air faux
Avec le premier critère que je me suis déduit, il y a dix ans, je ne serais pas d'accord. Parce que vous grinçeriez que JavaScript est un langage dynamique, et vous me privez de toute la beauté et de l'expressivité du langage. Il s'agit d'un test grep.Qu'est ce que c'est vim. , - Language Server, - — , , grep. , , . grep- , grep. , , .
Sequelize . ORM . user.getProjects(). , getProjects? .

, Sequelize, , hasMany, belongsToMany. , , , . , .
code review, , . . — , .
, : «merge request 20 — 30 , merge request 5000 — looks good to me». , .
JavaScript Ninja , , , junior-, . « react redux», 8000 , 10 000 » , , « ». , , « », , merge request .
, , merge request , , Linux. , , -. , git. , . , , . .
- . . - , , - .
, . Microsoft Surface Linux, . , , . - .
:

« », « ». , React. React, Fiber — .
, Fiber ( OCaml) JavaScript, . , . , — , proposal, JavaScript. Scheduler — proposal stage 0.
, React , - . , : , DOM. — . , .

— Vue.js. Vue? , . Vue, , , .
Vue React. , Vue, , React.
. Vue , state, , state , . , . Vue .
. , , Web Components c , , . : , pop-up, , , - . — .
Vue — scoped slots. , - . scoped slot — , . . React Render Proper: , . Vue , -.
-, Vue . Vue : , child-, , scoped slots, forceUpdate. , child . .
React . , , shouldComponentUpdate(), . Vue , , , , . . Vue. , - .

—
Jest . Facebook. JavaScript: , , . . , .
, ECMAScript 2015 . , if, require. Require , . , , , . Jest Babel Require .
NGS- Node, proposal, . JavaScript : Require, . . , Jest c NGS- , , . , .
, , - . , Inversion of Control - Dependency Injection-.
IoC/DI
, , . Angular IoC/DI. React … , , React Vue?
dan.church , evan.church .
, , React Dependency Injection, - . Vue inject provide. .
, , . ,
NestJS .
InversifyJS . TypeScript, , , JavaScript. , .

Typescript, Inversify. , :
inject (TYPES.Weapon) katana: Weapon. , , TYPES.Weapon Weapon? — .
, , , TypeScript ( Flow ) , inject dependency injection runtime, .
« »? Weapon , , TypeScript , . TypeScript , first-class citizen JavaScript, . , , runtime , katana Weapon. .
- C++, , , RTTI: run-time type information, , . C# Java reflection, . TypeScript, « », , RTTI.
. . Vue Vue 3 TypeScript, , Vue TypeScript , Microsoft: « , TypeScript, ?» , Vue, : props, this. , props , this, . TypeScript , . .
Microsoft , : Vue , Angular, . , TypeScript. React, , .
, . , Dart, mirrors, , Flutter. mirrors, , , .
Inversify, Babel-, , , , runtime-, , .
: . . , , , . , V8 .
V8 , . , , V8, , , . , V8 , TypeScript.
. , , .
#3: «» , «»
«» «» , , «» — , . , Vue, . - , - props' .
. typed-css-modules? : CSS, CSS Modules, .
typed-css-modules , , css-, .
12 , CSS- , . 11 12 undefined, CSS- , , , , undefined, .

Yeoman , , , . , , . Angular CLI, Blueprints (, Angular, GDG SPB , , ).

Anguar , , . .
, «» , «» — , . , «» — . , , , , , , .
, — . junior', , , , . , , React- .
, , , - ESLInt, - , , .
, , . ,
NestJS Sails.js .

, , , , , - -. Sails ORM, . Waterline — , . , Sails.js . blueprint , . , , .

Nest, — , . Dependency Injection, , middleweight .
. , , , , , : « - ?»
Angular, — , , dependency injection, , .
- Vue (, ), , Vue . Vue, - , — Nest. , , , , TypeScript.

:
, JavaScript. , , , , , .
— , , , , , : - . - , — .

Grafana, , — . , - , . speech recognition API Microsoft, , , 20 . , , , -.

: CI/CD. GitLab, , . GitLab, , JavaScript-friendly environment , , .
. , , … , -.

Blue/Green deployment: - , , . , , !
- JavaScript , , . , , , JavaScript GitHub. — , , , .
- JavaScript , ( , ). « , ». , . DI , « ?»
- , . TypeScript, Flow, Rizen — , runtime exception, , .
, — -, .
HolyJS, : HolyJS 24-25 . — , ( MobX) ( Chrome DevTools). — .