Sådan skrives enkle moderne JavaScript-apps med Webpack og progressive webteknikker

Har du tænkt på at fremstille moderne JavaScript-applikationer med den mest enkle konfiguration for dit næste projekt?

I så fald er du kommet til det rigtige sted!

JavaScript-rammer findes for at hjælpe os med at opbygge applikationer på en generaliseret måde med de fleste af de fælles funktioner. Men de fleste af applikationerne har muligvis ikke brug for alle de kraftfulde funktioner i en ramme. Det kan være overdrevent at bare bruge en ramme til specifikke krav (især små til mellemstore projekter).

I dag skal jeg vise en tilgang til, hvordan du kan bruge moderne funktioner og opbygge dine egne tilpassede webapplikationer. Du kan også opbygge dine egne rammer oven på eksempelprogrammerne, hvis du vil. Det er rent valgfrit. Kraften ved Vanilla JavaScript giver os mulighed for at følge vores egen kodningstil uanset de anvendte værktøjer.

Hvad vi har brug for

Lad os hurtigt gå igennem de funktioner, vi har brug for, inden vi starter.

Arkitektonisk planlægning

For at sikre hurtig indlæsning og ensartede oplevelser bruger vi følgende mønstre:

  • Ansøgning Shell Arkitektur
  • PRPL (Push, Render, Pre-cache, Lazy loading) mønster

Build Setup

Vi har brug for en god tilpasset build-opsætning, så vi bruger Webpack med følgende krav:

  • ES6 & Dynamic Imports support
  • SASS & CSS support
  • Brugerdefineret udvikling og produktionsopsætning
  • Custom Service Worker Build

Bare minimum JavaScript-funktioner

Vi vil berøre minimale JavaScript-funktioner for at få os væk fra jorden og producere det output, vi har brug for. Jeg vil vise dig, hvordan vi kan bruge eksisterende JavaScript ES6-funktioner i vores daglige vaniljeprogrammer. Her er de:

  • ES6-moduler
  • Dynamisk import
  • Objekt Literal Syntax Eller ES6 Class Syntax
  • ES6 Arrow-funktioner
  • ES6-skabelonlitterære

I slutningen af ​​denne artikel er der en eksempelapplikationsdemo sammen med dens kildekode på GitHub. Lad os grave dybere, skal vi?

Arkitektonisk planlægning

Fremkomsten af ​​Progressive Web Applications har bidraget til at bringe nye arkitekturer for at gøre vores første maling mere effektiv. Kombination af App Shell- og PRPL-mønstre kan resultere i konsekvent lydhørhed og applignende oplevelser.

Hvad er App Shell & PRPL?

App Shell er et arkitektonisk mønster til opbygning af progressive webapplikationer, hvor du sender de minimale kritiske ressourcer for at indlæse dit websted. Dette består dybest set af alle de nødvendige ressourcer til den første maling. Du kan også cache de kritiske ressourcer ved hjælp af en servicemedarbejder.

PRPL henviser til følgende:

  • Skub kritiske ressourcer (især ved hjælp af HTTP / 2) til den indledende rute.
  • Gengiv den første rute.
  • Forud cache resterende ruter eller aktiver.
  • Lat ladning af dele af et program, når og når det er nødvendigt (især når det kræves af en bruger).

Hvordan ser disse arkitekturer ud i kode?

App Shell- og PRPL-mønsteret bruges begge sammen for at opnå den bedste praksis.

App-shell ligner noget af følgende stykke kode:

Du kan se, at applikationsskallen består af den blotte minimumsmarkering som et skelet.

Linjer 9–82: Kritiske stilarter er blevet introduceret i markup for at sikre direkte parsing af CSS i stedet for at knytte den til en anden fil.

Linjer 89–96: Hovedpåførings shell-markering; disse områder vil senere blive manipuleret med JavaScript (især indholdet i hovedmærket på linje 93).

Linie 99: Det er her manuskripterne kommer i spil. Async-attributten hjælper med ikke at blokere parseren, mens scripterne downloades.

App-shell håndhæver også Push & Render-stadier i PRPL-mønsteret. Dette sker, når HTML parses af browseren for at danne pixels på skærmen. Den finder let alle de kritiske ressourcer. De kritiske scripts er også ansvarlige for at vise den indledende rute ved DOM-manipulation (Render).

Hvis vi ikke bruger en servicemedarbejder til at cache shell, vil det dog ikke være til nytte for fremtidige genindlæser og ydelsesfordele.

Følgende kodestykker viser en servicemedarbejder, der cache-shallen og alle de statiske aktiver, der kræves til applikationen.

