Asigurați-vă că codul JavaScript robust cu flux

JavaScript a fost întotdeauna un limbaj de programare semnificativ, fiind singurul limbaj care rulează în mod sigur în browser. Tendințele recente în dezvoltarea front-end-ului, precum și dezvoltarea back-end bazată pe Node.js au împins scara și complexitatea aplicațiilor JavaScript. 

Aplicațiile mari dezvoltate de echipele mari pot beneficia de verificarea tipului static, la care lipsesc JavaScript de la vanilla. Flow a fost dezvoltat de Facebook pentru a aborda această problemă. Acesta este un controler de tip static care se integrează în procesul de dezvoltare, captează o mulțime de probleme devreme și vă ajută să vă mișcați repede.

Ce este fluxul?

Flow este un instrument care verifică codul JavaScript adnotat și detectează diferite probleme care, fără aceasta, ar fi descoperite numai la timpul de execuție (sau mai rău, nu descoperit și corupt datele dvs.). Iată un exemplu rapid.

// Funcția @flow getGreeting (nume: șir): string retur 'Hi, $ name';  const http = solicită ("http"); const constare greeting = getGreeting ("Gigi") const port = 8888 console.log ('Ascultă pe port $ port ...') http.createServer (request, reply) response.writeHead ":" text / simplu "); răspuns.write (salut); răspuns.end ();) asculta (port);

Flow vs TypeScript

Înainte de a vă scufunda în detaliile de tip "Flow", merită să o comparați cu alte alternative și în special cu TypeScript. TypeScript este un superset strict al JavaScript dezvoltat de Microsoft. Orice program JavaScript este, de asemenea, un program TypeScript. 

TypeScript adaugă adnotări de tip opțional și în ansamblu servește aceluiași scop ca fluxul. Cu toate acestea, există unele diferențe importante. TypeScript este un limbaj de programare separat care se compilează în JavaScript, în timp ce adnotările Flow trebuie eliminate pentru a reveni la JavaScript valid. 

TypeScript are un suport excelent pentru instrumente și IDE. Fluxul este de capturare (de exemplu, JetBrains WebStorm are integrare Flow nativă).

Cea mai importantă diferență filosofică este că fluxul pune accentul pe soliditate. Tipul 1.0 nu a capturat erori nulale; TipScript 2.0 cu controale nulă stricte măsurate până la Flux în această privință. Dar în alte aspecte, cum ar fi containerele generice sau tastarea, TypeScript este mai permisiv și permite diferite categorii de erori prin, nu formarea nominală).

TypeScript ca limbă proprie adaugă concepte și caracteristici lingvistice, cum ar fi clase, interfețe, indicatori de vizibilitate (public, privat, readonly) și decoratori. Aceste caracteristici facilitează înțelegerea și utilizarea pentru persoanele care vin din limbi orientate pe obiect obișnuit, cum ar fi C ++, Java și C #.

Instalare

Deoarece adnotările de flux nu sunt standard, JavaScript trebuie eliminat înainte de implementarea aplicației. Iată cum se instalează fluxurile și fluxurile de eliminare prin fire: fire add --dev flux-bin flux-elimina-tipuri

Puteți adăuga câteva scrieri în fișierul package.json pentru a automatiza procesul:

 "scripts": "build": "flow-remove-types src / -d lib /", "prepublish": "construirea firelor de fire" 

Ar trebui să executați scriptul prepublish înainte de a vă publica codul în registrul npm.

Pentru alte opțiuni de instalare (de exemplu, utilizând npm sau babel), consultați ghidul de instalare Flow.

Pentru a finaliza instalarea, tastați: fila de curgere a firelor init

Aceasta va crea fișierul .flowconfig necesar.

Sistem tip

Flow are două obiective importante: precizia și viteza. Sistemul de tip a fost conceput pentru a sprijini aceste obiective.

Precizie

