En Liten JavaScript-Oppsett

0
13

Noen mennesker foretrekker å skrive JavaScript med å Reagere. For andre, det er Vue eller jQuery. For andre likevel, det er deres eget sett av verktøy eller en helt tomt dokument. Noen oppsett er minimal, noen gir deg mulighet til å få ting gjort raskt, og noen er gale kraftig, slik at du kan bygge komplekse og vedlikeholde programmer. Hvert oppsett har fordeler og ulemper, men positive vanligvis oppveier de negative når det kommer til populære rammeverkene bekreftet og sett gjennom av et aktivt fellesskap.

Reagere og Vue er kraftig JavaScript-rammeverk. Selvfølgelig er de — som er grunnen til at begge er trending så høy i total bruk. Men hva er det som gjør de, og andre rammeverk, så kraftig? Er det hastighet? Portabilitet til andre plattformer, for eksempel native stasjonære og mobile? Støtte av det store fellesskapet?

Suksessen av et utviklingsteam starter med en avtale. En avtale om hvordan ting er gjort. Uten en avtale, kode vil bli rotete, og programvaren bærekraftig ganske raskt, selv for relativt små prosjekter. Derfor, mange (om ikke de fleste) av kraften i en ramme som ligger innenfor denne avtalen. Evnen til å definere konvensjoner og felles mønstre som alle følger. At ideen gjelder for alle rammer, JavaScript eller ikke. Disse “reglene” er avgjørende for utviklingen og bringe lag vedlikehold i alle størrelser, reusability av koden, og evne til å dele arbeid med samfunnet i en form som alle vil forstå. Det er derfor vi kan web-søk for noen komponent/plugin som løser våre problemer heller enn å skrive noe på våre egne. Vi er avhengige av open-source alternativer, uansett hvilken ramme vi bruker.

Dessverre, det er ulemper med å rammer. Som Adrian Holovaty (en av Django skaperne) forklarer i sin tale, rammer har en tendens til å få store og oppsvulmet med funksjoner for en bestemt bruk tilfelle. Det kan være inkluderingen av et veldig god idé. Det kan også være et ønske om å gi en one-size-fits-all-løsning for alle behov. Det kan være å være populære. Uansett, det er ulemper med å rammer i lys av alle de upsides de har også.

I server-gjengitt verden, hvor vi jobber med innhold som er levert til nettleseren fra en server, denne “rammen misjon” er fylt med kompetanse, ideer og løsninger som folk dele med kolleger, venner, og andre. De har en tendens til å vedta konsekvent utvikling regler og håndheve dem i deres grupper eller bedrifter, snarere enn å stole på en forhåndsdefinert rammeverk. For en lang tid, er det blitt jQuery som har gjort det mulig å dele og gjenbruke kode på en global skala, med sitt plugins — men den tiden er falming som nye rammer inn i folden.

La oss ta en titt på noen kjernen poeng at alle framework — tilpasset eller ikke — bør vurdere avgjørende for å stimulere vedlikeholde og gjenbrukbare codebase.

Navnekonvensjoner

Noen vil kanskje si at navngiving er den vanskeligste delen av utviklingen. Enten det er å navngi JavaScript variabler, HTML-klasser, eller noen andre rekke ting, en navnekonvensjon har en stor innvirkning på hvordan vi jobber sammen, fordi det tilfører kontekst og mening til vår kode. Et godt eksempel på en navnekonvensjon er BEM, en CSS-metodikk som er opprettet av folk på Yandex og tatt i bruk av mange, mange front-enders. Den slags standardisering og konsistens kan hjelpe med å informere våre mål, som er å ha en standard konvensjonen for navngivning JavaScript-velgere.

Denne situasjonen kan virke kjent: du besøke et prosjekt etter et par måneder, og ser du noen atferd som skjer på siden — kanskje noe du ønsker å endre eller reparere. Men å finne kilden til at atferden kan være en vanskelig ting. Er det id-attributtet jeg skal søke på? Er det en av de klasser? Kanskje den data-attributtet for dette bestemt element?

