Vi tar for oss monteringen av frontenden på Gulp. Hyggelig montering av frontend-prosjektet15.02.2015 Gentlemans sett med frontend-utviklere

24. september , 2016

Følgende emner vil bli dekket: arbeid med sass-stiler ved å bruke kildekart, liming og komprimering av js-filer, bygging av requirejs med rjs, forhåndsbehandling av html, rensing og kopiering av filer, optimalisering av bilder, heve en lokal webserver og se-modus - watch-tasks. Velkommen til artikkelen, det vil være mye interessant!
P.S. Det er mye stoff, så artikkelen vil deles inn i 3 deler: grunnleggende montering og prosjektorganisering, skrive en testapplikasjon på Backbone + Require.js, og faktisk bygge med gulp.

Hvorfor du trenger å bygge en frontend.

Et av de viktigste prinsippene i utviklingen er modularitet. Deler opp prosjektkoden i mange små, ideelt sett løst koblede stykker-moduler. Dette gjelder langt mer enn bare javascript-kode. Dette gjelder stiler, og html-maler, til ulike biblioteker.

Strukturen til en enkel applikasjon skrevet i Backbone + Require kan se omtrent slik ut.

Og dette er et lite testprosjekt, i en ekte applikasjon kan det være hundrevis og tusenvis av filer. Å tvinge brukerens nettleser til å gjøre hundrevis av http-forespørsler er i det minste umenneskelig. Vi må sørge for raskest lasting av tjenesten vi har skrevet. Derfor er en av de viktigste oppgavene til byggeverktøy minifisering, redusere antall filer som brukes i prosjektet, lime dem inn i bunter. Ved utgangen bør vi ha en mer kortfattet struktur, for eksempel slik:

Forskjellen er tydelig synlig: i stedet for dusinvis av filer, har vi én index.html, én css-fil, optimerte og komprimerte bilder i en egen mappe, selv om dette ikke er synlig på skjermbildet :-)

Og også det mest interessante: i js-mappen mottok vi bare 3 komprimerte filer.
P.S. Hvorfor tre og ikke én, skal jeg fortelle deg senere.
Merk at dette er selve strukturen til testapplikasjonen som vi skal skrive om kort tid.

Jeg har nettopp beskrevet en grunn til å bruke byggeverktøy, men det er nok å begynne å bruke gulp, grunt, webpack eller noe sånt i prosjektene dine. Og det spiller ingen rolle om vi skriver en stor tjeneste, et lite SPA (som i artikkelen vår) eller en landingsside. Monteringsprinsippene er de samme for alle prosjekter og skiller seg bare i mangfoldet av oppgaver og tilnærminger til deres løsning. I vårt eksempel vil vi lage en struktur som kan utvides på hvilken som helst måte i fremtiden, men utdataene vil alltid være en ryddig stabel med filer, klare til å helles inn i produksjons-kampsiden din.

Hvordan organisere et prosjekt riktig.

Prinsippet er dette: det er en seksjon med utviklerfiler, det er med innsamlede filer og alt annet som disse tingene tjener. La oss lage 2 mapper i roten av prosjektet: src og build. I src og bare i src vil vi jobbe, lage nye filer, redigere dem og generelt ha det gøy. I skjermbildet ovenfor, hvor det er et par dusin filer, så du nøyaktig innholdet i src-mappen til testprosjektet vårt. Og like nedenfor er noen pene filer fra build-mappen. Den dannes bare automatisk, av monteringsverktøy, ingenting må redigeres der. Uansett, med hver sammenstilling blir innholdet overskrevet med nye filer (og i utviklingsmodus er det ingen byggemappe i det hele tatt - den slettes for ikke å være vondt)

I tillegg til src og build, vil package.json, gulpfile.js-filene, node_modules-mappen og eventuelt .gitignore (hvis du jobber med git) være i roten. Du kan fortsatt se loggmappen hos meg - dette er et produkt av apache og en langvarig vane med å holde prosjektlogger i sin egen mappe, selvfølgelig, og ekskludere den fra git-depotet :-)

Slik ser hele prosjektstrukturen ut:

I henhold til innholdet i bygget tror jeg det ikke er noen spørsmål, jeg vil forklare mer detaljert om src:

  • 1. html - index.html, rotindeksfilen til prosjektet. Hvorfor ikke umiddelbart ved rotkilden? Fordi det vil bli forbehandlet og skapt ved gulp. Hvordan får vi vite litt senere, når vi tar tak i monteringen.
  • 2. img - bilder, ikke komprimert, normal
  • 3. js - all javascript-bevegelse av prosjektet, ryggradsmodeller og visninger
  • 4. lib – tredjepartsbiblioteker som backbone.js, require.js, lodash.js og andre
  • 5. skript - js-skript som er nødvendig på et produksjonssted, men som ikke er nødvendig i utviklingsmodus. Dette refererer til koder for analyser, ulike eksperimenter og andre markedsføringsdeler.
  • 6. stiler - sass filer med stiler. Den sammensatte css-filen vil bli lagt til samme mappe (kun for utviklingsmodus)
  • 7. tpl - html maler. Brukes av Backbone-visninger ved å bruke require.js-tekstplugin

Utseendet til testapplikasjonen er ganske skjemmende. Du kan si at denne typen dritt gjøres med et par linjer med html og css-kode uten en eneste js-fil.
Men målet vårt er ikke å tegne et vakkert bilde, men å skape en pålitelig prosjektstruktur og vurdere så mange aspekter av monteringen som mulig. Når prosjektet vokser til hundrevis av filer, vil vi være klare for denne plagen og lett takle de økte volumene. Derfor, til tross for testapplikasjonens litenhet og ytre elendighet, vil vi lære prinsippene for montering for store og komplekse prosjekter.

Hvilke monteringsoppgaver skal vi løse.

La meg minne deg på at vi ble enige om to byggemåter: utvikling og produksjon. Vi vil skrive alle oppgavene våre med tanke på disse to modusene. Ikke alle operasjoner er nødvendige i utviklingsprosessen, og ikke alle i monteringen for produksjon.

Her er en liste over hva vi skal gjøre etter å ha skrevet en testsøknad:

  • 1. Rensing av filer og mapper fra resultatene fra forrige bygg
  • 2. Bygge css fra sass-filer, med og uten komprimering
  • 3. Koble kildekart til stiler, samtidig vil jeg vise med et eksempel hvorfor dette trengs
  • 4. Bygg en js-pakke med requirejs
  • 5. Liming og komprimering av individuelle js-filer (analyse)
  • 6. HTML-forbehandling
  • 7. Bildeoptimalisering og komprimering
  • 8. Heve en lokal webserver
  • 9. Oppgaver for å overvåke filer når du jobber i utviklingsmodus - watch-tasks
  • 10. Samle separate oppgaver til en haug - avsluttende oppgaver for produksjon-montering og utviklingsarbeid

Så vi diskuterte hvorfor vi i det hele tatt trenger å bygge frontend, bestemte oss for strukturen til prosjektet, analyserte i detalj hva vi ønsker fra bygget, og snakket generelt om testapplikasjonen. I neste del av artikkelen vil vi skrive en enkel Backbone-applikasjon i forbindelse med Require.js. Hvis du ikke er kjent med Backbone og/eller Require.js, så er det ingenting å bekymre seg for. Faktisk er det ikke nok ryggradskode i applikasjonen. Du kan enkelt bruke favorittbiblioteket ditt i stedet, eller bare skrive javascript/jquery-kode og hoppe over requirejs-oppsettseksjonen.

Gentleman's sett med Front-end utvikler

Det er ingen hemmelighet at en moderne front-end-utvikler må ha et av prosjektbyggeverktøyene i sitt arsenal, som f.eks. gulp eller Grynte. Inntil en tid hadde Grunt monopol i denne saken, men en gruppe utviklere som skilte seg fra Grunt bestemte seg for å lage sin egen lette og raske Gulp-oppgavebehandler.

I denne artikkelen vil vi utarbeide en startpakke fra bunnen av for bruk i fremtidige prosjekter.

Hvilke teknologier bruker vi

  • Programvareplattform: Node.js
  • CSS-forprosessor: pekepenn
  • Oppgavebehandling: gulp

Hvorfor trenger en frontender en oppgavebehandling?

Inntil nylig lurte jeg selv på hvorfor jeg må bruke tid på å sette oppn, hvis jeg allerede er god på layout-layout, helt til jeg begynte å bruke CSS-pre-prosessorer.

CSS-pre-prosessorer er veldig praktiske og øker skrivestiler, men å kompilere kode skrevet i en pre-prosessor til vanlig CSS er ikke en triviell oppgave som kan løses med én knapp. Det er her innsatslederen kommer oss til unnsetning. Konverteringen av koden skjer ikke ved å trykke på en knapp, alt skjer online uten din deltakelse (selvfølgelig hvis alt er satt opp riktig).

Selvfølgelig går oppgavene til en oppgavebehandler langt utover prosessene knyttet til å konvertere pre-prosessorkode til ren CSS. Prosjektmontøren tar også for seg minifisering, sammenkobling, kontroll av koden for feil, sammenstilling av bilder til sprites, optimalisering av bilder for nettet, etc. Du oppretter ganske enkelt mange logisk atskilte filer i prosjektet ditt, som deretter enkelt samles i én katalog, allerede behandlet og klare til å fungere i nettleseren. Men mer om det senere, men la oss nå begynne med forberedelsene.

Installerer Node.js

Hvis du vet hvordan du installerer node.js på systemet ditt og bruker det, kan du gjerne hoppe til neste overskrift.

Jeg vil umiddelbart advare om at alle de beskrevne handlingene er relevante for MacOS X, men generelt gjeldende for andre Unix systemer. Utvikling gjennom oppgavebehandleren og kommandolinjen inn Windows noe vanskeligere og vil ikke bli beskrevet her. Men hvis du fortsatt bruker Windows og ikke er klar til å gi opp det, kan jeg foreslå muligheten for å bruke en virtuell maskin med installert ubuntu, jeg bruker dette alternativet på hjemmesystemet mitt, noe som generelt er ganske praktisk.