Linjer 4–17: Installationsbegivenhed hos servicemedarbejdere hjælper med at cache alle statiske aktiver. Her kan du cache app shell-ressourcerne (CSS, JavaScript, billeder osv.) Til den første rute (som pr. App-shell). Du kan også cache resten af ​​applikationens aktiver og sikre, at hele appen også kan køre offline. Denne cache af statiske aktiver bortset fra den vigtigste app-shell sikrer PRPL-mønsterets pre-cache-trin.

Linjer 19–38: Aktivitetshændelsen er stedet til oprydning af ubrugte cacher.

Linjer 40–63: Disse kodelinjer hjælper med at hente ressourcer fra cachen, hvis de er i cache eller går til netværk. Hvis der oprettes et netværksopkald, er ressourcen ikke i cache og placeres i en ny separat cache. Dette scenarie hjælper med at cache alle dynamiske data til en applikation.

Alt i alt er de fleste af arkitekturdelene blevet dækket. Den eneste del, der er tilbage, er den doble ladetrin i PRPL-mønsteret. Jeg vil diskutere dette med hensyn til JavaScript.

Vores Build Setup

Hvad er en god arkitektonisk struktur uden en buildopsætning? Webpack til redning. Der er andre værktøjer som pakke, sammenlægning osv. Derude, men uanset hvilke koncepter vi anvender til Webpack kan anvendes til ethvert sådant værktøj.

Jeg vil kortlægge de koncepter, der bruges til plugins, så du kan få fat i det grundlæggende brugt til opsætning af arbejdsgangen. Dette er det vigtigste trin for at komme i gang med en god genanvendelig build-konfiguration til din egen applikation for fremtiden.

Jeg ved, hvor svært det er for udviklere som os at konfigurere Webpack eller ethvert værktøj til den sags skyld fra bunden. Den følgende artikel var en inspiration, som hjalp mig med at skabe min egen build-opsætning:

En historie om Webpack 4 og hvordan man endelig konfigurerer den på den rigtige måde. Opdateret.

Henvis til ovenstående link, hvis du sidder fast overalt med buildopsætningen. Lad os nu tjekke de koncepter, der kræves til build.

ES6 & Dynamic Imports support

Babel er en populær transpiler, der er der for at hjælpe os med transpilering af ES6-funktioner ned til ES5. Vi har brug for følgende pakker for at aktivere babel, der arbejder med webpack:

  • @ Babel / kerne
  • @ Babel / plugin-syntaks-dynamisk-import
  • @ Babel / preset-env
  • babel-core
  • babel-loader
  • babel-preset-env

Her er en prøve babelrc til reference:

Under babelopsætning er vi nødt til at tilføje følgende 2. linje i forudindstillinger for at aktivere babel til at transportere ES6 ned til ES5 og den 3. linje i plugins for at aktivere den dynamiske importstøtte med Webpack.

Sådan bruges babel med Webpack:

Linjer 10–17: Babel-læsseren bruges til at konfigurere babel-transpilationsprocessen i webpack.config.js. For at gøre det lettere er de andre dele af konfigurationen elimineret eller kommenteret.

SASS & CSS Support

Til opsætning af SASS og CSS har du brug for følgende pakker:

  • Sass-loader
  • css-loader
  • stil-loader
  • MiniCssExtractPlugin

Sådan ser konfigurationen ud:

Linjer 17–25: Dette er det område, hvor læsserne er registreret.

Linjer 29–31: Da vi bruger et plugin til at udpakke en CSS-fil, bruger vi MiniCssExtractPlugin her.

Custom Development & Production Setup

Dette er den vigtigste del af byggeprocessen. Vi ved alle, at vi har brug for et udviklings- og produktionsopbygningssæt til at udvikle applikationer og også implementere den endelige distribuerbare på nettet.

Her er de pakker, der bliver brugt:

  • clean-webpack-plugin: Til oprydning af indholdet af dist-mappen.
  • compression-webpack-plugin: Til gzipping af indholdet af dist-mappefilen.
  • copy-webpack-plugin: Til kopiering af statiske aktiver, filer eller ressourcer fra applikationskilde til dist-mappe.
  • html-webpack-plugin: Til oprettelse af en index.html-fil i mappen dist.
  • webpack-md5-hash: Til hashing af applikationskildefiler i dist-mappen.
  • webpack-dev-server: Til at køre en lokal udviklingsserver.

Her er den endelige Webpack-konfigurationsfil:

Linjer 9–77: Hele webpack-konfigurationen er en funktion, der tager to argumenter. Her har jeg brugt argv, dvs. de argumenter, der sendes, mens jeg kørte webpack- eller webpack-dev-server-kommandoer.

Nedenstående billede viser scriptsafsnittet i package.json.

npm-scripts i package.json