Jeg tror du skjønner poenget. Hva er det som hjelper er å ha noen form av konvensjonen for å forenkle prosessen og gjøre alle jobber med samme navn. Og det spiller egentlig ingen rolle om vi kommer med klasser (f.eks. js-[name]) eller data attributter (f.eks. data-name=”[navn]”). Det som er viktig er at navnene svarer til de samme stil. Sikkert nok, noen rammeverket vil du møte vil håndheve en navnekonvensjon av noe slag som godt, enten det er Reagere, Vue, Bootstrap, Foundation, etc.

Omfang

En utbygger vil trolig slite med JavaScript omfang på enkelte punkt i tid, men vi er spesielt å fokusere på DOM omfang her. Uansett hva du gjør med JavaScript, og du bruker den til å påvirke noen DOM-element. Å begrense deler av koden til en DOM-element oppfordrer vedlikehold og gjør koden mer modulbasert. Komponentene i både Reagerer og Vue opererer på en lignende måte, selv om deres “komponent” – konsept er annerledes enn standard DOM. Likevel, tanken scopes koden til en DOM-element som er gjengitt av disse komponentene.

Mens vi er på emnet av DOM-manipulasjon, og referere til elementer innen rot-element av komponent er super nyttig fordi det hjelpe unngår konstant behov for å velge elementer. Reagere og Vue gjør dette ut av boksen på en svært god måte.

Lifecycle

I det siste, siden lifecycle var veldig grei: den nettleseren som er lagt til side , og leseren til venstre på siden. Opprette eller fjerne event lyttere, eller å gjøre koden kjøre til rett tid ble mye enklere, så ville du bare lage alt du trenger på belastning, og sjelden bry seg med å deaktivere koden din, siden nettleseren ville gjøre det for deg som standard.

I dag, livssyklus har en tendens til å være mye mer dynamisk, takket være statlig styring og måten vi foretrekker å manipulere endringer direkte til den DOM eller laste innholdet på sider med JavaScript. Dessverre, som vanligvis bringer noen problemer der du kanskje trenger å re-run deler av koden til visse tider.

Jeg kan ikke fortelle hvor mange ganger i mitt liv jeg har hatt til å spille rundt med kode for å få min event handlers å kjøre riktig etter re-skriving en del av DOM. Noen ganger er det mulig å løse dette med event-delegasjonen. Andre ganger, koden behandlere ikke kjøre i det hele tatt, eller kjøre flere ganger fordi de er plutselig festet to ganger.

En annen bruk tilfelle vil være behov for å opprette en forekomst av biblioteker etter at du har endret DOM, som “falske velger.”

I alle fall, livssyklus er viktig og begrense koden din til en DOM-element hjelper absolutt her også, siden du vet at koden brukes som element trenger å være re-run i tilfelle elementet er re-modellert.

Rammer gjør det samme med funksjoner som componentDidMount eller componentDidUpdate, som gir deg en enkel måte å kjøre koden nøyaktig når du trenger det.

Reusability

Kopiering av kode fra et annet sted og gjenbruk det er super vanlig. Som ikke har brukt et utdrag fra et tidligere prosjekt eller et svar fra StackOverflow, ikke sant? Folk engang oppfunnet tjenester som npm ment for én ting: å enkelt dele og gjenbruke kode. Det er ikke nødvendig å finne opp hjulet på nytt og dele koden med andre er noe som er praktisk, hendig, og ofte mer effektivt enn å spinne opp noe fra bunnen av.

Komponenter, enten det er Reagere, Vue, eller noen andre byggesteinen i et rammeverk som oppfordrer reusability ved å ha en wrapper rundt et stykke kode som serverer noen bestemt hensikt. En standardisert wrapper med en tvungen format. Jeg vil si dette er mer av en bivirkning av å ha noen base-vi kan bygge på, enn en bevisst innsats for reusability, som en hvilken som helst base vil alltid trenger noen standard format av en kode, kan den kjøre, på samme måte som programmeringsspråk har en syntaks vi trenger å følge… men det er en super praktisk og nyttig bieffekt, sikkert. Ved å kombinere dette fikk reusability med pakken ledere som Garn, og bundlers som webpack, kan vi plutselig få kode som er skrevet av mange utviklere rundt om i verden arbeider sammen i vår app med nesten ingen innsats.