Precizia este realizată analizând modul în care codul interacționează cu tipurile, adnotate sau deduse. Orice nepotrivire ridică o eroare de tip. Tipurile adnotate acceptă scrierea nominală, ceea ce înseamnă că două tipuri diferite, cu aceleași atribute, se deosebesc una de cealaltă și nu pot fi substituite. Tipul unei variabile este definit ca setul de valori de runtime pe care variabila le poate primi. 

Viteză

Fluxul este rapid datorită unei combinații de modularitate și procesare distribuită. Fișierele sunt analizate în paralel, iar rezultatele sunt îmbinate ulterior printr-o memorie partajată eficientă pentru a realiza o verificare completă a tipului de programe.

Tipuri acceptate

Flow suportă multe tipuri. Pe lângă tipurile primitive, suportă și următoarele:

  • Obiect
  • mulțime
  • Orice
  • Poate
  • Variabil
  • tuplu
  • Clasă
  • Interfață
  • Generic

Adnotări de tip

Debit vă permite să declarați tipuri, precum și să restricționați variabilele și parametrii la valorile selectate:

tip Two2Four = 2 | 3 | 4 funcții doubleIt (număr: Two2Four) return numărul * 2 console.log (doubleIt (3)) Ieșire: 6 

Dacă depășiți intervalul valid, veți primi o eroare:

console.log (doubleIt (3)) Ieșire: Eroare: src / main.js: 30 30: console.log (doubleIt (5)) // eroare ^ număr. Acest tip este incompatibil cu tipul de paramă așteptat de 24: funcția doubleIt (număr: Two2Four) ^^^^^^^ număr enum S-a găsit o eroare 

De asemenea, puteți defini tipuri complexe, inclusiv subtipuri. În următorul exemplu de cod, tipul Warrior este un subtip de Persoană. Aceasta înseamnă că este OK să returnați un Războinic ca Persoană din luptă() funcţie. Cu toate acestea, returnarea null este interzisă.