Følgelig, hvis vi kører npm run build, vil det udløse en produktions build, og hvis vi kører npm run serve, vil det udløse en udviklingsstrøm med en lokal udviklingsserver.

Linjer 44–77: Disse linjer viser, hvordan plugins og udviklingsserverkonfigurationen skal konfigureres.

Linjer 59–66: Disse linjer er alle ressourcer eller statiske aktiver, der skal kopieres fra applikationskilden.

Custom Service Worker Build

Da vi alle ved, hvor trættende det er at skrive navnene på alle filerne igen til cache, lavede jeg et brugerdefineret servicemedarbejder til at oprette script til at få fat i filerne i dist-mappen og derefter tilføje dem som indholdet af cachen i tjenesten arbejder skabelon. Endelig vil servicemedarbejderfilen blive skrevet til dist-mappen.

Koncepterne vedrørende den servicemedarbejder-fil, vi talte om, vil være de samme. Her er scriptet i aktion:

Linjer 8–18: Dette er det sted, hvor alt indholdet i dist-mappen indfanges som en matrix statiskAssetsCacheFiles.

Linjer 22–85: Dette er den servicemedarbejderskabelon, vi talte om før. Koncepterne er nøjagtig de samme, bare at vi introducerer variabler i skabelonen, så vi kan genbruge servicemedarbejderskabelonen og gøre den praktisk til fremtidig brug. Denne skabelon var også påkrævet, da vi var nødt til at tilføje dist-mappeindhold til cachen pr. Linje 33.

Linjer 87–90: Endelig skrives en ny servicearbejder-fil til mappen dist sammen med dens indhold fra servicemedarbejderens skabelon serviceWorkerScript.

Kommandoen til at køre ovenstående script er node build-sw, og den skal køres efter webpack - modeproduktion er færdig.

Denne service-medarbejder-opbygning af script hjalp mig virkelig meget med at cache-filer let. Jeg bruger i øjeblikket dette til mine egne sideprojekter på grund af dets enkelhed og store lethed med at tackle cache-problemet.

Hvis I fyre vil bruge et bibliotek til Progressive Web Application-relaterede funktioner, kan du gå til Workbox. Dette bibliotek gør nogle rigtige pæne ting og har fantastiske funktioner, som du kan tage kontrol over.

Sidste kig på pakkerne

Her er en sample package.json-fil med alle afhængigheder:

Husk, at Webpack opdateres ofte, og at ændringer fortsætter med at ske i samfundet med nye plugins, der erstatter eksisterende. Så det er vigtigt at holde et notat om de koncepter, der kræves til en build-opsætning snarere end de faktiske anvendte pakker.

JavaScript-funktioner

Vi har alle et valg: enten at skrive vores egne rammer for bestemte funktioner, der skal bruges af vores applikation, såsom ændringsdetektering, routing, opbevaringsmønstre, redux osv. Eller trække allerede eksisterende pakker til sådanne funktioner.

Nu vil jeg tale om de nødvendige minimumsfunktioner, der kræves for at strukturere layoutet af vores applikation og få det i gang. Senere kan du tilføje dine egne rammer eller pakker til applikationen.

ES6-moduler

Vi bruger ES6 import og eksport erklæringer og behandler hver fil som et ES6 modul. Denne funktion bruges ofte af populære rammer som Angular and React og er temmelig praktisk. Med kraften i vores Webpack-konfigurering kan vi fuldt ud udnytte kraften i import- og eksporterklæringer.

Objekt Literal Syntax Eller ES6 Class Syntax

Bygningskomponenter er en meget vigtig del af vores applikation. Vi kan vælge at gå med de nyeste webstandarder som webkomponenter også, men for at holde tingene enkle kan vi gå foran og bruge syntaks objekter bogstavelig eller ES6-klasse.

Det eneste med klassesyntax er, at vi er nødt til at øjeblikkelig gøre det og derefter eksportere det. Så for at holde tingene endnu enklere gik jeg videre med en bogstavelig syntaks til komponentarkitektur.

Linjer 4–32: Vi eksporterer et objekt kaldet AppComponent, som umiddelbart er tilgængeligt til brug i andre dele af vores applikation.

Du kan også gå videre med at bruge ES6-klasse-syntaks eller standard-webkomponenter og få en mere deklarativ måde at skrive kode her. For enkelhedens skyld valgte jeg at skrive demo-applikationen i en mere imperativ tilgang.

Dynamisk import

Kan du huske, at jeg talte om at gå glip af “L” i PRPL-mønsteret? Dynamisk import er måden at gå videre og doven indlæsning af vores komponenter eller moduler. Da vi brugte App Shell og PRPL sammen til at cache shell og andre ruteaktiver, importerer dynamisk import den doble komponent eller modul fra cachen i stedet for netværket.