Selv om ikke alle-koden er open-source og delbare, en felles struktur vil hjelpe folk i mindre grupper, slik at noen er i stand til å forstå det meste av koden er skrevet i team uten å konsultere dens forfatter.

DOM-manipulasjon med ytelse i tankene

Lesing og skriving til DOM er kostbart. Utviklerne av front-end rammer holde det i tankene, og forsøke å optimalisere så mye som mulig med stater, virtuelle DOM og andre metoder for å gjøre endringer til DOM når det trengs og der det trengs… og så skal vi. Mens vi er mer opptatt av server-gjengitt HTML, de fleste av koden ender opp med å lese eller å skrive til DOM. Tross alt, det er hva JavaScript er på.

Mens de fleste av endringene av DOM er minimal, kan de også forekommer ganske ofte. Et fint eksempel på hyppig lesing/skriving er å utføre et skript på side bla. Ideelt sett ønsker vi å unngå å legge klasser, attributter eller endre innholdet av elementer direkte i hunden, selv om vi skriver det samme klasser, attributter eller innholdet fordi vår endringer som likevel kan få behandlet av leseren, og er fortsatt dyrt, selv når ingenting blir gjort for brukeren.

Størrelse

Sist, men ikke minst: størrelse. Størrelse er avgjørende for eller i alle fall burde være for et rammeverk. Koden diskutert i denne artikkelen er ment å bli brukt som en base på tvers av mange prosjekter. Det bør være så liten som mulig og unngå unødvendig kode som kan legges til manuelt for one-off bruke tilfeller. Ideelt sett bør det være modulbasert slik at vi kan trekke deler av den ut à la carte, basert på de spesifikke behovene for prosjektet.

Mens størrelsen av selv-skrevet koden er vanligvis rimelig, mange prosjekter ende opp med å ha minst noen avhengigheter/biblioteker for å fylle i hullene, og de kan gjøre ting ganske klumpete virkelig rask. La oss si vi har en karusell på øverste nivå siden av et nettsted, og noen diagrammer et sted dypere. Vi kan slå til eksisterende biblioteker som skulle håndtere disse tingene for oss, som glatt karusellen (10 KB minified/gzip, unntatt jQuery) og highcharts (73 KB minified/gzip). Det er over 80 KB code og jeg vil satse på at ikke hver byte som er nødvendig for vårt prosjekt. Som Addy Osmani forklarer JavaScript er dyrt, og størrelsen er ikke det samme som andre eiendeler på en side. Det er verdt å holde det i tankene neste gang du finner deg selv for å nå et bibliotek, men det bør ikke hindre deg fra å gjøre det hvis det positive oppveier de negative.

En titt på en minimal løsning vi kaller Gia

La oss ta en titt på noe av det jeg har jobbet på og bruke en stund med teamet mitt på Giant. Vi liker JavaScript og vi ønsker å arbeide direkte med JavaScript snarere enn et rammeverk. Men på samme tid, vi trenger vedlikehold og reusability som rammer tilbudet. Vi prøvde å ta noen begreper fra populære rammer og bruke dem til en server-gjengitt nettsted der du valg for en JavaScript-oppsett er så bred, og likevel så begrenset.

Vi vil gå gjennom noen grunnleggende funksjoner i vårt oppsett og fokuserer på hvordan det løser de punktene vi har dekket så langt. Vær oppmerksom på at mange av løsningene for våre behov, er direkte inspirert av store rammer, så hvis du ser noen likheter, vet at det ikke er en ulykke. Vi kaller det Gia (får det, som kort etter store?!) og du kan få det fra npm og finne kilden koden på GitHub.