Så det første vi må gjøre er å laste ned og installere node.js-pakken på systemet vårt for å jobbe med noden gjennom konsollen. Vi går til den offisielle siden til node.js og laster ned den siste stabile versjonen for systemet ditt. Når den er installert, skal nodekommandoen være tilgjengelig på kommandolinjen. For å sjekke at noden din fungerer, skriv inn kommandoen på kommandolinjen

versjonen av installert node.js skal vises som svar. Hvis alt er bra, går vi videre.

Prosjektkatalogstruktur

I våre prosjekter vil vi bruke en enhetlig versjon av strukturen:

Utvikle - utviklingsrotkatalog└─start - prosjektkatalog├─bygge - bygg satt sammen av oppgavelederen├─ressurs - alle kildefiler for utvikling (.psd, etc.)├─kilde - utviklingskatalog│├─css - katalog for stilutvikling││├─bilder - alle statiske bilder││├─sprites - bilde samlet i en sprite││├─delvis - tilpassede stilfiler│││├─mixins.style - tilpassede blandinger│││└─stiler - tilpassede stiler││├─leverandør - andre eksterne stilfiler││└─stiler - hovedstilark│├─fonter - fontkatalog│├─bilde - katalog over dynamiske bilder│├─js - JavaScript utviklingskatalog││├─_*.js - js sidefiler││├─_main.js - hovedtilpasset js││└─main.js - main js-fil│├─.htaccess - konfigurasjon for serveren│├─*.html - sidemarkeringsfiler│├─sider.html - en fil med lenker til alle sidene i malen│├─indeks.html - sidemarkeringsindeksfil│└─inkluderer - katalog med inkluderte markup-filer│ └─*.html - inkluderte markup-filer (header.html, etc.)├─package.json - npm-pakkebehandlerkonfig├─gulpfile.js - Gulp konfig├─stylus.mal.bart - maske for å lese sprites├─TODO - gjøremålsliste└─.gitignore - git config

Installasjon

I konsollen bruker du cd-kommandoen for å gå til utviklingsrotkatalogen, lag prosjektkatalogen mkdir start og gå til den.

La oss sette opp strukturen vår for prosjektet via konsollen:

mkdir bygge ressurs src src/css src/css/images src/css/sprites src/css/partial src/css/leverandør src/js src/mal src/mal/include src/img src/fonts

La oss lage de første filene i prosjektstrukturen:

berør gulpfile.js stylus.template.mustache .gitignore src/.htaccess src/TODO src/css/styles.styl src/css/partial/styles.styl src/css/partial/mixins.styl src/js/main.js src/js/_main.js src/template/pages.html src/template/index.html src/template/include/header.html src/template/include/footer.html

Opprett package.json

alle popup-spørsmål kan klikkes gjennom Enter, noden vil sette dem til standardverdier, eller fylle ut de foreslåtte feltene.

.gitignore

Vi forteller git hvilke kataloger som skal ignoreres og ikke lastes opp til depotet:

/node_modules/ /build/ /ressurs/

Katalogen node_modules vil dukke opp senere etter installasjon av pluginene og vil inneholde alle prosjektets node plugins.

src/.htaccess

Angi ekstra gzip-komprimering og caching for serveren:

AddOutputFilterByType DEFLATE tekst/html-tekst/ren tekst/xml-tekst/css-tekst/javascript-applikasjon/javascript # Server gzip-komprimerte CSS-filer hvis de finnes # og klienten godtar gzip. RewriteCond "%(HTTP:Accept-encoding)" "gzip" RewriteCond "%(REQUEST_FILENAME)\.gz" -s RewriteRule "^(.*)\.css" "$1\.css\.gz" # Vis gzip komprimert JS-filer hvis de finnes # og klienten godtar gzip. RewriteCond "%(HTTP:Accept-encoding)" "gzip" RewriteCond "%(REQUEST_FILENAME)\.gz" -s RewriteRule "^(.*)\.js" "$1\.js\.gz" # Vis riktig innhold typer, og forhindre mod_deflate dobbel gzip. RewriteRule "\.css\.gz$" "-" RewriteRule "\.js\.gz$" "-" # Vis riktig kodingstype. Overskrift tilføy Content-Encoding gzip # Tving proxyer til å bufre gzippede og # ikke-gzippede css/js-filer separat. Overskrift tilføy Varier Accept-Encoding ExpiresActive på ExpiresByType-applikasjonen/javascript "tilgang pluss 1 måneder" ExpiresByType image/jpg "tilgang pluss 1 måned" ExpiresByType image/jpeg "tilgang pluss 1 måned" ExpiresByType image/gif "tilgang pluss 1 måned" ExpiresByType tilgangsbilde pluss/png " måned" ExpiresByType text/css "tilgang pluss 1 måneder"

src/css/styles.style

Inkluder egendefinerte stilfiler i hovedstilfilen:

@import "delvis/stiler"

Merk at for å inkludere .styl-filer, er utvidelsen ikke spesifisert, i henhold til semantikken til Stylus-forprosessorkoden. For å inkludere stiler i en annen utvidelse, for eksempel .css, kreves sistnevnte.

Å GJØRE

Denne siden inneholder oppgavelisten for utvikling. Du kan lese mer om å jobbe med denne filen på PlainTasks-plugin-siden for Sublime Text.

Dette fullfører installasjonen av strukturen.

Installerer plugins med npm-pakkebehandling

Node.js inkluderer som standard npm-pakkebehandleren, som har mange plugins i sine repositories som vi må jobbe med.

Installere Gulp Plugin

Først må du installere Gulp globalt (med -g-bryteren) på systemet vårt

npm installer gulp -g

Du må gjøre dette en gang, ytterligere global installasjon er ikke nødvendig.

Nå må vi installere Gulp lokalt i prosjektkatalogen

npm installer gulp --save-dev

--save-dev-nøkkelen sier at informasjon om plugin-en (navnet i depotet og dets versjon) vil bli lagt til package.json-konfigurasjonen og vil huske det for dette prosjektet. Siden vi ikke lagrer en tung mappe med node_modules plugins i git, vil informasjonen om installerte plugins lagret i config tillate oss å distribuere alle nødvendige plugins i prosjektet med bare én npm i kommando.

Det er forkortelser for hver kommando, så vi kan skrive kommandoen ovenfor i et kortere format.

I fremtiden vil vi også bruke det forkortede kommandoformatet.

Stylus Plugin for Gulp

I våre prosjekter bruker vi Stylus-forprosessoren, som fungerer utmerket og kompilerer på noden.

Installere:

npm i gulp-stylus -D

CSS-behandlingsprogramtillegg

Autoprefikser- setter automatisk inn -ms- -o- -moz- -webkit- prefikser i de nødvendige egenskapene:

npm i gulp-autoprefixer -D

CSS-minifisering- plugin-en minimerer utdata-CSS-filen ved å fjerne ekstra mellomrom og tabulatorer fra den:

npm og gulp-minify-css -D

Programtillegg for bildebehandling

Kombinere bilder til sprites- du trenger ikke lenger å bruke timer med dyrebar tid på å slå sammen alle bildene til sprites, og deretter beregne koordinatene deres, denne plugin vil automatisk gjøre alt dette for deg:

npm i gulp.spritesmith -D

Legg til en maske for å beregne posisjoner i sprites til den tidligere opprettede stylus.template.mustache-filen:

((#items)) $((navn)) = ((px.x)) ((px.y)) ((px.offset_x)) ((px.offset_y)) ((px.width)) (( px.height)) ((px.total_width)) ((px.total_height)) "(((escaped_image)))"; ((/elementer))

Legg til egendefinerte mixins til mixins.styl:

SpriteWidth($sprite) bredde $sprite spriteHeight($sprite) høyde $sprite spritePosition($sprite) bakgrunnsposisjon $sprite $sprite spriteImage($sprite) bakgrunnsbilde-url($sprite) sprite($sprite) hvis !match( "hover", selector()) && !match("active", selector()) spriteImage($sprite) spritePosition($sprite) spriteWidth($sprite) spriteHeight($sprite)

Koble mixinene og den genererte filen med koordinater til hovedstilfilen src/css/styles.styl:

@import "partial/sprite" @import "partial/mixins"

Merk at sprite-filene må inkluderes før de egendefinerte stilene @import "partial/styles"

Bildeoptimalisering for nettet- plugin-modulen vil automatisk kutte ut all unødvendig informasjon fra bildene dine og krympe dem til optimal størrelse, som i noen tilfeller vil redusere størrelsen på bildene med opptil 90 %:

npm i gulp-imagemin -D

JavaScript-behandlingsprogramtillegg

JS minifisering- plugin-en minimerer JS-koden din så mye som mulig, og reduserer lastetiden:

npm jeg gulp-uglify -D

JS feilsporing- plugin-en vil sjekke JS-koden din grundig for å identifisere alle inkonsekvenser og vise dem i konsollen:

npm i jshint gulp-jshint -D

HTML-behandlingsprogramtillegg

Tilkoblede filer- pluginet lar deg lagre statiske deler av nettstedet, som topptekst , bunntekst , til side , etc., i separate filer og inkludere dem i en hvilken som helst del av en annen fil. Det er ikke lenger behov for å endre dusinvis eller til og med hundrevis av html-sider i malen i tilfelle mindre endringer i overskriften:

npm i gulp-rigger -D

Plugin er også kompatibel med JS.

Inkluder tilpasset JS i JS-hovedfilen src/js/main.js med konstruksjonen:

//= _main.js

Ta med header.html- og footer.html-filer i index.html

//= include/header.html//= include/footer.html

Andre plugins

LiveReload- plugin-en eliminerer behovet for å laste inn siden på nytt i nettleseren hver gang for å se endringene, nå skjer dette automatisk når du lagrer den endrede filen:

npm i gulp-connect -D

Forhindrer at Gulp krasjer- noen ganger hender det at Gulp kan krasje ut av klokkemodus ved kritiske feil (mest på grunn av JS). Denne plugin-en prøver å holde Gulp-prosesser i gang når det er mulig:

npm i gulp-rørlegger -D

Gi nytt navn til filer- det vanligste arbeidet med filnavn. Plugin-en lar deg endre navn på filer fullstendig, endre filtypen, legge til prefikser og postfikser, for eksempel for å bringe style.styl view-filen til style.min.css:

npm i gulp-rename -D

Renere- noen ganger er det behov for å rydde opp i byggekatalogen, her kommer en plugin til unnsetning:

Kildekart- for at filene dine skal forbli lesbare gjennom nettleserfeilsøking etter minifisering, må du legge til et kildekart til de minifiserte filene:

npm i gulp-sourcemaps -D

Avanserte klokkefunksjoner- plugin-en gjør klokken smart, nå overskriver den ikke alle filene i bygget når bare én fil endres, den overskriver en spesifikk modifisert fil, noe som sparer tid og ressurser:

npm i gulp-watch -D

Sjekk package.json

Etter at alle pluginene er installert, la oss sjekke vår package.json . Det skal se omtrent slik ut:

( "name": "start", "version": "1.0.0", "description": "Startpakke for frontend-utvikling", "author": "Ivan Ivanov", "license": "MIT", "dependencies": (), "devDependencies": ( "gulp": "siste", "gulp-autoprefixer": "siste", "gulp-connect": "siste", "gulp-imagemin": "siste", "jshint": "nyeste", "jshint-stylish": "nyeste", "gulp-jshint": "siste", "gulp-minify-css": "siste", "gulp-rørlegger": "siste", "gulp-rename": "siste", "gulp-rigger": "siste", "gulp-sourcemaps": "siste", "gulp-stylus": "siste", "gulp-uglify": "siste", "gulp-watch": "siste", "gulp.spritesmith": "nyeste", "rimraf": "siste" ) )

I stedet for siste, i ditt tilfelle, vil spesifikke versjoner av installerte plugins bli skrevet. Fordi Siden vi bygger vår startpakke som skal brukes i mange prosjekter, anbefales det også å erstatte versjonsverdiene med nyeste for alltid å installere oppdaterte plugin-versjoner i prosjektet.

Node_modules-katalogen skal også vises i prosjektmappen, der alle node-plugin-filer er lagret. Alle nødvendige plugins er installert, du kan fortsette til Gulp-konfigurasjonsinnstillingene.

Sette opp gulpfile.js

gulpfile.js- dette er hovedkonfigurasjonsfilen til oppgavebehandlingen vår, det er i den vi vil lagre alle innstillingene og kommandoene.

Alt Gulps arbeid koker ned til oppgave ( Engelsk en oppgave). En oppgave er en egen uavhengig funksjon med et navn. Hver oppgave kan kalles separat.

Kompatibilitetsmodus med moderne standarder

For det første, i begynnelsen av filen, vil vi koble til kompatibilitetsmodusen kun i henhold til moderne standarder:

"bruk streng";

Du kan lære mer om dette direktivet.

Initialiserer plugin

Plugins initialiseres med følgende konstruksjon:

var initPlugin = require("plugin-navn");

I samsvar med dette designet initialiserer vi alle pluginene våre:

Var gulp = require("gulp"), //main plugin gulp stylus = require("gulp-stylus"), //preprocessor stylus prefixer = require("gulp-autoprefixer"), //arranging autoprefixes cssmin = require(" gulp-minify-css"), //css minification uglify = require("gulp-uglify"), //js minification jshint = require("gulp-jshint"), //js feilsporingsrigger = require("gulp - rigger"), //arbeid med html og js inkluderer imagemin = require("gulp-imagemin"), //minimizing images spritesmith = require("gulp.spritesmith"), //kombinere bilder til sprites rimraf = require( "rimraf") "), //purge sourcemaps = require("gulp-sourcemaps"), //sourcemaps rename = require("gulp-rename"), //rename files plumber = require("gulp-plumber"), // fuse to stop gulp watch = require("gulp-watch"), //extending watch connect = require("gulp-connect"); //liveload

Banekonstanter

For enkelhets skyld definerer vi umiddelbart alle banene og maskene:

Var path = ( build: ( //Her vil vi spesifisere hvor filene skal legges klare etter build-html: "build/", js: "build/js/", css: "build/css/", img: " build/css/ images/", fonts: "build/fonts/", htaccess: "build/", contentImg: "build/img/", sprites: "src/css/images/", spritesCss: "src/css /partial/" ), src: ( //Baner for å hente html-kilder fra: "src/template/*.html", //Src/template/*.html-syntaksen forteller gulp at vi ønsker å få alle filer med . html-utvidelse js: "src/ js/[^_]*.js",//I stiler og skript trenger vi bare hovedfiler jshint: "src/js/*.js", css: "src/css/styles .styl", cssVendor: "src /css/vendor/*.*", //Hvis vi ønsker å lagre bibliotekfiler separat, så avkommenterer du img-linjen: "src/css/images/**/*.*", //Syntax img/**/*.* betyr - ta alle filer med alle utvidelser fra mappen og underkatalogene fonter: "src/fonts/**/*.*", contentImg: "src/img/**/* .*", sprites: "src/css/ sprites/*.png", htaccess: "src/.htaccess" ), watch: ( //Her indikerer vi, etter å ha endret hvilke filer vi vil se html: "src/template/**/*.html", js: "src/js/**/*.js", css: "src/css/**/*.*" , img: "src/css/images/**/*.*", contentImg: "src/img/**/*.*", fonts: "src/fonts/**/*.*", htaccess: " src/.htaccess", sprites: "src/css/sprites/*.png" ), clean: "./build", //kataloger som kan renses outputDir: "./build" //initial rotkatalog til start miniserveren );

Merk at vi kan bruke navnemasker:

  • *.js- alle filer med js-utvidelse
  • [^_]*.js- alle filer med js-utvidelsen, unntatt de som starter med et understrek
  • *.* - alle filer med en filtype i gjeldende katalog
  • /**/*.html- alle filer med .html-utvidelse i gjeldende katalog og alle underordnede kataloger

oppgave (oppgaver)

Nå som alle konstantene er skrevet, kan du begynne å skrive oppgaver. Alle oppgaver har følgende struktur:

Gulp.task("oppgavenavn", funksjon()( //noen funksjoner));

Miniserver og LiveReload

Først av alt vil vi sette opp den lokale serveren og LiveReload:

// Lokal server for utvikling gulp.task("connect", function()( connect.server(( //sett opp serverkonfigurasjoner rot: , //serverstart rotkatalogport: 9999, //hvilken port vi skal bruke livereload : true //initialisere LiveReload-operasjon )); ));

Mest sannsynlig vil du ofte måtte jobbe samtidig med flere prosjekter samtidig. Serveren lar deg kjøre mange servere samtidig, det er nok å registrere porten din for forskjellige prosjekter.

Bygg HTML

// oppgave for html-bygging gulp.task("html:build", function () ( gulp.src(path.src.html) //Velg filer fra den nødvendige path.pipe(rigger()) //Kjør gjennom rigger . pipe(gulp.dest(path.build.html)) //last dem opp til build-mappen .pipe(connect.reload()) //og start serveren vår på nytt for oppdateringer));

JS bygge

// sjekker js for feil og sender dem ut til konsollen gulp.task("jshint:build", function() ( return gulp.src(path.src.jshint) //select filer fra den nødvendige path.pipe(jshint( )) //kjør gjennom jshint .pipe(jshint.reporter("jshint-stylish")); //stil utdata av feil til konsollen )); // javascript bygning gulp.task("js:build", function () ( gulp.src(path.src.js) //Finn vår hovedfil.pipe(rigger()) //Kjør gjennom rigger .pipe(kildekart .init()) //Initialiser kildekartet .pipe(uglify()) //Komprimer vår js .pipe(sourcemaps.write()) //Skriv maps.pipe(rename((suffiks: ".min"))) / /legg til suffikset.min til utdatafilen.pipe(gulp.dest(path.build.js)) //last opp den ferdige filen for å bygge .pipe(connect.reload()) //Og start serveren på nytt ));

Sprite bygge

Alle bilder som skal sprites legges til src/css/sprites/-katalogen og, etter å ha kjørt gjennom Gulp, blir de til et enkelt sprite-bilde. Sprites bør ikke inkludere logoer og bakgrunner uten klare mål.

// build sprites gulp.task("sprites:build", function () ( var spriteData = gulp.src(path.src.sprites) //velg hvor bildene skal smeltes sammen til en sprite.pipe(spritesmith(( imgName) : " sprite.png", //navn på sprite-bildet cssName: "sprite.styl", //stilnavn hvor vi lagrer bildeposisjoner i sprite imgPath: "images/sprite.png", //bane hvor sprite ligger cssFormat: "stylus", //format som vi behandler posisjoner i cssTemplate: "stylus.template.mustache", //mask file cssVarMap: function(sprite) ( sprite.name = "s-" + sprite.name // navnet på hver sprite vil bestå av et filnavn og konstruksjoner "s-" i begynnelsen av navnet ) ))); spriteData.img.pipe(gulp.dest(path.build.sprites)); // bane hvor vi lagrer bildet spriteData.css.pipe(gulp.dest(path .build.spritesCss)); // bane hvor vi lagrer stiler ));

For å vise en sprite, bruk bare en mixin. For eksempel, for filen lorem.png, vil utvalget fra spriten se slik ut:

Lorem sprite($s-lorem)

Nå vil .lorem-objektet ta dimensjonene til bildet og selve bildet som bakgrunn.

Bygg av statiske bilder

Statiske bilder er bilder som brukes i layoutmalen.

// bygg statiske bilder gulp.task("image:build", function () ( gulp.src(path.src.img) //Velg bildene våre. pipe(imagemin(( //Komprimer dem progressivt: true, // compression.jpg svgoPlugins: [(removeViewBox: false)], //compression.svg interlaced: true, //compression.gif optimizationLevel: 3 //komprimeringsnivå fra 0 til 7 ))) .pipe(gulp.dest(path. build.img)) //last opp for å bygge .pipe(connect.reload()) //start serveren på nytt));

Bygg dynamiske bilder

Dynamiske bilder er innholdsbilder som vil endres på nettstedet og er inkludert på malnivå kun for demonstrasjonsformål. Det kan for eksempel være bilder til nyheter o.l.

// bygg dynamiske bilder gulp.task("imagescontent:build", function() ( gulp.src(path.src.contentImg) .pipe(imagemin(( //Komprimer dem progressivt: true, //compress.jpg svgoPlugins: [(removeViewBox: false)], //compression.svg interlaced: true, //compression.gif optimizationNivå: 3 //komprimeringsforhold fra 0 til 7 ))) .pipe(gulp.dest(path.build.contentImg)) //avlast for å bygge .pipe(connect.reload()) //start server på nytt));

Bygg CSS

// build custom css gulp.task("cssOwn:build", function () ( gulp.src(path.src.css) //Velg vårt hovedstilark. pipe(sourcemaps.init()) //initialize soucemap . pipe (stylus(( compress: true, "include css": true ))) //Kompiler stylus .pipe(prefixer(( nettleser: ["siste 3 versjon", "> 1%", "ie 8", "ie 7 "] ))) //Legg til leverandørprefikser.pipe(cssmin()) //Compress.pipe(sourcemaps.write()) //write sourcemap .pipe(rename((suffiks: ".min"))) / / legg til suffix.min til utdatafilnavn.pipe(gulp.dest(path.build.css)) //unload for å bygge .pipe(connect.reload()) //restart server ));

Separat oppgave for eksterne stiler:

// bygge leverandøren css gulp.task("cssVendor:build", funksjon () ( gulp.src(path.src.cssVendor) // Hent leverandørmappen .pipe(sourcemaps.init()) //initialiser kildekartet .pipe( cssmin()) //Compress.pipe(sourcemaps.write()) //skriv sourcemap .pipe(gulp.dest(path.build.css)) //last opp for å bygge .pipe(connect.reload() ) // start serveren på nytt));

La oss også legge til en oppgave for den generelle CSS-byggingen:

// bygg hele css gulp.task("css:build", [ "cssOwn:build", // "cssVendor:build" ]);

Hvis du vil behandle eksterne stiler separat fra hjemme-stiler og laste dem opp som separate filer, må du fjerne kommentaren til linjen "cssVendor:build"

Fontbygging

// build fonts gulp.task("fonts:build", function() ( gulp.src(path.src.fonts) .pipe(gulp.dest(path.build.fonts)) //dump to build ));

Bygg.htaccess

// build htaccess gulp.task("htaccess:build", function() ( gulp.src(path.src.htaccess) .pipe(gulp.dest(path.build.htaccess)) //last opp til bygg));

Generell konstruksjon

For at vi ikke trenger å bygge hver del separat, la oss skrive en oppgave for den generelle konstruksjonen:

// bygg alt gulp.task("build", [ "html:build", "jshint:build", "js:build", "sprites:build", "css:build", "fonts:build", " htaccess:build", "image:build", "imagescontent:build" ]);

Rydd opp i bygget

Noen ganger er det nødvendig å rydde opp i byggekatalogen helt. Her vil følgende oppgave komme oss til hjelp:

// clean build folder gulp.task("clean", function (cb) ( rimraf(path.clean, cb); ));

Se eller spor endringer i sanntid

En av de viktigste og mest nyttige funksjonene til Gulp er klokkefunksjonen, som lar deg overvåke i sanntid alle endringer med de produserte filene og, avhengig av dette, utføre spesifikke handlinger:

// watch gulp.task("watch", function()( //build html i tilfelle endring watch(, function(event, cb) ( gulp.start("html:build"); )); //build sprites i tilfelle endring av watch(, function(event, cb) ( gulp.start("sprites:build"); )); //bygg kontekstbilder ved endring av watch(, function(event, cb) ( gulp. start(" imagescontent:build"); )); //build css i tilfelle endring av watch(, function(event, cb) ( gulp.start("css:build"); )); //sjekk js i tilfelle of change watch(, ["jshint"]); //build js i tilfelle change watch(, function(event, cb) ( gulp.start("js:build"); )); //bygg statiske bilder i case of change watch(, function (event, cb) ( gulp.start("image:build"); )); //build fonts in case of change watch(, function(event, cb) ( gulp.start(" fonts:build"); )) ; //bygg htaccess i tilfelle endring av watch(, function(event, cb) ( gulp.start("htaccess:build"); )); ));

Standardhandlinger

Standardhandlingene er hvilke oppgaver oppgavebehandlingen vil utføre når du skriver inn gulp-kommandoen i konsollen:

// standard handlinger gulp.task("standard", ["bygg", "se", "koble til"]);

I vårt tilfelle vil vi som standard bygge prosjektet vårt, aktivere klokkemodus og starte serveren.

Kommandoer for kommandolinjen

Alle galp-kommandoer for kommandolinjen består av to deler - selve gulp-kommandoen og navnet på oppgaven atskilt med et mellomrom. Her er en liste over kommandoer som gjelder for konfigurasjonen vår:

  • gulp - hovedkommando, kjører standardoppgaven
  • gulp build - bygg alt
  • gulp watch - start watch
  • gulp clean - ren byggekatalog
  • gulp connect - start server
  • gulp html:build - HTML build
  • gulp jshint:build - sjekk JS for feil
  • gulp js:build - JS build
  • gulp sprites:build - sprite build
  • gulp image:build - statisk bildebygg
  • gulp imagecontent:build - dynamisk bildebygg
  • gulp cssOwn:build - tilpasset css build
  • gulp cssVendor:build - ekstern CSS build
  • gulp css:build - generell CSS build
  • gulp fonts:build - font build
  • gulp htaccess:build - build.htaccess

På dette tidspunktet er konfigurasjonen av gulpfile.js fullført.

Kopier startpakken til prosjektet

La oss først gå gjennom konsollen i mappen der vi utvikler, for eksempel cd develop/example og kopiere alt fra startpakkekatalogen til prosjektet vårt cp -a ~/develop/start/. ~/utvikle/eksempel/

Denne metoden for kopiering er mest praktisk, fordi. vil nøyaktig kopiere alt, inkludert skjulte .gitignore-filer, etc.

Konklusjon

Ved hjelp av denne veiledningen har vi utarbeidet en startpakke for bruk av Gulp i våre prosjekter for Front-end-utvikling.

Denne pakken er også tilgjengelig på GitHub.

Post Scriptum

Denne artikkelen er ikke endelig og vil bli oppdatert avhengig av endringene og forbedringene.

På den tiden da tomtene var små, var det ikke behov for en egen front-end-montering. Imidlertid har volumet og kompleksiteten til CSS og JS økt, og visningen det er praktisk å utvikle i har blitt veldig forskjellig fra visningen du trenger for å vise resultatet til brukeren. Oppgaver som sammenkobling (liming) av filer, minimering av kode og til og med forhåndskompilering dukket opp. Resultatet av dette var spesialiserte front-end byggesystemer, som vi skal snakke om.

Selvfølgelig, så snart behovet for montering ble håndgripelig, begynte verktøyene som ble brukt av backend umiddelbart å krype til frontend. Hovedproblemet deres og grunnen til at de for øyeblikket blir brukt mindre og mindre for front-end er at de ikke er helt skreddersydd til dens spesifikasjoner, siden prosjektstrukturen, teknologiene som brukes og utviklingssyklusen er veldig avhengig av oppgavene til prosjektet og kan variere betydelig. Den samme Ant, for eksempel, har en detaljert syntaks og er ikke spesielt i stand til å gjøre ting som er nødvendige for frontend: det er svært få innebygde oppgaver, og den utvider seg dårlig. Hvis vi snakker om GNU-fabrikat, så er det mye mer allsidig, siden det opererer med skallkommandoer. Blant ulempene er det nødvendig å nevne den spesielle syntaksen som må studeres videre, behovet for å kjenne skallet godt, samt tendensen til at Makefile raskt blir mer kompleks ettersom monteringskravene øker.

La oss se på et mellomstort nettsted med en standardstruktur og prøve å liste opp hovedbyggtrinnene som det går gjennom. For enkelhets skyld, la oss anta at du ikke gidder å lage forskjellige JS-filer for forskjellige sider, men du vil beholde noen små filer i utviklingsmiljøet ditt for å støtte en slags modularitet. Det ser vanligvis omtrent slik ut:

/libs/ jquery.min.js underscore.min.js /js/ common.js carousel.js popups.js ....

Byggesystemet gjør vanligvis følgende:

  • setter sammen alle JS-filer til én (i riktig rekkefølge, vi ønsker ikke å laste inn skriptene våre før jQuery);
  • sjekker JS-koden for gyldighet (for eksempel ved å bruke JSHint);
  • minimerer koden, tilslører den om nødvendig (det vil si gjør den uforståelig);
  • setter sammen CSS-filer (rekkefølgen er også viktig her, siden egenskaper ofte omdefineres);
  • minifiser CSS;
  • legger filene i en egen katalog, hvorfra du inkluderer dem i HTML-en.

Ofte er dette enkle opplegget komplisert av tilleggskrav: tester kjøres, CSS-forprosessorkode kompileres, bilder optimaliseres, maler kompileres.

Alle disse oppgavene, og enda flere, kan løses med moderne monteringsverktøy. Vi vil vurdere de mest populære løsningene som fungerer på Node.js-plattformen. Deres felles fordel er et tydelig språk som alle frontend-utviklere kan (eller tror de kan), et innledende fokus på å løse front-end-problemer og et tydelig Node.js-miljø der du kanskje allerede utvikler applikasjonen din.

Grynte

Grunt er det eldste, viktigste og mest populære byggeverktøyet. Nesten alle byggesystemene vi har sett på sammenligner seg med Grunt på en eller annen måte, og noen har dukket opp som raskere eller enklere alternativer til det. Til tross for dette har den et par betydelige ulemper.

For det første, som mange frontend-utviklere påpeker, er Grunt ordrik. For å sette opp et enkelt byggesystem trenger du en konfigurasjon for hundre linjer. Imidlertid er dette i seg selv ikke en slik ulempe: konfigurasjonen er ganske enkel å lese, og på grunn av populariteten til Grunt, er det vanligvis ikke vanskelig å finne en ferdig konfigurasjon for en typisk oppgave.

For det andre ble Grunt utviklet som et universelt produkt, det vil si at du på grunnlag av det kan løse nesten alle oppgaver knyttet til å bygge et prosjekt. Det er kult, men du må betale for allsidighet. Som nevnt detaljerthet og hastighet. Sammenlignet med andre Node.js byggesystemer, er Grunt merkbart tregere, og mest frustrerende, har den en tendens til å avta etter hvert som prosjektet vokser. Uten å gå inn på detaljene i Grunts arkitektur, ligger grunnen i det faktum at hver gang du skal bygge for eksempel en JS-fil, bygger den opp alle JS-filer på nytt. Du kan prøve å fremskynde byggeprosessen ved å manuelt skrive de nødvendige koblingene mellom filene, men på et prosjekt med et komplekst tre av filavhengigheter kan dette være altfor komplisert.

Til tross for alt dette har Grunt et enormt økosystem: hundrevis av plugins, tusenvis av prosjekter, milliarder av utviklere, det er det. Det vil si at ikke bare Grunt er universell, men også en plugin for oppgaven din er sannsynligvis allerede skrevet.

Oppsummert er Grunt et godt valg for små til mellomstore prosjekter, spesielt hvis du ikke har satt opp noen byggesystemer før. Et stort fellesskap, en haug med plugins, tydelig dokumentasjon og til og med artikler og rapporter på russisk for de uheldige menneskene som ikke kan leve uten det. Og selvfølgelig, hvis Grunt i fremtiden, av en eller annen grunn, slutter å passe deg, kan du alltid bytte til et annet system uten mangler.

gulp

Gulp er et byggesystem i aktivt utvikling. Arkitekturen er basert på bruk av tråder i Node.js, som lar deg ikke skrive midlertidige filer og mapper til disk. De viktigste fordelene med Gulp er hastigheten og kortheten til konfigurasjonen. Dessuten, hvis den første er udiskutabel, oppnås korthet sammenlignet med Grunt ganske enkelt på grunn av dens forskjellige struktur. Hvis du i Grunt-konfigurasjonen opererer individuelt med plugins og konfigurerer hver av dem, må du i Gulp-konfigurasjonen beskrive prosessen som hver fil (eller sett med filer) må gjennom for å bygges. Her er et levende eksempel på kompilering av SASS:

Gulp.task("styles", function() ( return gulp.src("styles/*.scss") .pipe(sass(( style: "expanded" ))) .pipe(rename((suffiks: ".min) "))) .pipe(minifycss()) .pipe(gulp.dest("build/styles/css")); ));

I den første linjen registrerer vi en oppgave for Gulp named styles . Deretter beskriver vi sekvensielt hva som må gjøres med hver av filene som samsvarer med styles/*.scss-masken: kompiler SASS, legg til .min i filnavnet, minifiser det, legg det i den siste katalogen. Hvis vi trenger å gjøre noe annet med denne filen, legger vi ganske enkelt til den passende kommandoen, for eksempel.pipe(legg til en kommentar med en ASCII-enhjørning i begynnelsen av filen) (Jeg håper de endelig lager en plug-in for denne hverdagen oppgave). Jeg liker denne tilnærmingen til å skrive en konfigurasjon mer: den beskriver bedre hva som egentlig skjer med filene dine.

Selvsagt, mens Gulp taper for Grunt når det gjelder antall plugins, finnes det plugins for mange oppgaver. Mest sannsynlig vil eksisterende plugins være nok for deg, og hvis noe virkelig mangler, kan du alltids skrive dine egne (bare tuller). Det finnes forresten en gulp-grunt-pakke som lar deg kjøre Grunt-oppgaver fra Gulp hvis du virkelig trenger det.

Hvis du liker denne tilnærmingen til bygging, er hastighet viktig, og du trenger ikke utføre spesifikke oppgaver som det kun finnes en plug-in for Grunt, så kan Gulp være et godt valg. Gulp er fortsatt Grunts største konkurrent til dags dato.

Brokkoli

Det yngste av byggeverktøyene som vurderes er nå faktisk under utvikling. Broccolli-utviklerne legger ikke skjul på at de ble inspirert av Gulp, men de anser noen av konseptene som ligger til grunn for å være feilaktige. For eksempel valgte de å cache alle mellomliggende byggeresultater (implementert av hver av pluginene) for å få fart på byggingen, i stedet for å delvis gjenoppbygge bare de nødvendige filene. De likte heller ikke at Gulp fungerer best med å transformere én fil til én finale, altså én etter én. For å forbedre ytelsen til mange-til-en-operasjoner, utvikler Gulp for tiden et komplekst opplegg med etablering av et virtuelt filsystem, som for utviklerne av Broccolli ser ut til å være en unødvendig komplikasjon og en manifestasjon av svakheten til de originale konseptene av Gulp. Broccolli opererer i utgangspunktet med begrepene trær i stedet for filer og utfører bare transformasjoner av trær til andre trær (selv om de er degenererte og fra ett toppunkt).

En svært rimelig teoretisk tilnærming til monteringsproblemet løser ikke problemet med antall utvidelser til Broccolli. Dessverre er det omtrent to dusin av dem, og de utfører bare de mest grunnleggende oppgavene. Hvis du vil prøve noe nytt, se på Broccolli, det er raskt nok, det utvikles aktivt, men sannsynligvis er det fortsatt fuktig for seriøse prosjekter.

Brunsj

Brunch ble skapt med samme mål – å slå Grunt på alle fronter, men nærmet seg det fra en helt annen vinkel. Brunch-utviklerne bestemte seg for å ta en god forståelse av fagområdet, det vil si å lage et mindre allsidig verktøy som vil bli spisset spesielt for front-end-oppgaver, for eksempel uten noen innstillinger, forstå at *.js er en fil med scripts, *.coffee er CoffeeScript og så videre. Brunsj er ganske rask, mye raskere enn Grunt, men litt tregere enn Gulp. De utvilsomme fordelene med Brunch inkluderer en veldig kompakt konfigurasjon, som er flere ganger mindre enn den til Grunt og Gulp. Her er for eksempel en enkel brunsjkonfigurasjon:

Exports.config = filer: javascripts: joinTo: "javascripts/app.js": /^app/ "javascripts/vendor.js": /^(bower_components|vendor)/ stylesheets: joinTo: "stylesheets/app.css" rekkefølge :after: ["vendor/styles/helpers.css"] maler: joinTo: "javascripts/app.js"

Merk at konfigurasjonen kan skrives både i CoffeeScript (som i dette tilfellet) og i vanlig JS. Vi lager en vanlig modul som returnerer JSON med byggeinnstillinger.

Legg merke til joinTo og bestillingsnøklene. Dette er domenekunnskapen jeg snakket om - på konfigurasjonsnivå vet Brunch at du mest sannsynlig vil slå sammen filer, noen før andre. Dette er det som lar deg erstatte 400 linjer i Grunt-konfigurasjonen med 20-30 linjer med brunsj.

I tillegg er brunsj-økosystemet mye mindre enn Grunt og til og med Gulp. Det er omtrent 50 plugins (sammenlignet med 450+ for Gulp, for eksempel), utviklingen er ikke veldig rask, generelt er alt ganske trist her.

For å oppsummere: Hvis du virkelig liker korte konfigurasjoner, er hastighet viktig, men du trenger ingen spesielle handlinger på byggestadiet, så kan du se på Brunch. Forvirret, selvfølgelig, et lite antall plug-ins, men kanskje situasjonen vil endre seg.

ENB

Og til slutt, den søteste delen. Jeg vil snakke om byggesystemet utviklet på Yandex av Marat Dulin, som kalles ENB. Dette er det vi for tiden bruker i prosjektet vårt. Dens tilnærming er fundamentalt forskjellig fra alle de beskrevne systemene: den ble opprinnelig opprettet for å jobbe med prosjekter ved å bruke BEM-metodikken, selv om, som forfatteren bemerker, plattformen er fri fra BEM-ideologien og kan brukes for alle prosjekter med en passende struktur .

Kort fortalt, hva er poenget. I ENB opererer vi med konseptet om et mål, det vil si den endelige filen som må samles inn, eller en node (mappe, i det generelle tilfellet, en side), som et bestemt sett med filer må samles inn for . For å bygge målfilen bruker vi en rekke teknologier (grovt sett plugins i Grunt-termer, selv om teknologiene er mindre og mer spesialiserte). Først av alt bestemmer ENB det første settet med filer som er nødvendig for å bygge målene (dette gjøres av flere grunnleggende teknologier som fungerer med BEM-metodikken som standard, det vil si at de ser etter en *.bemdecl-fil som inneholder avhengighetene av denne noden på forskjellige blokker), distribuerer det fullt ut er et avhengighetstre (når blokken siden din avhenger av avhenger av en annen, er begge inkludert i riktig rekkefølge) og finner deretter filene som trengs for hver registrerte teknologi. Deretter følger ENB sekvensen av filtransformasjoner beskrevet i konfigurasjonen (her kan du spore litt analogi med Gulp). Til tross for noen forskjeller fra standard byggesystemtilnærming, når du først forstår de grunnleggende konseptene, er det ganske enkelt å jobbe med ENB.

De viktigste fordelene med ENB: monteringshastighet, på grunn av et fleksibelt hurtigbuffersystem og muligheten til å utveksle mellomliggende data mellom forskjellige teknologier, parallellisere uavhengige prosesser og separere de tyngste teknologiene i separate underprosesser. Det er uvanlig enkelt å skrive nye teknologier til ENB hvis du ikke er fornøyd med oppførselen til standard.

Ulempene inkluderer det faktum at ENB-konfigurasjonen er ganske omfattende, siden det er mulig å kontrollere absolutt alle stadier av sammenstillingen. I tillegg ble ENB fortsatt skrevet for BEM-metodikken, og å knytte den til et prosjekt med en helt annen struktur vil kreve ekstra bevegelser. Det er ikke mange skriftlige teknologier for ENB (ca. 60), men den takler de fleste oppgavene til BEM-prosjekter med et smell.

For å oppsummere: ENB er det beste valget for prosjekter basert på BEM-metodikken, som jeg personlig synes er best egnet for mellomstore og store nettsteder, da organiseringen av koden i blokkerer stasjoner og pip. Den er veldig rask, samler dusinvis av sider og hundrevis av filer på sekunder, er enkel å sette opp og behagelig å bruke. Hvis prosjektet ditt er stort, blir du forvirret i koden og redigerer tusenvis av linjer med filer, jeg anbefaler deg å studere BEM mer detaljert som en måte å organisere strukturen til front-end-prosjekter på. Og når du elsker BEM, vil du elske ENB som det mest opprinnelige byggeverktøyet for BEM-prosjekter.

Denne håndboken inneholder en beskrivelse av nyttige og mest brukte front-end-verktøy. Du vil kunne lære prosessen med å installere verktøy og hovedpunktene for å jobbe med dem.

NPM

Introduksjon

Under utviklingen av et prosjekt er det ofte nødvendig å legge til tredjeparts biblioteker og plugins. Som et resultat må utvikleren søke etter den nødvendige avhengigheten, laste ned, pakke ut arkivet og kopiere filene til prosjektet. Pakkeforvaltere vil hjelpe til med å automatisere dette rutinearbeidet.

pakkeansvarlig- programvare som lar deg administrere prosessen med å installere, avinstallere, konfigurere og oppdatere ulike komponenter.

Å legge til tredjepartsbiblioteker ved å bruke pakkebehandlingen erstattes av et par kommandoer i terminalen.

En av pakkeforvalterne som brukes i frontend-prosjekter er NPM.

npm(Node.js Package Manager) er en pakkebehandling inkludert i Node.js. Brukes til å laste ned pakker fra npm-skyserveren, eller for å laste opp pakker til denne serveren.

Offisiell side

Begynnelsen av arbeidet

For å installere npm må du laste ned og installere NodeJS (npm blir automatisk installert): https://nodejs.org/en/.

Bruk

Installerer pakker

En pakke er en eller flere JavaScript-filer som representerer en slags bibliotek eller verktøy. For å installere en pakke ved hjelp av npm, kjør følgende kommando:

npm installere<название пакета>

Nøkkelen brukes til å installere pakken globalt -g. Etter installasjonen er pakken, sammen med kildene, plassert i katalogen node_modules/.

Versjonssjekk

For å sjekke gjeldende versjon av npm, må du kjøre kommandoen:

Sette opp konfigurasjonsfilen

Fil package.json inneholder informasjon om søknaden din: navn, versjon, avhengigheter osv. Enhver katalog som inneholder denne filen tolkes som en Node.js-pakke.

For å lage en fil package.json du må kjøre kommandoen:

npm init

Etter det må du fylle ut litt informasjon om prosjektet.

Denne filen vil lagre navn og versjoner av alle pakkene som trengs i prosjektet. Med kommandoen npm installere du kan laste ned alle pakkene som er i package.json.

For å installere en pakke og automatisk lagre den i filen package.json, bruk kommandoen:

npm installere<название пакета>--save-dev

Alternativer

Garn

Egenskaper

  • Opprette en webserver og automatisk laste inn siden på nytt i nettleseren når koden lagres, sporing av endringer i prosjektfilene.
  • Bruk av ulike JavaScript-, CSS- og HTML-forbehandlere (CoffeeScript, Less, Sass, Stylus, Jade, etc.).
  • Minifisering av CSS og JS-kode, samt optimalisering og sammenkobling av individuelle prosjektfiler til én.
  • Automatisk oppretting av leverandørprefikser (prefikser til navnet på CSS-egenskaper som nettleserprodusenter legger til for ikke-standardegenskaper) for CSS.
  • Administrer filer og mapper i et prosjekt - opprett, slett, gi nytt navn.
  • Lansering og overvåking av utførelsen av eksterne kommandoer til operativsystemet.
    Arbeide med bilder - komprimering, lage sprites, endre størrelse (png, jpg, svg, etc.).
  • Distribuer (sende til en ekstern server) et prosjekt via FTP, SFTP, etc.
    Tilkobling og bruk i prosjektet av et uendelig stort antall Node.js og Gulp-verktøy, programmer og plugins.
  • Oppretting av ulike prosjektkart og automatisering av annet manuelt arbeid.

Begynnelsen av arbeidet

NodeJS og npm må være installert på systemet.

Trinn 1: For å installere GulpJS globalt ved å bruke npm-pakkebehandleren, kjør følgende kommando:

npm installer gulp -g

Steg 2: Du må installere det for applikasjonen:

npm install --save-dev gulp

Lasting av flere plugins som kan brukes når du bygger et prosjekt, gjøres også ved å bruke npm med følgende kommando:

npm installere<название плагина>--save-dev

Alle installerte plugins er plassert i katalogen node_modules/.

Bruk

Trinn 1: Først må du koble til gulp til prosjektet. For dette i filen gulpfile.js skriv linjen:

var gulp = require("gulp");

Funksjon krever() lar deg koble til plugins fra en mappe node_modules/.

Steg 2: Med en variabel gulp du kan lage oppgaver for å bygge prosjektet:

Gulp.task("eksempeloppgave", funksjon() ());

Metode oppgave tar to parametere: et navn og en funksjon med hoveddelen av oppgaven.
Denne instruksjonen er allerede tilgjengelig. For å gjøre dette, skriv i konsollen:

Gulp eksempelTask

Grunnleggende kommandoer

Nedenfor er et mer komplekst eksempel på en uttalelse:

Gulp.task("eksempelTask", funksjon () ( return gulp.src("kildefiler") .pipe(plugin()) .pipe(gulp.dest("mappe")); ));

La oss analysere kommandoene som brukes i dette eksemplet:

  • gulp.src- utvalg av prosjektkildefiler for behandling av plugin-en;
  • .pipe(plugin())- ring Gulp-plugin for å behandle filen;
  • .pipe(gulp.dest('mappe')) - ut den resulterende filen til målmappen.

Filmasker

Gulp.src-funksjonen tar en filmaske som en parameter. Maskeeksempler:

  • ./ – gjeldende katalog;
  • ../ – overordnet katalog;
  • js/index.js- index.js-filen i js-mappen;
  • js/*.js- alle filer med js-utvidelsen i js-mappen;
  • js/**/*.js- alle filer med js-utvidelsen i js-mappen og dens underkataloger;
  • !js/*.js– ekskludering av filer med js-utvidelsen i js-mappen.

bekker

Bruken av tråder er en av de viktigste fordelene med GulpJS.

Strømmer lar deg overføre noen data sekvensielt fra en funksjon til en annen, som hver utfører en handling på disse dataene.

Funksjon gulp.src() oppretter en strøm av objekter som representerer filene som sendes til den som en parameter. Deretter bruker du funksjonene rør det bygges en rørledning langs hvilken en strøm av objekter overføres. Som en parameter sendes denne funksjonen en plugin som behandler flyten av objekter på en eller annen måte.

Nedenfor er et eksempel på bruk av tråder. I dette eksemplet brukes tredjeparts plugins. gulp-jshint Og gulp-concat, som skal installeres og kobles til gulpfile.js

Funksjon gulp.src tar filer med maske js/*.js. Kjører JSHint og sender ut resultatet. Deretter setter den sammen filene og lagrer til slutt den resulterende filen etter sammenkobling i katalogen dist/.

Gulp.task("eksempel", funksjon () ( return gulp.src("js/*.js") .pipe(jshint()) .pipe(concat("index.js")) .pipe(gulp.dest ("dist")); ));

Tredjeparts plugins

Tenk på et eksempel på bruk av tredjeparts plugins. For å gjøre dette, vil vi lage en js-filsammenkoblingsinstruksjon:

Trinn 1: Først må du inkludere plugin med kommandoen require:

var concat = require("gulp-concat");

Steg 2: Deretter må du lage en oppgave for å sette sammen filer med js-utvidelsen som ligger i js/-katalogen. På slutten blir den resulterende filen plassert i dist/js-katalogen:

Gulp.task("concat", function () ( return gulp.src("js/*.js") .pipe(concat("index.js")) .pipe(gulp.dest("dist/js") ); ));

gulp concat

Tilleggsinformasjon

Du kan også definere en oppgave som vil føre til utførelse av andre oppgaver.

Gulp.task("bygg", ["html", "css"]);

I tillegg er det en metode se for å observere endringer i filer:

Gulp.watch("maske av filer å se på", ["navnet på oppgaven som vil bli utført når filene endres"]);

I gulpfile.js du kan lage en standardoppgave:

Gulp.task("standard", ["oppgave1", ​​"oppgave2"]);

Denne oppgaven startes fra konsollen med kommandoen:

Hovedplugins

  • gulp-autoprefikser– prefikser automatisk CSS-egenskaper;
  • gulp-nettleser-synkronisering- oppretter en tilkobling, hvoretter den automatisk oppdaterer siden når du endrer klient- eller serverfiler;
  • gulp-uncss- Optimalisering av CSS-filer. Programtillegget analyserer HTML-koden og finner alle ubrukte og dupliserte stiler;
  • gulp-csso- CSS-minifier;
  • gulp-htmlmin– enkel HTML-minifier;
  • gulp-htmlhint– HTML-validator;
  • gulp-uglify– JavaScript-minifier;
  • gulp-concat– filsammenkobling;
  • gulp-webserver– lar deg opprette og kjøre en server;
  • gulp-jshint– kontrollere kvaliteten på JS-koden;
  • gulp-sjasmin– kjører jasmintester;
  • gulp-jsdoc- generering av JSDoc-dokumentasjon.

Du finner hele listen over Gulp-plugins her:
http://gulpjs.com/plugins/

Alternativer

GruntJS

Egenskaper

  • Støtte for asynkron testing.
  • Mulighet for å eksponere observatører (observatører) på ulike objekter.

Begynnelsen av arbeidet

For å koble Jasmine til prosjektet ditt, må du laste ned biblioteket og inkludere følgende filer på HTML-hovedsiden:

  • lib/jasmine-*/jasmine.js- selve rammeverket;
  • lib/jasmine-*/jasmine-html.js- registrering av resultater i form av HTML;
  • lib/jasmine-*/jasmine.css- utseende av testresultater;
  • SpecRunner.html- filen som skal åpnes i nettleseren for å kjøre testene.

Synkronisering med instrumenter

GulpJS

Jasmine kan inkluderes i GulpJS-prosjektet:

Trinn 1: Først må du installere gulp-jasmine plugin:

npm installer gulp-jasmine --save-dev

Steg 2: Deretter må du inkludere plugin-en i byggefilen og lage en teststartoppgave:

var jasmin = require("gulp-jasmin"); gulp.task("jasmin", function() ( gulp.src("testfiler") .pipe(jasmin()); ));

KarmaJS

(på slutten av artikkelen er arbeid med dette verktøyet beskrevet mer detaljert)

For å koble til Jasmine i KarmaJS trenger du:

Trinn 1: Installer KarmaJS:

npm installer -g karma-cli

Steg 2: Installer plugins som er nødvendige for å kjøre tester skrevet i Jasmine i Chrome og PhantomJS nettlesere:

npm installer karma-jasmine karma-chrome-launcher karma-phantomjs-launcher

Trinn 3: Installer selve Jasmine:

npm installer -g jasmine

Trinn 4: I karma-konfigurasjonsfilen, koble til plugins og angi banen til testene.

Bruk

Nøkkelord

  • beskrive - definisjon av et sett med tester;
  • it - testdefinisjon;
  • forventer - definisjon av forventningene som sjekkes i testen.

Describe og it-funksjonene tar to parametere: den første er navnet, den andre er funksjonen med koden.

Grunnleggende testeksempel

describe("test suitenavn", funksjon () ( it("testnavn", funksjon () (forvent(2+2).toBe(4); )); ));

Metoder for å sjekke resultater

  • forventer().toBe()– sjekke variabler for likhet (‘===’);
  • forventer().not.toBe()– sjekke variabler for likhet (‘!==’);
  • forventer().toEqual()– sjekke for likhet mellom variabler og objekter, inkludert innhold;
  • forventer().toBeDefined()- sjekk for eksistens;
  • forventer().toBeUndefined()– sjekk for ikke-eksistens;
  • forventer().toBeNull()– sjekke verdien av en variabel for null;
  • forventer().toBeTruthy()- sjekke for sannhet;
  • forventer().toBeFalsy()- se etter falskhet;
  • forventer().toBeLessThan()– kontrollere at verdien må være mindre enn;
  • forventer().toBeGreaterThan()– kontrollere at verdien må være større enn;
  • forventer().toBeCloseTo()– kontrollere at verdien skal være nær et tall;
  • forventer().toMatch()– se etter samsvar med regulære uttrykk;
  • forventer().toContain()– se etter innhold i matrisen;
  • forventer().toThrow()– sjekk av et unntaksanrop;
  • forventer().toHaveBeenCalled()– kontroll av funksjonsanrop.

Ekstra funksjoner

For å unngå å kopiere logikk som brukes i tester, brukes funksjoner førHver/etterHver. De kjører henholdsvis før/etter hver test.

Funksjoner brukes til å teste asynkrone samtaler løper Og venter på.

  • løper- aksepterer en asynkron funksjon for å utføre;
  • venter på- tar tre parametere: den første er en funksjon som skal returnere ekte, hvis asynkron anropsfunksjon løper ble utført, den andre er feilmeldingen, den tredje er ventetiden i millisekunder.
describe("asynchronous call test example", function () ( var resultat = 0; function asyncFunc() ( setTimeout(function() ( resultat = resultat + 2; ), 500); ) it("testnavn", funksjon ( ) ( runs(function () ( asyncFunc(); )); waitsFor(function() ( returnerer resultat === 2; ), "verdien har ikke endret seg", 2000); )); ));

Observatører

Evnen til å spore funksjonsanrop gjøres ved å bruke spionere på. Denne funksjonen tar to parametere: den første er objektet som funksjonen kalles for, den andre er navnet på funksjonen som skal spores.

If(“function call test”, function () ( spyOn(exampleObject, "exampleFunction"); exampleObject.exampleFunction(); expect(exampleObject.exampleFunction).toHaveBeenCalled(); ));

Når testet med spionere på du kan spore antall samtaler, deres parametere og hver samtale individuelt.

For å lage en funksjon uten implementering kan du bruke oppretteSpy. Funksjon oppretteSpy tar et funksjonsnavn for å identifisere.

If(“function call test”, function () ( var example = createSpy(“EXAMPLE”); example(“param1”, “param2”); expect(example.identify).toHaveBeenCalledWith(“param1”, “param2”) ;expect(example.calls.length).toEqual(1); ));

Et stubbeobjekt lages ved hjelp av oppretteSpyObj. Som parametere oppretteSpyObj tar navnet på et objekt og en rekke strenger, som er en liste over metoder på stubbobjektet.

Alternativer

Mokka

Bruk

Dokumentasjon genereres fra kildekodekommentarer.

Oppgaveløpere og byggesystemer øker arbeidet betraktelig ved å automatisere kompilering, testing og andre rutineoppgaver. Som på alle andre felt er det sterk konkurranse i dette markedet. Fram til 2014 dominerte oppgaveløperen grynt blant dem, men senere skilte et lite team seg fra prosjektet og bestemte seg for å lage et alternativt verktøy, gulp, fokusert på å bygge prosjektet.

For å hjelpe deg med å ta et valg, vil vi i rammen av artikkelen vurdere de viktigste oppgavebehandlerne:

  • grynte

og berører også andre midler og metoder for montering.

Ser vi litt fremover, la oss si at vi bruker gulp i WaveAccess. Implementering av verktøyet viste seg å være veldig enkelt: JetBrains produktfamilie (IDEA, WebStorm, ReSharper), som vi har brukt i mange år, har utmerkede plugins for å jobbe med gulp/grunt og npm/nodejs.

Oppgaveleder vs. prosjektbyggesystem: hva er forskjellen?

Oppgavebehandling- et verktøy for å automatisere oppgaver. I konfigurasjonen til løperne kan du skrive navnene på disse oppgavene; funksjonen som utfører dem; plugins for å fremskynde standardhandlinger, men selve oppgavene kan være vilkårlige. For eksempel:

  • Distribusjonsoppgaver (zip prosjektet, last opp prosjektet til en ekstern server, etc.)
  • Prosjektmonteringsoppgaver (minifisering, optimalisering, kontroll av koden for gyldighet, etc.)
  • Oppgaver for datamigrering mv.

Eksempler på slike verktøy er grynt og gulp.

Monteringssystem er et verktøy som løser bare én typisk oppgave med å bygge et prosjekt på et java-skript, som inkluderer:

  • sammenkobling,
  • sjekke koden for gyldighet,
  • kodeminifisering osv.

Slike verktøy inkluderer Webpack, Broccoli, Brunch, Browserify og andre.

Alle slike frontend-oppgaver kan utføres automatisk på andre måter: for eksempel ved å bruke npm run, som vi også vil snakke om i artikkelen.

Eksempel

Vurder en gulp-fil for å bygge prosjektet:

Const gulp = require('gulp'); const coffee = require('gulp-kaffe'); const concat = require('gulp-concat'); const uglify = require('gulp-uglify'); const imagemin = require('gulp-imagemin'); const sourcemaps = require('gulp-sourcemaps'); const del = require('del'); )

Men montering er et spesielt tilfelle av en stor typisk oppgave. For gulp kan du skrive en annen konfigurasjon - si for distribusjon:

var gulp = require("gulp"); var zip = require("gulp-zip"); var del = require("del"); var install = require("gulp-install"); var runSequence = require("run-sequence"); var awsLambda = require("node-aws-lambda"); gulp.task("clean", function(cb) ( del(["./dist", "./dist.zip"], cb); )); gulp.task("copy", function() ( return gulp.src("index.js") .pipe(gulp.dest("dist/")); )); gulp.task("node-mods", function() ( return gulp.src("./package.json") .pipe(gulp.dest("dist/")) .pipe(install((produksjon: true) )); )); // Rydd opp i alle aws-sdk-kataloger fra node_modules. Vi trenger ikke // å laste dem opp siden Lambda-forekomsten allerede // vil ha den tilgjengelig globalt. gulp.task("clean-aws-sdk", function(callback) ( del(["dist/node_modules/** /aws-sdk", tilbakeringing); )); gulp.task("zip", function() (retur gulp.src(["dist/**/*", "!dist/package.json"]) .pipe(zip("dist.zip")) .pipe(gulp.dest("./")); )); gulp.task("opplasting", function(callback) ( awsLambda.deploy("./dist .zip", require("./lambda-config.js"), tilbakeringing); )); gulp.task("deploy", function(callback) (retur runSequence(["clean"], ["copy"] , ["node-mods"], ["clean-aws-sdk"], ["zip"], ["opplasting"], tilbakeringing); ));

A, du kan beskrive nye oppgaver som kombinasjoner av eksisterende:

Gulp.task('deploy', gulp.series ('clean', 'copy', 'node-mods', 'clean-aws-sdk', 'zip', 'upload'));

Der ligger forskjellen. La oss nå se på hovedverktøyene.

gulp vs. grynte

Så vi har to oppgaveløpere: gulp og grynt. Begge bruker node.js og npm og har i oppgave å bruke javascript.

Ved første øyekast er de like, men gulp har noe som gjør det mer praktisk å bygge: muligheten til å behandle oppgaver parallelt og en kompakt konfig, konsis API. La oss se nærmere på hvordan de fungerer.

Streaming av data

Foran oss er en tilskuddsfil som setter sammen og behandler CSS.

Det viser at grunt kjører på hver prosessoppstart:

    åpner en fil;

    starter prosessen;

    lagrer endringer;

    lukker den behandlede filen for å forhindre at neste prosess forstyrrer den;

    skriver filen til målmappen.

Det vil si at kjeden inkluderer å lage flere midlertidige mapper og lagre mellomfiler:

Plugins er skrevet av forskjellige forfattere. For at hver plugin skal fungere med filer, uten å lagre, må filer representeres som objekter. I gulp utføres denne oppgaven av det virtuelle filsystemet Vynyl-FS. Og gulp sender umiddelbart filen til neste prosess uten å lage midlertidige filer og uten å lagre på disk.

Den samme konfigurasjonen for gulp er allerede mer kompakt:

Dens generelle operasjonsmekanisme er strømbehandling av filer uten å skrive til disk:

Oppgavesekvens

Det er en annen forskjell: gulp utfører oppgaver asynkront som standard. Dette har både plusser og minuser. I den samme konfigurasjonsfilen gir vi kommandoen for å lese filene fra dev/*scss-katalogen og sende dem til SASS.

Tråder sender resultatet til .pipe. .pipe-metoden lar deg samle resultatet i en buffer i deler, og når den er full, umiddelbart sende informasjon til strømmen for lesing, ennå ikke ferdig med å motta innholdet i katalogen.

Sekvensiell utførelse av oppgaver gjør gulp rask og kraftig, men noen ganger blir det nødvendig å utføre oppgaver synkront, som i grynt. Problemet kan løses gjennom tilbakeringing, strømretur eller et løfte . Oppgaven analyseres nærmere på Habré. Det er også et alternativt alternativ på selve npm.js-siden

Hvis du bruker grunt, men er interessert i å streame data, kan den samme Vynyl-FS-modulen brukes til å implementere den i grunt.

Det kortfattede gulp API har bare 5 metoder:

    Oppgave(navn, fn). Registrerer en funksjon med et navn. Du kan spesifisere en avhengighet av andre oppgaver hvis du trenger å utføre dem først.

    Kjør(oppgaver...). Utfører oppgaver.

    Se (glob, fn). Utfører en funksjon hvis filen i stedet for glob endres.

    src(glob). Den tar en maske av filer som en parameter og returnerer en strøm som representerer disse filene. Strømmen kan deretter sendes som input til plugins.

    Dest(mappe). Lagrer filer i den angitte mappen.

Jeg vil spesielt merke meg tilstedeværelsen av .watch() i prosjektets "native" API, fordi sporing av konstante filendringer er den viktigste komponenten i bygget. Kortheten til API-en gjør at denne oppgavelederen kan fokusere på hovedoppgaven sin - byggeprosjekter.

Alternativer til gulp og grynt

Til tross for populariteten til gulp (mer enn 130 nedlastinger per dag) og grynt (mer enn 86 nedlastinger per dag ifølge npmjs.com), ser utviklerne sine ulemper ved disse systemene: for eksempel avhengighet av plugins, ufullstendig dokumentasjon, upraktisk feilsøking. Alternativt kan du vurdere prosjektbyggingssystemer (som Broccoli og Webpack) eller npm-skript.

Prosjekt bygge systemer

La oss se på flere alternative løsninger på Node.js-plattformen. De kan erstatte gulp og grynt for å bygge et prosjekt.

Dette systemet, i likhet med gulp, oppsto som en konkurrent til grynteoppgaveløperen, men utviklerne tenkte det i utgangspunktet som en byggeassistent med alle fordeler og ulemper. Uten innstillinger vil den "forstå" at *.js er en fil med skript, *.coffee er CoffeeScript; konfigurasjonen er mer kompakt. Den vil imidlertid ikke kunne utføre noen vilkårlige handlinger på monteringsstadiet.

Her er konfigurasjonsfilen for brunsj. Det er skrevet i CoffeeScript (du kan også skrive i JS):

Exports.config = filer: javascripts: joinTo: "javascripts/app.js": /^app/ "javascripts/vendor.js": /^(bower_components|vendor)/ stylesheets: joinTo: "stylesheets/app.css" rekkefølge :after: ["vendor/styles/helpers.css"] maler: joinTo: "javascripts/app.js"

Her vil jeg ta hensyn til joinTo- og ordreoperatørene. På konfigurasjonsnivået forstår Brunch at den må bygge filene i riktig rekkefølge. Som et resultat tar konfigurasjonen 20-30 linjer.

Brokkoli

Et indieverktøy som er under utvikling. Utviklerne ønsket å konkurrere med gulp allerede.

Sammenlignet med gulp, bruker brokkoliverktøyet forskjellige prinsipper:

    Bygg fart. Hver plugin implementerer mellomliggende bufring av byggeresultater i stedet for å delvis gjenoppbygge bare filene du trenger.

    Trær i stedet for filer. Gulp er best til å transformere én fil til én siste fil. Brokkoli bruker bare trær som standard, ikke filer, og transformerer dem til andre trær (degenerert fra et enkelt toppunkt).

For øyeblikket utvikler verktøyet aktivt, nye plugins dukker opp, men det er for tidlig å bruke det til seriøse prosjekter: det er ikke nok plugins ennå.

Webpack er et fleksibelt modulbasert byggesystem. Den har en uvanlig syntaks, men den aksepterer selv enhver modulsyntaks.

Da de innså at de måtte konkurrere med giganter som gulp, bestemte skaperne seg for å gjøre livet enklere for oss når de utvikler store prosjekter. Og lagt til verktøyet:

    Evnen til å automatisk bygge et tre av avhengigheter og ressurser.

    Praktiske verktøy for implementering av dynamisk lasting.

    Kompatibel med nesten alle moduler (AMD, UMD, ES 2015, Common JS, tredjepartsmoduler basert på dem).

    Kompatibel med forprosessorer (SASS, Babel, Coffee Script, Type Script, etc.).

    Live Reload (asynkron lasteteknologi, der nettleseren ikke oppdaterer hele sider, men individuelle applikasjoner).

    Muligheten til å dele kode og generere flere bunter, og unngå opprettelsen av en tung bundle.js.

    Evne til å optimalisere kode.

Separat kan vi merke oss en fleksibel tilnærming til avhengigheter. Modulen kan være JS, CSS og HTML-filer, og til og med JPEG med PNG. Du kan bruke require("myJSfile.js") og require("myCSSfile.css"), dele og gjenbruke deler av artefakten.

Flere detaljer om funksjonene, verktøykonfigurasjon, plugins finner du på Github, i presentasjonen med Fronttalks: Webpack Deep Dive.

npm-skript

Byggeoppgaver kan også løses ved hjelp av npm-skript. Mange mennesker blir skremt av denne ideen: det er få funksjoner, skriptene er ikke raske nok sammenlignet med gulp eller Webpack. Disse manglene er imidlertid overdrevet.

Funksjoner av npm-skript

Npm-skript løser ganske mange oppgaver. Så du kan for eksempel implementere trap-skript:

( "name": "npm-scripts-example", "version": "1.0.0", "description": "npm-skripteksempel", "scripts": ( "prebuild": "ekko jeg kjører før byggeskriptet ", "build": "cross-env NODE_ENV=produksjonsnettpakke" "postbuild": "ekko jeg kjører etter byggeskriptet") ) )

Skriptene vil bli lastet i rekkefølge i henhold til prefikser: prebuild, for eksempel, starter før build fordi den har et prefiks. Følgelig vil postbuild lastes sist. npm run build-kommandoen vil kjøre dem i riktig rekkefølge.

Du kan kalle ett skript fra et annet for å dekomponere komplekse oppgaver. For eksempel, her kaller prebuild-oppgaven den rene oppgaven.

( "name": "npm-scripts-example", "version": "1.0.0", "description": "npm scripts example", "scripts": ( "clean": "rimraf ./dist && mkdir dist ", "prebuild": "npm renne", "build": "cross-env NODE_ENV=produksjonsnettpakke" ) )

Hvis oppgaven blir for kompleks, kan du alltid kalle en egen fil:

( "name": "npm-scripts-example", "version": "1.0.0", "description": "npm scripts example", "scripts": ( "build": "node build.js") )

På grunn av streaming har gulp blitt mye mer praktisk for byggeoppgaver enn grynting. Men det kan også implementeres via npm. På Windows og Unix utføres streaming som standard, uten å lagre mellomfiler.

For eksempel, på Unix, kan du grep innholdet i en fil og overføre den til en ny fil:

Grep «Mitt navn» bigFile.txt > linesThatHaveMyName.txt

Redirect(>) dirigerer de nødvendige linjene til målfilen. Oppgaven utføres uten å lagre mellomfiler.

Men det er også en ulempe: du kan ikke legge igjen kommentarer i package.json. Løsningen kan være å lage korte skript med klare navn, rettet mot en liten oppgave. Spørsmålet om å erstatte oppgaveløpere med npm-skript er godt dekket mer detaljert i den engelske artikkelen Why I Left Gulp and Grunt for npm Scripts.

Utfall

Det er stor konkurranse på markedet mellom verktøy for automatisering av rutineoppgaver (som gulp og grynt), samt verktøy for automatisering av prosjektbygg (Webpack, Broccoli, Medusa, Browserify, etc.).

Hvis du ser på oppgaveløpere, er gulp enklere, mer forståelig og mer produktiv enn grynt: den vinner ved å spare på diskoperasjoner. Men grunt har flere plugins (det finnes for eksempel en plugin for testing). På grunn av dette har han mange fans.

Hvis vi bare snakker om monteringen, har gulp alle fordelene fremfor grynt:

    En strømmearkitektur for kjetting av filer, som leveres av Vynyl-FS-modulen.

    Som standard - asynkron utførelse av oppgaver.

    Kortfattet API med kun 5 funksjoner.

Samtidig er Webpack et like interessant verktøy for å bygge. Den inkluderer Live Reload-teknologi, som øker hastigheten på nettleseroppdateringer. Dette er et stort pluss: teknologien sparer tid ved å trykke på oppdateringsknappen, som utviklere må trykke på hele tiden. Gulp har også Live Reload, men Webpack er vanskelig å sammenligne med gulp eller grynt, siden den er "skjerpet" kun for å bygge og ikke "vet hvordan" den skal løse vilkårlige oppgaver.

Alle disse løsningene er perfekt integrert med JetBrains-produktfamilien, men vi i WaveAccess foretrakk grynt på grunn av de brede mulighetene for både layoutdesignere og frontend-spesialister.

Har du spørsmål og trenger å utvikle et nettprosjekt, skriv til oss på [e-postbeskyttet]

  • frontenden
  • Grynte
  • gulp
  • Oppgaveløpere