Robustes JavaScript: Jagd nach einem Mythos

JavaScript wird oft als die „beliebteste Sprache“ bezeichnet, aber es scheint, dass niemand von der JS-Entwicklung als der „sichersten“ spricht, und die Anzahl der lauernden Probleme im Ökosystem ist groß. Wie kann man sie effektiv umgehen?



Ilya Klimov dachte darüber nach, als der Fehler (buchstäblich) sehr teuer war - und hielt schließlich eine Präsentation über HolyJS. Und da sich die Kritiken des Publikums als ausgezeichnet erwiesen haben, haben wir jetzt eine Textversion dieses Berichts für Habr vorbereitet. Unter dem Schnitt - sowohl Text als auch Video.



Hallo an alle. Mein Name ist Ilya Klimov, ich komme aus Kharkov, Ukraine. Ich habe mein eigenes kleines Outsourcing-Unternehmen mit bis zu zehn Mitarbeitern. Wir machen alles, wofür Geld bezahlt wird ... in dem Sinne, dass wir in allen Sektoren in JavaScript programmieren. Wenn ich heute über zuverlässiges JavaScript spreche, möchte ich irgendwo im letzten Jahr meine Best Practices teilen, da mich dieses Thema ziemlich ernsthaft und ernsthaft zu stören begann.

Diejenigen, die im Outsourcing arbeiten, werden den Inhalt der folgenden Folie verstehen:



Alles, worüber wir sprechen werden, hat natürlich nichts mit der Realität zu tun. Wie man in South Park sagt, sind alle Charaktere verwöhnt und elend. Natürlich wurden die Orte, an denen der Verdacht eines Verstoßes gegen die NDA besteht, mit Vertretern der Kunden vereinbart.

Nichts hat meine Gedanken über Zuverlässigkeit und dergleichen als Grundlage meines eigenen Unternehmens beeinflusst. Wenn Sie eine eigene Firma gründen, stellt sich plötzlich heraus, dass Sie ein sehr cooler Programmierer sein können, Sie können sehr coole Leute haben, aber manchmal passieren unglaubliche Dinge, ein paar unmögliche und völlig verrückte.

Ich habe ein Ninja JavaScript-Bildungsprojekt. Manchmal mache ich Versprechungen. Manchmal folge ich ihnen sogar. Ich habe 2017 im Rahmen eines Bildungsprojekts versprochen, ein Video über Kubernetes aufzunehmen. Mir wurde klar, dass ich dieses Versprechen gegeben hatte und es wäre schön, es am 31. Dezember zu erfüllen. Und ich habe mich hingesetzt, um aufzunehmen ( hier ist das Ergebnis ).

Da ich gerne Videos aufnehme, die so realitätsnah wie möglich sind, habe ich Beispiele eines realen Projekts genutzt. Infolgedessen habe ich im Demo-Cluster etwas bereitgestellt, das echte Aufträge aus der realen Produktion entgegengenommen und in eine separate Kubernetes-Datenbank in meinem Demo-Cluster gestellt hat.

Da es der 31. Dezember war, ging ein Teil der Bestellungen verloren. Aus Gründen der Saisonalität abgeschrieben: Alle gingen Tee trinken. Als der Kunde zwischen dem 12. und 13. Januar aufwachte, beliefen sich die Gesamtkosten des Videos auf etwa 500.000 US-Dollar. Ich hatte noch keine so teure Produktion.



Beispiel Nummer zwei: Ein weiterer Kubernetes-Cluster. Neuartige Ökosysteminfrastruktur als Code: Alles, was durch Code und Konfigurationen beschrieben werden kann, zuckt Kubernetes programmgesteuert mit JavaScript-Shells und so weiter. Cool, jeder mag es. Eine kleine Änderung im Bereitstellungsverfahren, und es kommt eine Zeit, in der Sie einen neuen Cluster bereitstellen müssen. Folgende Situation entsteht:

const config = { // … mysql: process.env.MYSQL_URI || 'mysql://localhost:3306/foo' // ... } 

Viele von Ihnen haben wahrscheinlich auch diese Codezeile in Ihren Konfigurationen. Das heißt, wir nehmen die Konfiguration aus der MySQL-Variablen oder nehmen die lokale Datenbank.

Aufgrund eines Tippfehlers im Bereitstellungssystem stellte sich heraus, dass das System erneut als Produktion konfiguriert wurde, die MySQL-Datenbank jedoch eine lokale Testdatenbank für Tests verwendete. Diesmal wurde weniger Geld ausgegeben - nur 300.000 US-Dollar. Glücklicherweise war dies nicht meine Firma, sondern der Ort, an dem ich als engagierter Berater arbeitete.



Sie könnten denken, dass all dies Sie als Front-End nicht betrifft, weil ich über DevOps gesprochen habe (übrigens bewundere ich den Namen der DevOops- Konferenz, er beschreibt die Essenz perfekt). Aber ich werde Ihnen von einer anderen Situation erzählen.

Es gibt ein System zur Bekämpfung von Veterinärepidemien in Äthiopien, das unter der Schirmherrschaft der Vereinten Nationen entwickelt wurde. Es enthält eines der Schnittstellenelemente, wenn sie zu einer Person kommen, und sie gibt die Koordinaten manuell ein: wann und wo es Ausbrüche einer bestimmten Krankheit gab.

Es kommt zu einem Ausbruch einer normalen Maul- und Klauenseuche (ich bin nicht stark bei Kuhkrankheiten), und in Eile drückt der Bediener versehentlich zweimal auf die Schaltfläche „Hinzufügen“ und lässt die Felder leer. Da wir JavaScript haben und JavaScript und Typen sehr gut sind, führen leere Breiten- und Längengrade freudig zu Nullkoordinaten.

Nein, wir haben den Arzt nicht weit zum Meer geschickt, aber es stellte sich heraus, dass dies alles zuvor unter dem Gesichtspunkt der Clusterbildung berechnet wurde, um es auf der Karte anzuzeigen, Berichte zu erstellen, Analysen durchzuführen und die Platzierung von Personen im Backend zu analysieren. Wir versuchen, die Ausbruchspunkte zu vereinen.

Infolgedessen ist das System tagsüber gelähmt, da das Backend versucht, den Cluster unter Einbeziehung dieses Punkts zu berechnen. Alle Daten werden irrelevant, und völlig unverantwortliche Bestellungen aus der Serie „400 Kilometer fahren“ gehen an Ärzte. 400 Kilometer in Äthiopien sind ein zweifelhaftes Vergnügen.

Die Gesamtverlustschätzung liegt bei etwa einer Million Dollar. In dem Bericht über diese Situation wurde geschrieben: "Wir waren das Opfer einer unglücklichen Reihe von Umständen." Aber wir wissen, dass der Punkt JavaScript ist!



Und das letzte Beispiel. Obwohl diese Geschichte schon lange her ist, kann ich das Unternehmen leider immer noch nicht nennen. Aber dies ist ein Unternehmen, das eine eigene Fluggesellschaft, eigene Hotels usw. hat. Sie arbeitet sehr interaktiv mit Unternehmen, dh sie bietet ihnen eine separate Schnittstelle für die Buchung von Tickets und so weiter.

Nach einem absurden Unfall kommt eine Bestellung für die Buchung von Tickets von New York nach Los Angeles in Höhe von 999.999 Stück an. Das System des Unternehmens kaufte glücklich alle Flüge seiner eigenen Fluggesellschaft, stellte fest, dass nicht genügend Sitzplätze vorhanden waren, und schickte die Daten an das internationale Buchungssystem, um den Mangel auszugleichen. Das internationale Buchungssystem, das eine Anfrage nach ungefähr 950.000 Tickets sah, trennte diese Fluggesellschaft glücklich von ihrem System.

Da das Herunterfahren ein ungewöhnliches Ereignis ist, wurde das Problem innerhalb von sieben Minuten behoben. In diesen sieben Minuten betrugen die Kosten für die zu zahlenden Geldbußen jedoch nur 100.000 US-Dollar.



Glücklicherweise geschah dies alles in mehr als einem Jahr. Aber diese Fälle haben mich dazu gebracht, über Zuverlässigkeitsprobleme nachzudenken und zwei originale russische Fragen zu stellen: Wer ist schuld und was soll ich dagegen tun?

Warum das passiert: die Jugend des Ökosystems


Wenn Sie viele Geschichten analysieren, werden Sie feststellen, dass es mehr Geschichten über ähnliche Probleme mit JavaScript gibt als mit einer anderen Programmiersprache. Dies ist nicht mein subjektiver Eindruck, sondern das Ergebnis der intelligenten Analyse von Nachrichten auf Hacker News. Einerseits ist dies eine Hipster- und subjektive Quelle, andererseits ist es ziemlich schwierig, eine vernünftige Quelle durch Fakap im Programmierbereich zu finden.

Außerdem habe ich vor einem Jahr einen Wettbewerb veranstaltet, bei dem ich jeden Tag algorithmische Probleme lösen musste. Da ich gelangweilt war, löste ich sie in JavaScript mithilfe der funktionalen Programmierung. Ich habe eine völlig reine Funktion geschrieben, und im aktuellen Chrome hat sie 1197 Mal korrekt funktioniert und 3 Mal ein anderes Ergebnis erzielt. Es war nur ein kleiner Fehler im TurboFan-Optimierer, der gerade in das Haupt-Chrome aufgenommen wurde.

Natürlich wurde es behoben, aber Sie verstehen: Dies bedeutet zum Beispiel, dass wenn Ihre Komponententests einmal bestanden wurden, dies überhaupt nicht bedeutet, dass sie im System funktionieren. Das heißt, wir haben Code ungefähr 1197 Mal ausgeführt, dann kam der Optimierer und sagte: „Wow! Heiße Funktion! Lass es uns optimieren. " Und im Optimierungsprozess zum falschen Ergebnis geführt.

Mit anderen Worten, wir können die Jugend des Ökosystems als einen der ersten Gründe dafür bezeichnen. JavaScript ist eine relativ junge Branche, gerade im Bereich der ernsthaften Programmierung, in den Fällen, in denen sich Millionen drehen und die Kosten eines Fehlers mit fünf bis sechs Zeichen gemessen werden.

JavaScript wurde lange Zeit als Spielzeug wahrgenommen. Aus diesem Grund (nicht weil wir es nicht ernst nehmen) haben wir immer noch Probleme mit dem Mangel an Werkzeugen.

Um diesen Grund zu behandeln, der das Grundprinzip von allem ist, worüber ich heute sprechen werde, habe ich versucht, die Zuverlässigkeitsregeln zu formulieren, die ich in meinem Unternehmen auferlegen oder als Berater an andere übertragen könnte. Wie das Sprichwort sagt: "Regel Nummer eins ist, nicht über Zuverlässigkeit zu sprechen." Aber im Ernst, dann ...

Zuverlässigkeitsregel Nr. 1: Alles, was automatisiert werden kann, muss automatisiert werden


Einschließlich übrigens und Rechtschreibprüfung:

Versteckter Text
Zuverlässigkeitsregel Nr. 1: Alles, was automatisiert werden kann, muss automatisiert werden

Alles beginnt mit den einfachsten Dingen. Es scheint, dass jeder schon lange Prettier schreibt. Aber erst im Jahr 2018 hat dieses Ding, das wir alle verwenden, gut und solide gelernt, mit git add -p zu arbeiten, wenn wir teilweise Dateien zum git-Repository hinzufügen, und wir möchten den Code beispielsweise gut formatieren, bevor wir ihn an das Haupt-Repository senden. Das bekannte Realinstaged-Dienstprogramm, mit dem Sie nur die geänderten Dateien überprüfen können, hat genau das gleiche Problem.



Spielen Sie weiterhin Captain Evidence: ESLint. Ich werde nicht fragen, wer es hier benutzt, weil es für das gesamte Publikum keinen Sinn macht, die Hände zu heben (nun, ich hoffe es und ich möchte nicht enttäuscht werden). Heben Sie besser Ihre Hände, die ihre eigenen benutzerdefinierten Regeln in ESLint haben.

Solche Regeln sind eine der sehr mächtigen Möglichkeiten, um das Durcheinander zu automatisieren, das in Projekten auftritt, in denen Leute auf der Junior-Ebene schreiben und dergleichen.

Wir alle wollen ein gewisses Maß an Isolation, aber früher oder später entsteht eine Situation: „Sehen Sie, dieser Helfer Vasya hat irgendwo im Verzeichnis seiner Komponente sehr nahe verkauft. Ich werde es nicht gemeinsam herausnehmen, dann werde ich es tun. “ Das Zauberwort ist "später". Dies führt dazu, dass im Projekt keine vertikalen Abhängigkeiten auftreten (wenn die oberen Elemente die unteren verbinden, klettern die unteren niemals hinter die oberen), sondern Komponente A von Komponente B abhängt, die sich in einem völlig anderen Zweig befindet. Infolgedessen kann Komponente A nicht so leicht zu anderen Komponenten transportiert werden.

Übrigens, ich drücke der Alfa-Bank meinen Respekt aus, sie haben eine sehr gut und schön geschriebene Bibliothek von Komponenten auf React. Es ist eine Freude, sie genau im Hinblick auf die Gestaltung der Qualität des Codes zu verwenden.

Mit der banalen ESLint-Regel, mit der verfolgt wird, woher Sie Entitäten importieren, können Sie die Qualität des Codes erheblich verbessern und das mentale Modell während der Codeüberprüfung speichern.

Ich bin schon aus der Sicht der Welt des Frontends. Kürzlich hat in der Region Kharkov ein großes und seriöses Unternehmen, PricewaterhouseCoopers, eine Studie abgeschlossen, und das Durchschnittsalter des Front-End-Anbieters liegt bei 24 bis 25 Jahren. Es fällt mir schon schwer, über all das nachzudenken. Ich möchte mich bei einer Überprüfung der Pull-Anfrage auf die Geschäftslogik konzentrieren. Daher freue ich mich, ESLint-Regeln zu schreiben, um nicht über solche Dinge nachzudenken.

Es scheint, dass Sie die üblichen Regeln dafür anpassen können, aber die Realität stört normalerweise viel mehr, da sich herausstellt, dass einige Redux-Selektoren von der Reaktionskomponente benötigt werden (sie ist leider noch am Leben). Und diese Selektoren befinden sich irgendwo in einer völlig anderen Hierarchie, also "../../../ ..".

Oder, noch schlimmer, der Webpack-Alias, der etwa 20% aller anderen Tools zerstört, weil nicht jeder versteht, wie man damit arbeitet. Zum Beispiel mein geliebter Flow.

Überlegen Sie sich daher beim nächsten Mal, bevor Sie einen Junior anknurren möchten (und der Programmierer hat so einen Lieblingsbeschäftigung), ob Sie dies irgendwie automatisieren können, um in Zukunft keine Fehler zu machen. In einer idealen Welt werden Sie natürlich Anweisungen schreiben, die sowieso niemand lesen wird. Hier sind die Redner von HolyJS - talentierte Spezialisten mit großer Erfahrung, aber als vorgeschlagen wurde, bei einer internen Kundgebung Anweisungen für die Redner zu erstellen, sagten sie: "Ja, sie werden es nicht lesen." Und das sind die Leute, von denen man ein Beispiel nehmen kann!

Der letzte Banalismus, und weiter zu Zinn. Dies sind alle Tools zum Ausführen von Pre-Commit-Hooks. Wir verwenden Husky , und ich konnte nicht anders, als dieses schöne Husky-Foto einzufügen, aber Sie können etwas anderes verwenden.



Wenn Sie denken, dass dies alles sehr einfach ist - wie sie sagen, halten Sie mein Bier, werden wir bald herausfinden, dass alles komplizierter ist als Sie denken. Noch ein paar Punkte:

Tippen


Wenn Sie kein TypeScript schreiben, sollten Sie darüber nachdenken. Ich mag TypeScript nicht, ich bin traditionell ein High-Flow-Flow, aber wir werden später darüber sprechen, aber hier werde ich ab der Phase die Mainstream-Lösung mit Ekel bewerben.

Warum so? Das TC39-Programmkomitee hatte kürzlich eine sehr große Diskussion darüber, wohin die Sprache im Allgemeinen geht. Eine sehr lustige Schlussfolgerung, zu der sie gekommen sind: In TC39 gibt es immer einen „Schwan, Krebs und Hecht“, die ihre Zunge in verschiedene Richtungen ziehen, aber es gibt eine Sache, die jeder will und immer Leistung ist.

TC39 gab in einer internen Diskussion informell diese Tirade heraus: "Wir werden JavaScript immer so gestalten, dass es produktiv bleibt, und diejenigen, die es nicht mögen, werden eine Sprache verwenden, die in JavaScript kompiliert wird."

TypeScript ist eine ziemlich gute Alternative zum Ökosystem für Erwachsene. Ich kann nur meine Liebe zu GraphQL erwähnen. Es ist wirklich gut, leider wird es niemand bei einer Vielzahl bestehender Projekte umsetzen lassen, an denen wir bereits arbeiten müssen.



Auf der Konferenz gab es bereits Berichte über GraphQL, daher gibt es nur einen Strich speziell für die Frage der Zuverlässigkeit: Wenn Sie beispielsweise Express GraphQL verwenden, können Sie jedes Mal zusätzlich zu einem bestimmten Resolver bestimmte Validatoren aufhängen, mit denen Sie die Wertanforderungen im Vergleich zu verschärfen können Standardtypen von GraphQL.

Zum Beispiel möchte ich, dass der Überweisungsbetrag zwischen zwei Vertretern einiger Banken positiv ist. Denn spätestens gestern gab das Popup in meinem Internet-Banking freudig bekannt, dass ich -2 ungelesene Nachrichten von der Bank hatte. Und es ist wie eine führende Bank in meinem Land.

Was diese Validatoren betrifft, die zusätzliche Genauigkeit auferlegen: Ihre Verwendung ist eine gute und fundierte Idee. Verwenden Sie sie nur nicht wie beispielsweise von GraphQL vorgeschlagen. Sie fühlen sich GraphQL als Plattform sehr verbunden. Gleichzeitig wird die von Ihnen durchgeführte Validierung an zwei Stellen gleichzeitig benötigt: im Frontend, bevor wir Daten senden und empfangen, und im Backend.

Ich muss dem Kunden regelmäßig erklären, warum wir JavaScript und nicht die X-Sprache als Backend verwendet haben. Außerdem ist die X-Sprache normalerweise eine Art PHP und nicht schön Go und dergleichen. Ich muss erklären, dass wir Code so effizient wie möglich wiederverwenden können, auch zwischen dem Client und dem Backend, da sie in derselben Programmiersprache geschrieben sind. Wie die Praxis zeigt, bleibt diese These leider oft nur eine Phrase auf der Konferenz und findet im wirklichen Leben keine Verkörperung.

Verträge


Ich habe bereits über die Jugend des Ökosystems gesprochen. Die Vertragsprogrammierung besteht seit über 25 Jahren als primärer Ansatz. Wenn Sie in TypeScript schreiben, nehmen Sie io-ts, wenn Sie wie ich in Flow schreiben, nehmen Sie typed-contract, und Sie erhalten eine sehr wichtige Sache: die Fähigkeit, Laufzeitverträge zu beschreiben, aus denen statische Typen abgeleitet werden können.



Es gibt nichts Schlimmeres für einen Programmierer, als mehr als eine Quelle der Wahrheit zu haben. Ich kenne Leute, die fünfstellige Beträge in Dollar verloren haben, einfach weil ihr Typ in einer Sprache mit statischer Typisierung (sie haben TypeScript verwendet - natürlich ist dies nur ein Zufall) und dem Laufzeit-Typ (es scheint tcomb verwendet zu haben) beschrieben ist. etwas anders.

Daher wurde der Fehler nicht in der Kompilierungszeit abgefangen, nur weil warum sollte er überprüft werden? Es gab keine Komponententests dafür, da wir von einem statischen Typisierer überprüft wurden. Es macht keinen Sinn, Dinge zu testen, die von der darunter liegenden Ebene überprüft wurden. Jeder erinnert sich an die Testhierarchie.

Aufgrund der Tatsache, dass die Synchronisation zwischen diesen beiden Verträgen im Laufe der Zeit unterbrochen wurde, wurde eines Tages eine falsche Übertragung an die Adresse vorgenommen, die an die falsche Adresse ging. Da es sich um eine Kryptowährung handelte, ist es unmöglich, eine Transaktion etwas mehr als im Prinzip zurückzusetzen. Niemand wird dir wieder die Luft geben. Daher sind Verträge und Interaktionen in der Vertragsprogrammierung die ersten Dinge, mit denen Sie morgen beginnen sollten.

Warum das passiert: Isolation


Das nächste Problem ist die Isolation. Es ist vielfältig und vielfältig. Als ich für ein Hotel- und Flugreiseunternehmen arbeitete, hatten sie eine App auf Angular 1. Das ist lange her, also ist es entschuldbar. Ein Team von 80 Personen arbeitete an dieser Anwendung. Alles wurde in Tests abgedeckt. Alles war in Ordnung, bis ich eines schönen Tages mein Feature machte, es nicht einfrierte und feststellte, dass ich beim Testen absolut unglaubliche Stellen auf dem System gebrochen hatte, die ich nicht einmal berührt hatte.

Es stellte sich heraus, dass ich Probleme mit der Kreativität habe. Es stellte sich heraus, dass ich den Dienst versehentlich genauso aufgerufen habe wie einen anderen Dienst, der im System vorhanden war. Da es sich um Angular 1 handelte und das dortige Dienstsystem nicht streng, sondern streng typisiert war, begann Angular ganz ruhig, meinen Dienst an völlig andere Orte zu verschieben, und ironischerweise stimmten einige Methoden bei der Benennung überein.

Dies war natürlich kein Zufall: Sie verstehen, dass zwei Dienste, die denselben Namen haben, wahrscheinlich dasselbe tun, plus oder minus. Es war ein Service im Zusammenhang mit der Berechnung von Rabatten. Nur ein Modul war mit der Berechnung von Rabatten für Firmenkunden beschäftigt, und das zweite Modul mit meinem Namen war mit der Berechnung von Rabatten auf Aktien verbunden.

Wenn die Anwendung von 80 Personen gesägt wird, bedeutet dies natürlich, dass sie groß ist. Die Code-Aufteilung wurde in der Anwendung implementiert. Dies bedeutet, dass die Reihenfolge des Verbindens der Module direkt von der Reise des Benutzers auf der Site abhängt. Um es noch interessanter zu machen, kam es vor, dass kein einziger End-to-End-Test, der das Verhalten und den Durchgang eines Benutzers durch eine Site, dh ein bestimmtes Geschäftsszenario, testete, diesen Fehler abfing. Weil es so aussieht, als müsste niemand jemals beide Rabattmodule gleichzeitig kontaktieren. Dies hat zwar die Arbeit der Site-Administratoren völlig gelähmt, aber mit wem es nicht passiert.

Das Problem der Isolation wird sehr gut durch das Logo eines der Projekte veranschaulicht, die dieses Problem teilweise lösen. Das ist Lerna.



Lerna ist ein hervorragendes Tool zum Verwalten mehrerer npm-Pakete in einem Repository. Wenn Sie einen Hammer in der Hand haben, wird alles verdächtig wie ein Nagel. Wenn Sie ein Unix-ähnliches System mit der richtigen Philosophie haben, wird alles verdächtig wie eine Datei. Jeder weiß, dass auf Unix-Systemen alles eine Datei ist. Es gibt Systeme, in denen es in höchstem Maße gebracht wird (ich hätte fast "bis zur Absurdität" gesagt), wie Plan 9 .

Ich kenne Unternehmen, die sich auf die Zuverlässigkeit einer riesigen Anwendung eingestellt haben und eine einfache Idee haben: Alles ist ein Paket.



Wenn Sie ein Funktionselement, sei es eine Komponente oder etwas anderes, in einem separaten Paket entfernen, stellen Sie automatisch eine Isolationsschicht bereit. Nur weil Sie normalerweise nicht von einem Paket aus ein anderes erreichen können. Und auch, weil das System für die Arbeit mit Paketen, die in einem Mono-Repository über npm-link oder Yarn Workspaces gesammelt werden, so schrecklich und unvorhersehbar ist, was die interne Organisation betrifft, dass Sie nicht einmal auf einen Hack zurückgreifen und eine Verbindung herstellen können Datei durch "node_modules etwas", einfach weil verschiedene Leute alles in eine andere Struktur gehen. Dies hängt insbesondere von der Version von Yarn ab. Dort haben sie in einer der Versionen den Mechanismus, wie Yarn Workspaces die Arbeit mit Paketen organisiert, stillschweigend vollständig geändert.

Das zweite Beispiel für Isolation, um zu zeigen, dass das Problem vielfältig ist, ist das Paket, das ich jetzt überall verwenden möchte - dies ist cls-süchtig . Möglicherweise ist Ihnen ein anderes Paket bekannt, das dasselbe implementiert - dies ist Continuation-Local-Storage . Es löst ein sehr wichtiges Problem, auf das beispielsweise Entwickler in PHP beispielsweise nicht stoßen.

Es geht darum, jede spezifische Anfrage zu isolieren. In PHP haben wir im Durchschnitt in einem Krankenhaus alle Anfragen isoliert und interagieren nur dann zwischen ihnen, wenn Sie keine Perversionen wie Shared Memory verwenden. Wir können nicht, alles ist in Ordnung, friedlich, schön. Im Wesentlichen fügt cls-hooked dasselbe hinzu, sodass Sie Ausführungskontexte erstellen, lokale Variablen in diese einfügen und diese Kontexte dann vor allem automatisch zerstören können, damit sie Ihren Speicher nicht weiter belasten.

cls-hooked async_hooks, node.js , , . , .

, , node-.

#2: «»


, , . , JavaScript — , . grep-.

Was ist das? 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). — .

Source: https://habr.com/ru/post/de439612/


All Articles