Gia, som mange rammer som er bygget rundt komponenter som gir deg en grunnleggende byggestein og noen fordeler vi vil komme inn på i en bit. Men ikke forveksle Gia komponenter med komponent begreper som brukes av Reagere og Vue, hvor alle HTML er et produkt av komponenten. Dette er annerledes.

I Gia, en komponent er en wrapper for din egen kode som kjører i omfanget av en DOM-element, og forekomsten av en komponent er lagret i element i seg selv. Som et resultat, et eksempel er fjernet automatisk fra minnet ved garbage collector i tilfelle elementet er fjernet fra DOM. Kildekoden til komponenten kan bli funnet her, og er ganske enkel.

Bortsett fra en komponent, Gia har flere hjelpere til å søke, ødelegge, og arbeidet med den komponenten forekomst eller kommunisere mellom komponenter (med standard eventbus inkludert for enkelhets skyld).

La oss starte med en grunnleggende oppsett. Gia er ved hjelp av et attributt til å velge elementer, sammen med navnet på komponenten som skal utføres (dvs. g-komponent=”[komponent navn]”). Dette krever en konsekvent naming convention. Kjører loadComponents funksjonen skaper de tilfeller som er definert med g-komponent-attributtet.

Se Pen Grunnleggende komponent av Georgy Martsjuk (@gmrchk) på CodePen.

Gia komponenter som også gir oss mulighet til å enkelt velge elementer innen rot-element med g-ref-attributtet. Alt som må gjøres er å definere refs som er forventet, og om vi jobber med en enkelt element eller et utvalg av dem. Referanse er deretter tilgjengelig i dette.ref-objekt i komponenten.

Se Penn Komponent med ref elementer av Georgy Martsjuk (@gmrchk) på CodePen.

Som en bonus, standard valg kan være definert i komponenten, som er automatisk omskrevet ved noen valg som inngår i g-valg-attributtet.

Se Penn Komponent med valg av Georgy Martsjuk (@gmrchk) på CodePen.

Komponenten omfatter metoder som utføres til forskjellige tider, for å løse lifecycle problemet. Her er et eksempel som viser hvordan en komponent kan bli initialisert eller fjernes:

Se Penn legg i/ta ut komponenter av Georgy Martsjuk (@gmrchk) på CodePen.

Legg merke til hvordan loadComponents funksjonen gjelder ikke det samme komponent når det allerede eksisterer.

Det er ikke nødvendig å fjerne lyttere knyttet til rot-element av en komponent eller elementer i det før re-gjengi dem siden elementer vil bli fjernet fra DOM uansett. Det kan imidlertid være noen lyttere opprettet på global objekter (f.eks. vinduet), som de som brukes for å bla håndtering. I dette tilfellet, er det nødvendig å ta lytteren manuelt før ødelegge komponent eksempel for å unngå minne lekkasjer.

Konseptet av en komponent omfattet til en DOM-element er lik i sin natur å Reagere og Vue-komponenter, men med et viktig unntak at DOM-struktur er utenfor komponent. Som et resultat, har vi å gjøre sikker på at det passer komponent. Å definere ref elementer hjelper absolutt, som Gia komponenten vil fortelle deg når det er nødvendig refs er ikke til stede. Det gjør komponent gjenbrukbare. Følgende er eksempel gjennomføring av en grunnleggende karusellen som enkelt kunne gjenbrukes eller delt:

Se Pen Grunnleggende karusellen komponent av Georgy Martsjuk (@gmrchk) på CodePen.

Mens vi snakker om reusability, er det viktig å nevne at komponentene må ikke brukes om igjen i sin eksisterende tilstand. Med andre ord, kan vi utvide dem til å lage nye komponenter som alle andre JavaScript-klasse. Det betyr at vi kan lage en generell komponent og bygge på det.

For å gi et eksempel, en komponent som vil gi oss avstanden mellom markøren og sentrum av et element virker som en ting som kan være nyttig en dag. En slik komponent kan bli funnet her. Etter å ha som klar, og det er latterlig enkelt å bygge på det og arbeidet med oppgitt tall, som neste eksempel viser i gjengi funksjon, selv om vi kan argumentere om nytten av dette eksempelet.