(nume: șir, vârstă: număr, putere: număr lăsați redWolf: Warrior = name: "Wolf", varsta: 24, puterea: 10 (w1: strength w2. strength return w1 if (w1: strength = w2. strength) return w1 w2.sharpness> w1.strength) return w2 return null Ieșire: a găsit 1 eroare $ flux Eroare: src / main.js: 47 47: return null ^^^^ null. Acest tip este incompatibil cu tipul de retur așteptat de 39: lupta funcțională (w1: Warrior, w2: Warrior): Persoana ^^^^^^ obiect găsit 1 eroare 

Pentru ao rezolva, să-i întoarcem pe cel mai tânăr războinic dacă ambii războinici au aceeași putere:

(W1: Warrior, w2: Warrior): Persoana if (w1.altitude> w2.strength) retur w1 daca (w2.sharpness> w1.strength) return w2 retur (w1.age < w2.age ? w1 : w2)  let winner = fight(redWolf, skullCrusher) console.log(winner.name) Output: Skull Crusher 

Debitul permite un control mai precis prin extensie de clasă, invarianță, co-varianță și contra-varianță. Consultați documentația Flow privind varianța.

configurație

Flow utilizează fișierul de configurare .flowconfig în directorul rădăcină al proiectelor dvs. Acest fișier conține mai multe secțiuni care vă permit să configurați ce fișiere trebuie să verifice Flow și multe aspecte ale funcționării acestuia. 

Include

[include] secțiunea controlează directoarele și fișierele care trebuie verificate. Directorul rădăcină este întotdeauna inclus în mod implicit. Căile din [include] secțiunile sunt relative. O singură stea este o carte de salvare pentru orice nume de fișier, extensie sau nume de director. Două stele sunt o carte sălbatică pentru orice adâncime a directorului. Iată o mostră [include] secțiune:

[include] ... /externalFile.js ... / externalDir / ... /otherProject/*.js ... / otherProject / ** / coolStuff /

Ignora

[ignora] secțiunea este completarea [include]. Fișierele și directoarele pe care le specificați aici nu vor fi verificate în funcție de flux. În mod ciudat, utilizează o altă sintaxă (expresii regulate OCaml) și necesită căi absolute. Schimbarea acestora se face pe foaia de parcurs a echipei Flow.

Până atunci, rețineți că secțiunea include este prelucrată mai întâi, urmată de secțiunea ignorată. Dacă includeți și ignorați același director și / sau fișier, acesta va fi ignorat. Pentru a aborda problema cu calea absolută, este comună prefixarea fiecărei linii cu .*. Dacă doriți să ignorați directoarele sau fișierele sub rădăcină, puteți utiliza  substituent în loc de .*. Iată o mostră [ignora] secțiune:

[ignore]. * / __ teste __ /. *. * / src / \ (foo \ | bar \) /.*. *. \ ignore \ .js /ignore_me.js

libs

Orice aplicație JavaScript non-trivială utilizează o mulțime de biblioteci terțe părți. Fluxul poate verifica modul în care aplicația dvs. folosește aceste biblioteci dacă furnizați fișiere libdef speciale care conțin informații de tip despre aceste biblioteci. 

Fluxul scanează automat subdirectul "flowed-typed" al proiectului dvs. pentru fișierele libdef, dar puteți furniza și calea fișierelor libdef în secțiunea [libs]. Acest lucru este util dacă mențineți un depozit central al fișierelor libdef utilizate de mai multe proiecte.

Importul definițiilor de tip existente și crearea propriilor dvs. dacă biblioteca țintă nu oferă propriile definiții de tip este destul de simplă. Vedea:

  • Documentație flux: Definiții bibliotecă
  • Documentație flux: Crearea definițiilor bibliotecii
  • GitHub: Importarea și utilizarea definițiilor bibliotecii

Lints

Fluxul are mai multe reguli de lut pe care le puteți controla și puteți determina cum să le tratați. Puteți configura regulile din linia de comandă, în comentariile codului sau în [lints] din fișierul dvs. de configurare. Voi discuta despre lustruire în secțiunea următoare, dar aici este cum să îl configurați utilizând [lints] secțiune:

[lints] all = avertizează untyped-type-import = eroare sketchy-null-bool = off

Opțiuni

[Opțiuni] secțiunea este locul unde puteți să îi spuneți lui Flow cum să se comporte într-o varietate de cazuri care nu merită o secțiune proprie, astfel încât acestea sunt grupate împreună.

Există prea multe opțiuni pentru a le lista pe toate aici. Unele dintre cele mai interesante sunt:

  • toate: setați la true pentru a verifica toate fișierele, nu doar pentru cele cu @flow
  • emoticonuri: setați la true pentru a adăuga emojis la mesajele de stare
  • module.use_strict: setați la true dacă utilizați un transpilator care adaugă "utilizarea strictă";
  • suppress_comment: un regex care definește un comentariu pentru a suprima orice eroare de flux pe următoarea linie (util pentru codul în curs de desfășurare)

Consultați toate opțiunile din Ghidul flux pentru configurarea opțiunilor.

Versiune

Flow și formatul fișierului său de configurare evoluează. [versiune] vă permite să specificați ce versiune de Flux este creată pentru a evita erorile confuze.

Dacă versiunea Flow nu se potrivește cu versiunea configurată, Flow va afișa un mesaj de eroare.

Iată câteva moduri de a specifica versiunile acceptate:

[versiune] 0.22.0 [versiune]> = 0.13.0 <0.14.0 [version] ^1.2.3 

Versiunea caret păstrează fixată prima componentă non-zero a versiunii. Asa de ^ 1.2.3 se extinde la intervalul> = 1.2.3 < 2.0.0, and ^ 0.4.5 se extinde la intervalul = = 0.4.5 < 0.5.0.

Utilizarea fluxului de la linia de comandă

Flow este un program client-server. Un server Flow trebuie să ruleze și clientul se conectează la el (sau îl pornește dacă nu rulează). FLI-ul Flow are multe comenzi și opțiuni care sunt utile în scopuri de întreținere și introspecție, precum și pentru configurația temporară care depășește configurația din .flowconfig.

Tastare flux - ajutor afișează toate comenzile și opțiunile. Pentru a obține ajutor pentru o anumită comandă, tastați curgere --Ajutor. De exemplu:

$ flow ast --help Utilizare: flux ast [OPTION] ... [FILE] de ex. flux ast foo.js sau flux ast < foo.js --from Specify client (for use by editor plugins) --help This list of options --pretty Pretty-print JSON output --tokens Include a list of syntax tokens in the output --type Type of input file (js or json) 

Comenzile importante sunt:

  • init: generați un fișier .flowconfig gol
  • Verifica: efectuați un control complet al fluxului și tipăriți rezultatele 
  • ls: afișează fișierele vizibile pentru Flow
  • stare (implicit): afișați erorile de flux actuale de la serverul Flow
  • sugera: sugerați tipuri pentru fișierul țintă

Linting With Flow

Flow are un cadru de lustruire care poate fi configurat prin fișierul .flowconfig așa cum ați văzut mai devreme, prin argumentele liniei de comandă sau în fișierele de cod care utilizează comentariile fluxului. Toate metodele de configurare constau dintr-o listă de perechi cheie-valoare unde cheia este o regulă și valoarea este severitatea. 

reguli

Există în prezent trei reguli: toate, importate de tip untyped, și sketchy-null. Regula "Toate" este într-adevăr manevrarea implicită pentru orice eroare care nu are o regulă mai specifică. Regula de import "tip untyped-type" este invocată atunci când importați un tip dintr-un fișier unic. Regula "sketchy-null" este invocată atunci când faceți existența verificați o valoare care poate fi falsă sau nulă / nedefinită. Există reguli mai granulare pentru:

  • schițate-nul-bool
  • schițate-nul-număr
  • schematizate-null-string
  • schematizate-nul-mixt

Niveluri de severitate

Există, de asemenea, trei niveluri de severitate: oprit, avertizare și eroare. După cum vă puteți imagina, opțiunea "off" ignoră verificarea de tip, "avertizează" produce avertismente, care nu determină ieșirea de tip și nu se afișează implicit în ieșirea CLI (le puteți vedea cu --includ avertismente), iar "eroarea" este tratată la fel ca erorile de flux și determină ieșirea de tip pentru a afișa un mesaj de eroare.

Linting cu argumente de linie de comandă

Folosește --lints linia de comandă pentru a specifica mai multe reguli de scame. De exemplu:

flow -lints "toate = avertizează, untyped-type-import = eroare, sketchy-null-bool = off"

Linting With Flowlint Comentarii

Există trei tipuri de comentarii: fluxlint, fluxlint-line și flowlint-next-line.

Comentariul "flowlint" aplică un set de reguli într-un bloc până când este suprascris de un comentariu corespunzător:

tipul de import // flowlint untyped-type-import: off Foo, Bar, Baz, // flowlint untyped-type-import: error din './untyped.js'; 

Dacă nu există niciun comentariu corespunzător, setările se aplică doar până la sfârșitul fișierului.

"Linia de scurgere" se aplică doar liniei curente:  

funcția (x:? booleană) if (x) // fluxlint-line sketchy-null-bool: oprit ... altceva ... 

"Linia de scurgere-următoarea linie" se aplică liniei care urmează comentariului:

functie (x:? boolean) // flowlint-urmatoarea linie sketchy-null-bool: off daca (x) ... altceva ... 

Concluzie

Proiectele mari JavaScript dezvoltate de echipe mari pot beneficia foarte mult de verificarea tipului static. Există mai multe soluții pentru introducerea verificării tipului static într-o bază de date JavaScript. 

JavaScript continuă să crească într-o varietate de moduri pe web. Nu este fără curbele sale de învățare și există o mulțime de cadre și biblioteci care să vă țină ocupați, după cum puteți vedea. Dacă sunteți în căutarea unor resurse suplimentare pentru a studia sau a utiliza în munca dvs., verificați ce avem la dispoziție pe piața Envato.

Facebook Flow este o soluție recentă și robustă, cu o acoperire excelentă, unelte și documentație. Încearcă-o dacă ai o bază de cod JavaScript mare.

Cod