Bemærk, at hvis vi kun brugte App Shell-arkitektur, ville de resterende aktiver i applikationen, dvs. indholdet af chunks-mappen, ikke have været cache.

Linjer 15–19: Se app-komponentkode; dette er stedet, hvor dynamisk import skinner. Hvis vi klikker på en knap, der har klassen btn-todo, bliver kun denne TodoModule indlæst. For øvrig er TodoModule bare en anden JavaScript-fil, der består af et sæt objektkomponenter.

ES6 Arrow-funktioner og ES6-skabelonlitterære

Pilefunktioner bør især bruges, hvor vi vil sikre os, at dette nøgleord er inde i funktionen, som skal henvise til den omgivende kontekst, hvor pilefunktionen er deklareret. Bortset fra det hjælper disse funktioner virkelig med at skabe pæn shorthand-syntaks.

Ovenstående eksempel er en skabelonfunktion defineret som en pilefunktion, der accepterer en model og returnerer en HTML-streng, der består af modeldataene i den. Strenginterpolering udføres ved hjælp af ES6-skabelonlitterære. Den reelle fordel ved skabelonlitterære er flerlinjestreng og interpolering af modeldata i strengen.

Her er et mikrotip til håndtering af komponenttemplering og generering af genanvendelige komponenter: Brug reduktionsfunktionen til at akkumulere alle HTML-strenge ifølge følgende eksempel:

Ovennævnte kodestykker gør faktisk en hel del arbejde. Enkel, men alligevel intuitiv. Det følger lidt inspiration fra rammerne derude.

Linjer 1–19: Dette er en eksempelmodellarray, som reduceringsfunktionen kan køre for at give den genanvendelige skabelonfunktion.

Linie 53: Denne linje gør al den magi ved at generere flere genanvendelige komponenter i en HTML-streng. Reduktionsfunktionen tager akkumulatoren i som det første argument og hver værdi af arrayet som det andet argument.

Takket være disse enkle funktioner har vi allerede en applikationsstruktur på plads. Den bedste måde at lære en funktion er at sætte den i gang, siger de, så her er vi.

Application Demo

Tillykke med at nå her!

Dette indlæg dækkede faktisk en masse funktioner, og det vil tage nogen tid at få fat i alle koncepter og teknikker.

Her er en demonstration af to-do-applikationen bygget med alle de funktioner, der er diskuteret i denne artikel. Klik her for at besøge siden.

Vanilla Todos Demo

Klik her for linket til GitHub-arkivet. Du er velkommen til at klone depotet og gå gennem koden for en bedre forståelse af de konceptuelle eksempler nævnt i artiklen.

Eksempel på produktionsapp

Produktionsstedet er en portefølje, der blev designet, udviklet og konstrueret fra bunden ved hjælp af de nøjagtige funktioner som specificeret i denne artikel. Applikationen til enkeltsider er opdelt i brugerdefinerede moduler og komponenter.

Fleksibiliteten og kraften, der følger med Vanilla JavaScript, er noget unikt og hjælper med at producere nogle forbløffende resultater.

Klik her for at gå til siden. Her er stedet i aktion:

Tilpasset portefølje

Besøg stedet for at få en fornemmelse af det. Farverne er ikke nøjagtigt produceret i demoen her. Teknologien, der blev indført på dette sted, gav følgende resultater:

Portfolio Fyrtårnsresultater

Aldrig scoret perfekte 100 før i noget emne.

Konklusion

Der er flere projekter, vi måske gerne vil bygge ved hjælp af Vanilla JavaScript i stedet for rammer for hurtigt at opnå visse resultater. Jeg skrev denne artikel for at hjælpe udviklere med at bruge en simpel tilpasset opsætning til at opbygge deres fremtidige projekter.

Det bedste ved Vanilla-rammen er, at udviklere har friheden til at forme deres tekniske tankemønstre i henhold til forskellige anvendelsessager. Det være sig tvingende eller deklarativ stil med programmering, oprettelse eller brug af de nyeste eksisterende funktioner. Så længe vi producerer konsistente og udøvende applikationer med god kodevedligeholdelighed, udføres vores job for dagen.

God hacking!

Andre indlæg af mig

Find mig på https://medium.com/@anurag.majumdar

➥ Webudvikling

  • Progressiv webapp-shell: nøglen til at indlæse dit websted under 1 sekund!
  • “Super” og “Udvides” i JavaScript ES6 - Forståelse af de hårde dele
  • Introduktion til polyfills & deres anvendelse

➥ Livshændelse

  • Udacity's Google Mobile Web Stolarship Challenge og dets herlige effekter!