Se Penn ZMXMJo av Georgy Martsjuk (@gmrchk) på CodePen.

La oss prøve å se inn optimalisert DOM manipulasjoner. Å oppdage hvis en endring til DOM er ment å skje, kan bli manuelt lagret eller sjekket uten direkte tilgang til DOM, men som har en tendens til å være mye arbeid som vi kanskje ønsker å unngå.

Dette er hvor Gia virkelig hentet inspirasjon fra Reagere, med enkle, strippet ned komponent statlig styring. Tilstanden til en komponent som er satt på samme måte som stater i å Reagere, ved hjelp av en setState funksjon.

Når det er sagt, det er ingen gjengivelse involvert i vår komponent. Innholdet er gjengitt av serveren, så vi trenger å gjøre bruk av endringer i statlige andre steder. Staten endringene er evaluert og noen faktiske endringer er sendt til stateChange metode for en komponent. Ideelt sett noen interaksjon mellom komponenten og DOM ville bli håndtert på denne funksjonen. I tilfelle noen del av staten ikke endres, vil det ikke være til stede i stateChanges objekt gått inn i en funksjon, og derfor vil ikke bli behandlet — DOM vil ikke være berørt uten at det er virkelig nødvendig.

Sjekk følgende eksempel med en komponent som viser deler som er synlig i vinduet:

Se Penn Seksjoner i viewport komponent av Georgy Martsjuk (@gmrchk) på CodePen.

Legg merke til hvordan å skrive til DOM (visualisert ved blinking) er bare gjort for elementer der staten faktisk endres.

Nå er vi i å komme til min favoritt del! Gia er virkelig minimal. Hele pakken inneholder all koden, inkludert alle hjelpere, tar opp en measly 2.68 KB (minified/gzip). For ikke å nevne at du mest sannsynlig ikke trenger alle av Gia ‘ s deler og ville ende opp med å importere enda mindre med en bundler.

Som nevnt tidligere, er størrelsen på koden kan raskt øke med inkludert tredjeparts avhengigheter. Det er derfor Gia inneholder også kode for splitting støtte, der du kan definere en avhengighet til en komponent, som bare vil bli lastet inn når komponenten blir initialisert for første gang, uten noen ekstra setup nødvendig for å bundler. På den måten, store biblioteker brukt et sted dypt i ditt nettsted eller applikasjon behøver ikke å roe ting ned.

I tilfelle du bestemmer deg for en dag at du virkelig ønsker å dra nytte av alle godbitene store rammer kan tilby et sted i koden din, det er ingenting lettere enn å bare legge det ut som noen andre avhengighet for komponenten.

klasse SampleComponent strekker seg Komponent {
asynkron krever() {
dette.vue = venter på import(‘vue’);
}

mount() {
nytt dette.vue({
el: dette.elementet,
});
}
}

Konklusjon

Jeg antar det viktigste poenget med denne artikkelen er at du ikke trenger et rammeverk for å skrive, vedlikeholde og gjenbrukbar kode. Følgende og håndheve et par konsepter (som rammer bruk, så vel) kan ta deg langt på egen hånd. Mens Gia er minimal, og ikke har mange av de robuste funksjoner som tilbys av store spillere, som Reagerer og Vue, er det fortsatt hjelper oss å få det rent struktur som er så viktig på lang sikt. Det inkluderer noen mer interessante ting som ikke dugde her. Hvis du liker det så langt, går sjekk det ut!

GitHub-Repo

Det er massevis av use cases, og ulike behov krever ulike tilnærminger. Ulike rammer kan gjøre mye av jobben for deg; i andre tilfeller kan de være begrensende.

Hva er din minimalt oppsett, og hvordan får du konto for de punktene vi har dekket her? Foretrekker du en ramme eller ikke-framework-miljø? Har du bruke rammer i kombinasjon med statisk side generatorer som Gatsby? Gi meg beskjed!