Docker: Pokretanje aplikacija svuda


Uvod u Docker svet

Šta je Docker?

Docker je platforma koja omogućava programerima da jednostavno kreiraju, implementiraju i pokreću aplikacije unutar kontejnera.

Šta su to kontejneri?
Kontejneri se mogu shvatiti kao lagane virtuelne mašine, ali su dosta brži i manje zahtevni od njih, oni sadrže sve što je potrebno za pokretanje aplikacije: kod, biblioteke i podešavanja operativnog sisteme.

docker image

Zašto koristiti Docker?

  1. Rad aplikacije na različitim sistemima

    Kada aplikacija radi u kontejneru, onda ona može raditi bilo gde, i lokalno ili u nekom udaljenom serveru. Kontejneri omogućavaju aplikacijama da rade konzistentno u različitim okruženjima a to se naručito “oseti” kod timova koji razvijaju aplikaciju na različitim računarima koristeći različite operativne sisteme, kao npr.:

    • Programer A (Windows): Razvija aplikaciju u Docker kontejneru.
    • Programer B (Mac): Testira aplikaciju u Docker kontejneru.
    • Server za produkciju (Linux): Pokreće aplikaciju u istom Docker kontejneru.

    Bez Docker-a, svaki programer bi morao instalirati sve potrebne alate i biblioteke na svom računaru, što može dovesti do problema sa kompatibilnošću i reproduktivnošću. A ako se koristi Docker onda svi programeri koriste jednu istu Docker sliku, što im omogućava da razvijaju i testiraju aplikaciju u identičnom okruženju. Na kraju, aplikacija se prenosi na produkciju bez brige o različitim verzijama biblioteka ili softvera na produkciskom serveru.

  2. Izolacija aplikacije

    Kontejneri omogućavaju svakoj aplikaciji da radi u svom odvojenom okruženju, bez međusobnog ometanja. Ovo može biti veoma bitno kod kompanija koja razvijaju ili hostuje dve različite aplikacije a koje zahtevaju različite verzije MySQL baze podataka. U tom slučaju je idealno da se koristi Docker jer se tada svaka aplikacija može smestiti u svoj Docker kontejner sa odgovarajućom verzijom MySQL-a, kao u sledećem primeru:

    • Aplikacija 1 (MySQL 5.7): Pokreće se u Docker kontejneru sa MySQL 5.7
    • Aplikacija 2 (MySQL 8.0): Pokreće se u Docker kontejneru sa MySQL 8.0

    Ili kada tim radi na aplikaciji koja zavisi od specifičnih verzija Node.js-a, NPM-a ili nekih drugih biblioteka. U tom slučaju kada se koristi Docker onda tim kreira Docker sliku koja sadrži sve potrebne zavisnosti, pa se na taj način pokreće aplikacija u potpuno istom okruženju, bez brige o verzijama biblioteka.

  3. Skalabilnost aplikacije

    Docker omogućava lako skaliranje aplikacija horizontalno (dodavanje novih instanci), pa ako kompanija doživljava nagli porast saobraćaja na svojoj e-commerce platformi onda se sistem lako skalira dodavanjem dodatnih kontejnera za rukovanje većim opterećenjem, kao npr.:

    • Web serveri: 10 Docker kontejnera sa Nginx-om
    • API serveri: 15 Docker kontejnera sa aplikacijom
    • Web serveri: 15 Docker kontejnera sa MySQL-om

Osnovni Docker koncepti:

  • Docker Image (Slika): Template za stvaranje kontejnera. Definiše kako će izgledati kontejner.
  • Docker Container (Kontejner): Pokrenut primerak Docker slike.
  • Dockerfile: Datoteka s uputstvima kako kreirati Docker sliku.
  • Docker Hub: Repozitorijum za deljenje i preuzimanje Docker slika.

Instalacija Docker-a

Evo kratkog uputstva za instalaciju:

  1. Provera sistemskih zahteva:

    • Docker Desktop zahteva 64-bitni Windows 10 ili noviji sa verzijom 21H2 ili novijom, ili Windows 11.
    • Virtualizacija mora biti omogućena u BIOS-u (Hyper-V i Windows Container funkcije).
    • Instalacija zahteva najmanje 4GB RAM-a.
  2. Preuzmi Docker Desktop instalacioni program: na ovom linku ili poseti stranicu za instalaciju i klikni na dugme “Download Docker Desktop for Windows”.
  3. Pokreni instalacioni program (npr. “Docker Desktop Installer.exe”) i prati uputstva na ekranu.
  4. Restartuj računar
  5. Proveri Docker instalaciju:

    • Otvori terminal (PowerShell ili Command Prompt) i pokreni komandu:
    • Ako vidiš verziju Dockera, to znači da je instalacija uspela.

NAPOMENA:
Postupak instalacije se može menjati od verzije do verzije, te je najbolje pogledati aktuelno stanje na oficijalnoj stranici.

Korišćenje Docker-a

Docker može da se koristi preko preuzete aplikacije Doker Desktop ili preko terminala, evo par najčešćih komandi za terminal:

  1. Preuzimanje Docker slike sa Docker Huba

    Kao npr:

    ili

  2. Kreiranje slike prema uputstvu iz Dokerfile-a

    U trenutom direktorijumu:

    Ako se DockerFile nalazi na nekoj drugoj lokaciji:

    Gde je:

    • -t: Označava (tag) sliku imenom.
    • -f: Navodi put do Dockerfilea.
  3. Prikazivanje dostupnih Docker slika

    Naredba docker images se koristi za prikazivanje liste svih Docker slika koje su trenutno sačuvane na vašem lokalnom računaru.

    Kada koristite samo docker images bez dodatnih opcija, Docker prikazuje samo najnovije označene slike za svaki repozitorijum. Ovo znači da, ako imate više verzija slike sa različitim oznakama (tagovima), prikazuje se samo poslednja verzija. Kada dodate opciju “-a” ili “–all”, Docker prikazuje sve slike, uključujući sve verzije iste slike kao i tzv. “dangling images” tj. slike koje nemaju oznake i često su rezultat međukoraka tokom procesa građenja slike.

    Primer

    Ova opcija omogućava da vidimo sve slike koje su sačuvane na vašem sistemu, što vam pomaže da upravljate prostorom na disku i odlučite koje slike možete obrisati.

  4. Pokretanje kontejnera

    Kao npr.:

    ili sa dodatnim opcijama:

    Značenje opcija:

    • -d: Pokreće kontejner u pozadini (detached mode)
    • -p: Mapira portove host:container (npr. 8080:80)
    • –name: Dodjeljuje ime “moj-nginx” kontejneru
  5. Spisak pokrenutih kontejnera

    Npr.

    ili sa dodatnim opcijama:

    Opcija -a prikazuje sve kontejnere, uključujući i zaustavljene.

  6. Zaustavljanje pokrenutog kontejnera

    Zaustavljanje po nazivu:

    ili prema id-u:

  7. Brisanje kontejnera

    Brisanje po nazivu:

    NAPOMENA:
    Naredba "docker container prune" sza uklanjanje svih zaustavljenih kontejnera sa vašeg sistema. Ova naredba pomaže u oslobađanju prostora i održavanju urednog Docker okruženja uklanjanjem kontejnera koji više nisu aktivni.

  8. Brisanje Docker slike

    Npr:

    NAPOMENA:
    “Dangling” slike su one koje nisu povezane ni sa jednim repozitorijumom ili oznakom (tagom). Obično imaju “none” kao naziv repozitorijuma i oznake. Naredba "docker image prune" se koristi za uklanjanje neupotrebljenih (dangling) Docker slika sa vašeg lokalnog sistema.

  9. Izvršavanje naredbe unutar pokrenutog kontejnera:

    Npr.:

  10. Prikazivanje logova kontejnera:

    Npr. prikazivanje svih logova

    Prikazivanje zadnjih 10 linija loga:

Docker Volume

Docker volume je mehanizam za trajno skladištenje podataka generisanih i korišćenih od strane Docker kontejnera. Volumeni omogućavaju da podaci prežive ponovna pokretanja kontejnera, a mogu se deliti između različitih kontejnera. Koriste se za upravljanje podacima na način koji je nezavistan od životnog ciklusa kontejnera.

Ključne karakteristike Docker volumena:
  • Trajnost podataka: Podaci smešteni u Docker volumene opstaju čak i kada kontejneri koji ih koriste budu obrisani.
  • Deljenje podataka: Više kontejnera može istovremeno koristiti isti volumen, što omogućava deljenje podataka između kontejnera.
  • Izolacija podataka: Docker volumeni su izolovani od sistema domaćina (host) i ostalih kontejnera, što doprinosi boljoj sigurnosti i organizaciji podataka.
  • Performanse: Docker volumeni obično nude bolje performanse u odnosu na skladištenje podataka direktno na fajl sistemu kontejnera.

Kreiranje i korišćenje Docker volumena:

Kreiranje volumena:

Pregled postojećih volumena:

Korišćenje volumena u kontejneru:

Kada kreirate ili pokrećete kontejner, možete montirati volumen koristeći opciju -v ili --mount.

Korišćenje opcije -v:

U ovom primeru:

  • my_volume je naziv volumena koji montirate.
  • /app/data je direktorijum unutar kontejnera gde će volumen biti montiran.
  • my_image je Docker slika koju koristite za kreiranje kontejnera.

Korišćenje opcije --mount:

Ova sintaksa je slična, ali pruža više fleksibilnosti i čitljivosti.

Upravljanje Docker volumenima:

Brisanje volumena:

docker volume rm my_volume

Automatsko brisanje volumena:

Kada želite da uklonite sve nepovezane (dangling) volumene, koristite naredbu:

Primer upotrebe:

Pretpostavimo da imate aplikaciju koja skladišti podatke u direktorijumu /app/data unutar kontejnera. Želite da osigurate da ti podaci budu trajni i dostupni čak i ako ponovo pokrenete kontejner.

1. Kreirajte Docker volumen:

2. Pokrenite kontejner i montirajte volumen:

Podaci kreirani u /app/data unutar kontejnera my_app_container biće sačuvani u volumenu app_data, koji možete koristiti sa drugim kontejnerima ili pristupiti direktno ako je potrebno.

Docker Compose

Docker Compose je alat koji olakšava upravljanje višekontejnerskim Docker aplikacijama. Koristeći jednostavni YAML fajl (docker-compose.yml), možemo da definišemo konfiguraciju svih servisa, mreža i volumena koji čine našu aplikaciju, a zatim ih pokrenete i upravljate njima pomoću jedne komande. Docker Compose je uključen u sklopu Docker Dektop instalacije.

YAML (YAML Ain’t Markup Language):

YAML je format za serializaciju podataka koji je dizajniran da bude jednostavan za čitanje i pisanje. Podaci su organizovani u parove ključeva i vrednosti. Ključ i vrednost se odvajaju dvotačkom i jednim razmakom. Struktura podataka u YAML-u definiše se pomoću uvlačenja razmacima, što omogućava jasnu hijerarhiju podataka.

Rečnici se definišu pomoću ključeva i vrednosti, sa uvlačenjem koje pokazuje koji ključevi pripadaju kojem rečniku.

Liste se predstavljaju pomoću crtica sa jednim razmakom ispred svakog elementa liste.

Komentari u YAML-u počinju sa # i mogu biti postavljeni bilo gde u liniji.

Primer

U ovome primeru je prikazan doker-compose.yml fajl sa uputstvima za aplikaciju sa dva servisa: frontend (Vue.js aplikacija) i backend (NestJS API):

Gde je backend servis (NestJS API) opisan u DockerFile:

I frontend servis (Vue.js aplikacija) opisan u DockerFile:

Objašnjenje koraka
  • FROM node:18:

    Koristi zvaničnu Node.js sliku verzije 18 kao osnovu za kreiranje novog kontejnera.

  • WORKDIR /app:

    Postavlja radni direktorijum na /app. Ako direktorijum postavljen sa WORKDIR ne postoji, Docker ga automatski kreira.

    • Sledeće naredbe u Dockerfile-u će se izvršavati relativno prema ovom direktorijumu.
    • Na primer, ako naredba COPY . . sledi nakon WORKDIR /app, sve datoteke će biti kopirane u /app. COPY, ADD i druge naredbe koje koriste fajl ili direktorijum kao argument oslanjaju se na relativne puteve prema trenutnom radnom direktorijumu.
  • COPY package*.json ./:

    Kopira package.json i package-lock.json iz trenutnog direktorijuma na hostu u trenutni radni direktorijum unutar kontejnera (/app).

    • ./ ukazuje na radni direktorijum (postavljen sa WORKDIR).
  • RUN npm install:

    Izvršava npm install unutar trenutnog radnog direktorijuma (/app).

    • Instalira sve Node.js zavisnosti prema package.json.
  • COPY . .:

    Kopira sav preostali kod iz trenutnog direktorijuma na hostu u trenutni radni direktorijum unutar kontejnera (/app).

  • CMD [“npm”, “start”]:

    Postavlja komandnu liniju za pokretanje aplikacije koristeći npm start.

Struktura projekta:

Za pokretanje apilikacije je potrebno da se u terminalu “prebacimo” do lokacije projekta:

A zatim pokrenemo Docker Compose na sledeći način:

Nakon čega možemo da pogledamo aplikaciju u pretraživaču:


Sistemi za upravljanje SQL bazama (DBMS)

Uvod

mysql

Pre svega treba napraviti razliku izmedju pojmova: “baza podataka”, “sistem za upravljanje bazama podataka” (tzv.DBMS “Database Management System”) i samog “SQL jezika”.
“Relacijska baza podataka” je digitalna baza podataka na osnovu relacijskog modela podataka i predstavlja skup povezanih podataka koji zamenjuju neki aspekt stvarnog sveta.
“Relaciski sistem za upravljanje bazama podataka” (RDBMS) je softver koji se koristi za održavanje relacijskih baza podataka. On pruža interfejs između podataka i softverske aplikacije tj. prihvata zahtev za podacima iz aplikacije i nalaže operativnom sistemu da pruži određene podatke.
SQL (Structured Query Language) je jezik koji se koristi pri upravljanju relacionim bazama. Ovaj jezik je dizajniran da korisniku omogući čuvanje, pronalaženje, upravljanje ili manipulisanje podacima unutar sistema za upravljanje bazama
podataka (DBMS).

SQLlite

SQLite je “file-based” sistem koji ne zahteva nikakvu instalaciju ili podešavanje izuzetno male veličine oko 700KB. To znači da se aplikacija ne pokreće u okviru odvojenog procesa servera koji treba pokrenuti, zaustaviti ili konfigurisati. Ova arhitektura bez servera omogućava da baza podataka bude kompatibilna sa više platformi.

Kompletna baza podataka SQL sadržana je u jednoj datoteci diska i sva čitanja i upisivanja odvijaju se direktno na ovoj datoteci diska. Budući da baza podataka SQLite ne zahteva administraciju, ona dobro funkcioniše na uređajima koji moraju da rade bez ljudske podrške. SQLite je pogodan za upotrebu u mobilnim telefonima, set-top box uređajima, televizorima, igraćim konzolama… Ovo je jednostavan sistem koji podržava samo pet tipova podataka: BLOB, NULL, INTEGER, TEKST, REAL (dok napreednije dbms podržavaju skoro sve moguće tipove). Upravo njegova jednostavnost omogućava da za razliku od drugih naprednijih dbms-a bude veoma brz.

sqlite

Jedan od glavnih nedostataka SQLite sistema je nedostatak mogućnosti rada sa više korisnika koje se mogu naći u RDBMS sistemima kao što su MySQL i PostgreSQL. Pošto radi samo sa jednim korisnikom SQLite ne pruža sistem za potvrdu identiteta pri pristupu datoteci baze podataka. Još jedan veliki nedostatak SQLite-a je rukovanje operacijama upisivanja koje su serializovane. Ovo može biti glavno usko grlo za aplikacije koje zahtevaju istovremeno izvršavanje operacija.

MySQL

Za razliku od SQLite, MySQL koristi arhitekturu server/klijent koja se sastoji od SQL servera sa više niti. Ova višenitna priroda MySQL-a omogućava veće performanse jer niti jezgra mogu lako koristiti više CPU-a. Ovaj sistem ima sigurnosne funkcije koje omogućavaju autentifikaciju korisnika, sistem upravljanja korisničkim računom i šifrovane veze pomoću SSL-a. Za razliku od SQLlite MySQL podržava rada sa više korisnika. Ovaj sistem je dostupan na svim većim platformama: Windows, Linux i Mac OS X.

Mana MySQL-a je ta da veći broj INSERT-ova može imati negativan uticaj na performanse (u ovome je odličan PostgreSQL). Takođe ne radi dobro sa dugotrajnim SELECT-ima te je u slučaju MySQL-a najbolje koristi manje SELECT-e.

PostgreSQL

postgresql

Kao i MySQL, PostgreSQL koristi model baze podataka tipa klijent/server. PostgreSQL ima mogućnost da obrađuje istovremene klijentske sesije stvaranjem („račvanje“) novog procesa za svaku vezu. Poput MySQL, PostgreSQL takođe ima nekoliko naprednih funkcija vezanih za sigurnosti i replikaciju. Zbog svojih superiornih mogućnosti paralelne obrade, PostgreSQL je odličan (za razliku od MySQL-a) kada pokreće dugačke SELECT-ove. Kada se poredi sa MySQL-om u potrošnji energije tu je značajno lošiji i ima veliku potrošnju. Još jedan veliki nedostatak može se uočiti tokom čestih UPDATE-a, gde zbog nepodržane grupisanih indeksa PostgreSQL može imati negativan uticaj na performanse u poređenju sa MySQL bazama.

Microsoft SQL Server

microsoft sql server

Ovo je Microsoft-ov sistem za upravljanje relacionim bazama koj takodje koristi model baze podataka tipa klijent/server. Prednosti ovog sistema su relativno jednostavno održavanje, lak za upotrebu i razumevanje, a pristup i administracija su vrlo jednostavni. Može se koristiti kod malih i velikih projekata. SQL Server je razvio Microsoft prvobitno samo za operativni sistem Vindovs, mada je Microsoft objavio odluku da RDBMS učini dostupnim i na Linuksu kao i na Mac OS (putem Dockera).

Jedna od mana ovoga sistem je što novije verzije trebaju napredne tehnologije za pokretanje. Dakle, ako se vaš hardver sastoji uglavnom od starijeg hardvera, možda ćete morati da investirate u novije mašine da biste koristili Microsoft SQL Server.


Osnove linux-a za web developere

Uvod

linux serveri

Svaki web developer u jednom trenutku dodje u poziciju da hostuje svoju aplikaciju na VPS-u koji je baziran na Linux operativnom sistemu i da mu je potrebno osnovno poznavanje administracije Linux servera.
Za olakšavanje administracije linux servera se često koriste specijalizovane aplikacije kao što je “Control panel”, “Plesk”… Medjutim ove aplikacije nisu besplatne, čak šta više, često koštaju skoro isto kao i iznajmljivanje samog VPS-a. Čak iako se zakupi licenca za administriranje servera, smatra se da je i pored toga poželjno (potrebno) da web developer ima osnovno znanje za rad sa Linux operativnim sistemom. Pokušao sam u ovome članku da zabeležim podatke vezane za linux operativni sistem i njegovo osnovno korišćenje kroz bash shell (terminal).

Bash shell

Za rad sa linux operativnim sistemom je predvidjen Bash Shell (terminal) koji korisniku omogućava:

  • izvršavanje komandi iz komandne linije
  • istorija prethodno izvršenih komandi
  • kontrola poslova (job control)
  • upotrebu shell funkcija i aliasa
  • aritmetičke operacije

NAPOMENA: Na windows 10 postoji mogućnost da se aktivira Linux subsistem sa svim linux opcijama, sa kojim jednostavno prebacujemo windows-ov CMD u “bash”. Pogledajete više o ovome u u članku “Instalacija alata za web development”.

Bash script

Fajl koji sadrži niz sukcesivno navedenih komandi koje se izvršavaju onim redosledom kojim su navedeni se naziva bash skripta i ima extenziju .sh.

Treba napomenuti da Unix sistem sve u okviru operativnog sistema predstavlja kao sekvence bajtova bez strukture, u to spadaju fajlovi ali i uređaji koji su priključeni na komjuter sa linux operativnim sitemom. Zbog toga se sav hardver (mrežne kartice, hard diskovi, particije, tastatura, štampač) tretira kao objekat sličan fajlu. Svaku hardversku komponentu predstavlja jedan specijalni fajl koji ima odgovarajući naziv i mesto u file sistemu (npr. memorija sistema je definisana kao fajl sa lokacijom /dev/mem, a terminal (tastatura i ekran) su definisani u fajlu /dev/tty1).

“In Linux everything is file”

Pristup serveru koristeći SSH protokol

Šta je SSH protokol?

Za konekciju i komunikaciju sa udaljenim linux sistemom se najčešće korisiti SSH protokol. Secure Shell (SSH) je kriptografski mrežni protokol za siguran rad mrežnih usluga preko nezaštićene mreže. SSH komande su šifrovane i sigurne jer oba kraja veze i klijenta i servera su autentifikovana koristeći digitalni sertifikat, a lozinke su zaštićene šifriranjem.
Protokol radi po modelu klijent-server, što znači da povezivanje inicira SSH klijent koji se povezuje na SSH server. SSH klijent upravlja procesom uspostavljanja veze i koristi kriptografiju javnog ključa da bi potvrdio identitet SSH servera. Nakon faze podešavanja protokol SSH koristi snažne simetrične algoritme za šifrovanje kako bi se osigurala privatnost i integritet podataka koji se razmjenjuju između klijenta i servera.

Konekcija na sistem sa SSH protokolom

Za konekciju na udaljeni server je potrebno:

  1. hostname IP
  2. username host-a
  3. password za korisnika

Udaljenom serveru se pristupa korišćenjem odgovarajućih naredbi, u zavisnosti da li je vaš user isti kao na serveru ili ne imamo dve različite naredbe. Ukoliko je vaš user isti kao i na serveru možemo koristi:

ssh ip-adresa-udaljenog-servera

Ali ako nije isti user onda koristimo:

ssh naziv-usera-udaljenog-servera@ip-adresa-udaljenog-servera

Nakon ovoga sistem zahteva da se unese odgovarajuća šifra, naposletku za prekid sesije se koristi naredba:

exit

Aplikacije koje podržavaju SSH protokol

Za pristup udaljenom serveru nam je potreban bash (terminal), postoji već pomenuta mogućnost da se windows-ov CMD prebaci u bash ali to važi samo za WIN 10, za korisnike starijih windows izdanja je rešenje neka od third part aplikacija koji emuliraju linux bash:

  • Putty
    Putty je najstarija windows aplikacija za komunikaciranje sa udaljenim sistemom koja koristi SSh protokol, dok je većina ostalih aplikacija “ulepšana” varijacije sa dodatnim mogućnostima.
  • PuttyTray
  • Kitty
  • Mobaxterm
  • mRemoteNG
  • Smartty

Kopiranje i sinhronozaovanje fajlova sa Rsync

Rsync je brz i izuzetno prilagodljiv alat za kopiranje fajlova. Može kopirati fajlove lokalno, kao i sa drugog domaćina. On nudi veliki broj opcija i omogućava fleksibilnu specifikaciju izbora datoteka koje treba kopirati. Poznat je po algoritmu prenosa “delta”, koji smanjuje količinu podataka poslatih preko mreže,tako što šalje samo razlike između izvornih datoteka i postojećih datoteka u odredištu.

Postoje dva različita načina da Rsync da stupi u kontakt sa udaljenim sistemom: koristeći SSH ili direktno kontaktiranjem dinamičkog Rsync preko TCP-a.

rsync options source destination

NAPOMENA:
Korišćenjem SSH protokola se prenose podaci sigurnom vezom sa šifrovanjem.Da bi ste koristili SSH protokol morate da navedete root lozinku da biste je povezali, a pomoću opcije SSH će se šifrirati šifrirani način tako da će vaša lozinka biti sigurna.

Dodatne opcije su:

  • -v => verbose opcija jednostavno proizvodi izlaz na ekranu koji pruža komentare o radu dok se pojavljuju, tako da ćete u realnom vremenu prikazivati status korisničkog programa ili programa za pokretanje zadataka ili naredbi koje ste poslali.
  • -r => kopira podatke rekurzivno (kopiranje direktorijuma i svih njegovih datoteka i poddirektorijuma i svih njihovih datoteka, sve dublje i dublje do dna stabla direktorijuma).
  • -a => archive mode omogućava rekurzivno kopiranje fajlova pri čemu čuva simboličke veze, file permissions, vlasničke i vremenske oznake.
  • -z => kompresuje fajlove
  • -h => human-readable format
  • -d => transfer direktorijuma bez rekurzije
  • -e => specify the ssh as remote shell

a) Rad sa fajlovima na lokalu

Naredba Objašnjenje
rsync -zvh test.txt /home/test1/ Fajl test.txt će biti kopiran ili sinhronizovan unutar foldera test1 čija je putanja /home/test1/
rsync -t *.c foo:src/ Prethodna naredba bi prenela sve datoteke koje odgovaraju obrazcu * .c iz trenutnog direktorijuma u ​​direktorijum “src” na mašini “foo”. Ako bilo koja od datoteka već postoji na udaljenom sistemu, onda se protokol rsinc daljinskog ažuriranja koristi za ažuriranje datoteke slanjem samo razlika.
rsync -avz foo:src/bar /data/tmp Ovo bi rekurzivno prekopiralo sve datoteke iz direktorijuma src/bar na mašini foo u direktorijum /data/tmp/bar na lokalnoj mašini. Datoteke se prenose u režimu “lqarchiverq”, što osigurava da se u prenosu čuvaju simboličke veze, uređaji, atributi, dozvole, vlasništva itd. Pored toga, kompresija će se koristiti za smanjenje veličine dijelova podataka prenosa.
rsync -avz foo:src/bar/ /data/tmp
Dodatna kosa crtna na izvoru foo:src/bar/ omogućava da se izbegne stvaranje dodatnog nivoa direktorijuma na odredištu.

b) Sinhronizacija sa lokalnog servera na udaljeni

Opšti izgled naredbe:

rsync options izvorni_fajl naziv_usera@ip_adresa_udaljenog_servera:destinacija
Primer
Naredba SSH Objašnjenje
rsync -avzh public_html/test.txt root@22.22.22.22:/home/ NE
Sa ovom komandom je fajl test.txt koji se nalazi u lokalnoj mašini kopiran ili sinnhronizovan na mašinu sa IP adresom 22.22.22.22 u direktorijum home.
rsync -avzhe ssh public_html/test.txt root@22.22.22.22:/home/ DA
Sa ovom komandom je fajl test.txt koji se nalazi u lokalnoj mašini kopiran ili sinnhronizovan na mašinu sa IP adresom 22.22.22.22 u direktorijum home koristeći SSH protokol.

c) Sinhronizacija sa udaljenog servera na lokalni

Opšti izgled naredbe:

rsync options naziv_usera@ip_adresa_udaljenog_servera:izvorni_fajl destionacija
Primer
Naredba SSH Objašnjenje
rsync -avzh root@22.22.22.22:/home/test.txt /home/test/ NE
Sa ovom naredbom kao korisnik “root” kopiramo sa servera čija je IP adresa 22.22.22.22 iz foldera home fajl test.txt na naš lokalni server u folder home/test/
rsync -avzhe root@22.22.22.22:/home/test.txt /home/test/ DA
Sa ovom naredbom kao korisnik “root” kopiramo sa servera čija je IP adresa 22.22.22.22 iz foldera home fajl test.txt na naš lokalni server u folder home/test/ koristeći SSH protokol
sync -avze ssh --exclude '*txt' rroot@22.22.22.22:/home/test.txt home/test/ DA
Sa ovom naredbom kao korisnik “root” kopiramo sa servera čija je IP adresa 22.22.22.22 iz foldera home sve osim “.txt” fajlova na naš lokalni server u folder home/test/ koristeći SSH protokol

Struktura Linux file sistema

Na slici je prikazana najčešća struktura file sitema Linux opertativnog sistem. Najvažniji direktorijum je Root i on jedini nema roditeljski direktorijum. Označava se sa kosom crtom “/” i pristup ovome direktorijumu ima samo “root” user. Ukoliko putanja koja definiše mesto nekog fajla ili direktorijuma počninje sa kosom crtom “/” znamo da je u pitanju absolutna putanja. Relativna putanja je definisana u udnosu na trenutnu poziciju i počinje sa “./”, pošto se na ovaj način obeležava trenutni direktorijum.

linux directory system

/bin

U ovome direktorijumu se čuvaju binarne izvršne komande, kao što su: ps, ls, ping, grep, cp….

/etc

Sadrži konfiguracione fajlove za sve programe, kao i shell skripte za započinjenje i gašenje aplikacija.

/dev

Linux predstavlja uređaje kao fajlove, pa ovaj direktorijum sadrži više specijalnih fajlova koji predstavljaju uređaje. Npr. “/dev/sda” predstavlja prvi SATA disk u sistemu.

/home

U ovaj folder se čuvaju privatni i konfiguracijski fajlovi za svakog korisnika. Svaki korisnik ima samo “write” pristup u svome direktorijumu, za pisanje u drugim direktorijumima potrebno je da bude root korisnik.

/media

Ovaj direktorijum sadrži poddirektorijumeje u kojima su prikazani prenosivi mediji ubačeni u računar.

/root

Ovaj direktorijum je direktorijum root korisnika. Umesto da se nalazi na “/home/root”, sa ostalim user-ima on nalazi se ovde.

/srv

Ovaj direktorijum sadrži podatke za usluge koje pruža sistem. Npr. ako koristte Apache HTTP server za servisiranje veb stranica, verovatno ćete uskladištiti datoteke vašeg veb sajta u direktorijumu unutar /srv direktorijuma.

/tmp

Aplikacije čuvaju privremene fajlove u ovom direktorijumu. Fajlovi u ovome direktorijumu se generalno brišu kad god se vaš sistem ponovo pokrene i može se u bilo kom trenutku izbrisati pomoćnim programima kao što je “tmpvatch”.

/usr

Ovaj direktorijum sadrži aplikacije i fajlove koje koriste korisnici, za razliku od aplikacija i fajlova koje koristi sistem. Npr. ne-esencijalne aplikacije se nalaze unutar direktorija “/usr/bin” umesto direktorijuma /bin, a lokalni direktorijum “/usr/local” se koristi kao mesto za instaliranje lokalnih aplikacija čime se sprečava da nepotrebno “zagadi” ostatak sistema.

/var

U ovaj direktorijum se snimaju promenjivi (varijabilni) fajlovi. Fajlovi čiji sadržaje se očekuje da raste može se pronaći pod ovom direktorijumu. To najčešće uključuje: system log files (/var/log), packages and database files (/var/lib), ili emails (/var/mail)…

Osnovne linux komande

Pomoć pri pisanju naredbi

U radu sa Bash shell-om se koristimo:

  • Tab na tastaturi predstavlja ogromnu pomoć pri pisanju Linux komandi, jer će automatski popuniti imena fajlova i direktorijuma.
  • Simboli “?” i “*” su wildcard u Linux-u. Znak pitanja “?” će zameniti jedan karakter, dok će “*” zameniti ceo string.
  • Kopiranje teksta u okviru terminala je sa naredbom Ctrl+Shift+C dok je paste se naredbom Ctrl+Shift+V (ukoliko naredba ne radi, probati desni klik ili komandu iz context menija).

Sintaksa naredbi

Sve komande u Linux-u se mogu predstaviti sa sledećim šablonom:

[sudo] command [optional switch] [file or directory path]
Naredba Objašnjenje
[command] --help Izlistava opcije za korišćenje komande
man [command] Prikazaju uputstvo (eng. “manual”) za traženu komandu.
sudo [command] Komanda se izvršava sa administratorskim pravima

Bash prečice

Naredba Objašnjenje
CTRL + c
Zaustavlja izvršenje trenutne naredbe
CTRL + z
Sleep program
CTRL + a
Šalje kursor na početak naredbe
CTRL + e
Šalje kursor na kraj naredbe
CTRL + u
Briše sve karaktere od početka do kursora
CTRL + k
Briše sve karaktere od kursora pa sve do kraja linije
CTRL + r
Pretraga kroz korišćene naredbe (izlistavnje sa ponovnim CTRL + R)
!!
Repeat last command
!<em>abc</em>
Pokreće poslednju naredbu koja počinje sa abc
!<em>abc</em>:p
Štampa u terminalu poslednju naredbu koja počinje sa abc
!*
Štampa sve argumente iz prethodne naredbe

Monitoring i informacije

Naredba Objašnjenje
ps rikazuje sve trenutno aktivne procese koje je inicirao user
ps -ef Prikazuje sve trenutno aktivne procese
ps -ef | grep nazivprocesa
Filtrira procese prema nazivu procesa i prikazuje informacije o izabranom procesu u terminalu (linux pipeline: kada “ps -ef” izlista sve trenutne procese onda “grep” filtrira izlistane procese prema definisanom nazivu procesa)
kill processID Ubija proces čiji ID je naznačen
killall processName Ubija proces čije ime je processName
du -sh naziv_foldera/* Izlistava veličinu svih poddirektorijuma ili fajlova unutar trženog direktorijuma
vmstat Prikazuje statistiku virtualne memorije
cat /proc/meminfo Prikazuje podatke o memoriji
cat /proc/cpuinfo Prikazuje podatke o procesoru
free -h Prikazuje slobodnu i zauzetu memoriju ( -h za human readable, -m za MB, -g za GB.)
id Prikazuje id od usera i njegove grupe
last Prikazuje listu poslednje logovanih usera na sistem
ifconfig -a Prikazuje sve podatke o network interfejsu i IP adresi
ping webprogramiranje.org Šalje kontrolnu poruku do traženog host-a i štampa odgovor
dig webprogramiranje.org Prikazuje DNS informacije o traženom host-u
netstat -nutlp Prikazuje sve tcp i udp portove koji osluškuju saobraćaj
badblocks -s /dev/sda Testiranje hard diska

Rad sa file sistemom

Naredba Objašnjenje
pwd
Štampa u terminalu putanju trenutnog direktorijuma
mkdir  test-direktorijum
Pravi novi direktorijum test-direktorijum
cd test-direktorijum
Ulazak u direktorijum test-direktorijum
cd ..
Go up a directory
ls
Izlistava sve fajlove u trenutnom working direktorijumu
ls -a
Izlistava sve fajlove u trenutnom working direktorijumu uključujući i hidden
ls -R
Rekurzivno izlistava sve fajlove u trenutnom working direktorijumu uključujući sve poddirektorijume
ls -t
Izlistava sve fajlove u trenutnom working direktorijumu sortirane prema filteru last modified
ls -S
Izlistava sve fajlove u trenutnom working direktorijumu sortirane prema filteru size
ls -l
Izlistava sve fajlove u trenutnom working direktorijumu u punom formatu
ls -1
Izlistava sve fajlove u trenutnom working direktorijumu – svaki fajl u novu liniju
ls -m
Izlistava sve fajlove u trenutnom working direktorijumu, fajlovi su razdvojeni zarezom.
touch novi_fajl.txt
Kreira novi fajl pod nazivom novi_fajl.txt
less neki_fajl

Štampa sadržaj tekstualnog fajla neki_fajl u terminalu (izlazak sa “Q”)
cat neki_file1 neki_file2

Štampa u terminalu tekstualni sadržaj fajlova (ukoliko ih ima više spaje sve u jedan ispis)
file file1
Štampa u terminalu podatke o fajlu file1
cp pic.jpg pic2.jpg

Kopira fajl u working direktorijumu pic.jpg i snima ga kao novi fajl pod imenom pic2.jpg isto u working direktorijumu
cp /home/pic.jpg /home/backup/pic.jpg
Iz direktorijuma home se kopira fajl pic.jpg i snima se u direktorijum backup kao novi fajl pod imenom pic.jpg
cp -R /home/slike /home/backup

Kopira ceo direktorijum slike sa svim poddirektorijumima u folder backup (prvi postaje poddirektorijum od foldera backup)
cp *.jpg /home
Kopira sve fajlove sa ekstenzijom .jpg u working direktorijumu i snima ih u home direktorijum sa istim nazivima
mv /home/file1 /home/file2
Rename fajl file1 iz foldera home u file2
mv /home/file1 /tmp/file2

Move fajl file1 iz foldera home u folder tmp i čuva ga kao fajl file2
rm file1

Briše fajl file1
head file1

Štampa u terminal prvih 10 linija tekstualnog fajla file1
tail file1

Štampa u terminal poslednjih 10 linija tekstualnog fajla file1
tail -3 file1

Štampa u terminalu poslednje 3 linije tekstualnog fajla file1

Search

Naredba Objašnjenje
grep <em>"neki tekst"</em> <em>/home/logovi.txt</em>
Pretraga teksta “neki tekst” unutar fajla logovi.txt. Ukoliko postoji rezultat, on se štampa u terminalu
grep -r <em>"neki tekst"</em> /home/
Rekurzivna pretraga teksta kroz sve fajlove u okviru home direktorijuma i njegovih podirektorijuma
grep -i <em>"neki tekst"</em> /home/
Case insens­itive pretraga teksta “neki tekst” kroz sve fajlove u okviru home direktorijuma
find <em>/home/</em> -name <em>"test*"</em>
Pretraga fajlova u okviru home direktorijuma prema imenu (-name), a koje započinje sa test
find <em>/home/</em> -user <em>"pera"</em>
Pretraga fajlova u okviru home direktorijuma prema useru (-user), čije ime započinje sa pera
find <em>/home/</em> -mmin <em>60</em>
Pretraga za svim fajlovima u okviru home direktorijuma koji su modifikovani u zadnjih 60 minuta
find <em>/home/</em> -amin <em>60</em>
Pretraga za svim fajlovima u okviru home direktorijuma kojima je pristupano (access) u zadnjih 60 minuta
find <em>/home/</em> -size <em>60M</em>
Pretraga za svim fajlovima u okviru home direktorijuma koji su veći od 60MB
find /home/ -size +50M -size -100M
Pretraga za svim fajlovima u okviru home direktorijuma koji su veći od 50MB a manji 0d 100MB
find /home -type f -empty
Pretraga za svim fajlovima u okviru home direktorijuma koji su prazni
find /home -type d "test"
Pretraga za direktorijumima u okviru home direktorijuma pod nazivom “test”
find /home -type d -empty
Pretraga za direktorijumima u okviru home direktorijuma koji su prazni

File permissions

Naredba Objašnjenje
chmod 644 file.html

Vlasnik može da čita i piše (4+2), grupa može da čita, i ostali mogu da čitaju
chmod u=rw example.jpg

Vlasnik može da čita i piše (4+2)
chmod -R 755 nekifolder

Rekurzivno promeniti permisije u direktorijumu pod nazivom “nekifolder” i svim njegovim poddirektorijumima tako da vlasnik može da čita i piše i izvršava(4+2+1), grupa može da čita i izvršava (4+0+1), a ostali mogu da čitaju i izvršavaju (4+0+1)
chmod 775 <em>file</em>

Promena permisija Change mode of file to 775
chmod -R 600 <em>nekifolder</em>
Rekurzivna promena permisija na 600 za nekifolder i svih njegovih fajlova i podfoldera
chown <em>user</em>:<em>group</em> <em>nekifile</em>

Promena vlasništva nad fajlom nekifile ne group
OBJAŠNJENJE:
linux permision

User: Read, Write, and eXecute => u=rwx
Grupa: Read and eXecute => g=rx
Others: Read => o=r

  • “read” = 4
  • “write” = 2
  • “execute” = 1
  • “no permission = 0
  • 5 je kombinacija permisija 4+0+1 (read, no write, and execute)
  • 6 je kombinacija permisija 4+2+0 (read, write, and no execute)
  • 7 je kombinacija permisija 4+2+1 (read, write, and execute)

chmod u=rwx,g=rx,o=r nazivfajla je ekvivalentno sa chmod 754 nazivfajla

Arhiviranje

Komanda “tar” spaja više fajlova u jedan tj. kreira arhivu, takva arhiva može da se kompresuje sa “gzip” algoritmom.

Naredba Objašnjenje
tar -cf archive.tar file1 file2 Pravljenje jedne arhive od dva fajla
tar -cf archive.tar mydir/ Kreiranje arhive od direktorijuma “mydir”
tar -czvf naziv_arhive.tar.gz /home/test
Od izabranog direktorijuma “test” kreira kompresovanu arhivu pod nazivom naziv_arhive.tar.gz
tar -czvf naziv_arhive.tar.gz test U radnom direktorijumu od izabranog direktorijuma “test” kreira kompresovanu arhivu pod nazivom naziv_arhive.tar.gz
tar -xf archive.tar Extrahuje arhivu
tar -xzvf archive.tar.gz Extrahuje kompresovanu arhivu
tar -xvf archive.tar documents/work/budget.doc Extrahuje samo documents/work/budget.doc fajl iz arhive archive.tar
tar -xvf archive.tar documents/work/ Extrahuje samo documents/work/ direktorijum i njegove fajlove iz arhive archive.tar
tar -czf DogPhotos.tar.gz --exclude='kitty.jpg' MyPetPhotos Pravi arhivu DogPhotos.tar.gz od fajlova u direktorijumu “MyPetPhotos” iz kojih je izbačeni fajlov sa imenom kitty.jpg

OBJAŠNJENJE:
–create ili (-c) => kreira novu .tar arhivu
–verbose ili (-v) – verbose opcija prikazuje status korisničkog programa
–file ili (-f) => indikuje da će sledeći argument u naredbi biti ime archive fajla
–gzip ili (-z) => kompresuje arhivu sa gzip algoritmom
–extract ili (x) – ekstrahuje arhivu
–ignore-case => ignoriše veličinu slova kada pretražuje po zadatom šablonu
–overwrite => briše početni ne kompresovan fajl a na njegovo mesto stavlja kompresovani
–recursion => rekurzija je podrazumevano podešavanje
–no-recursion => bez rekurzije
–exclude=PATTERN => izbacuje iz selekcije definisani šablon

Pipe

Pipe je oblik redirekcije koji se koristi u Linux-u i drugim Unix-like operativnim sistemima za slanje izlaza jednog programa u drugi program na dalju obradu. Obeležava se sa vertikalnom linijom | izmedju dve naredbe.

komanda_1 | komanda_2 | komanda_3

U prethodnom primeru će se prvo izvršiti komanda_1 nakon čega će njen izlaz komanda_2 uzeti kao ulazne parametre i obraditi ih, a nakraju će tako obradjene podatke uzeti komanda_3 i takodje ih obraditi.

Primer

ls -al | grep '^d'

Ova kombinacija naredbi izlistava samo podirektorijume trenutnog working direktorijuma.

Primer

$ls -l | grep -i "neki_naziv"

Ova kombinacija naredbi izlistava sadržaj trenutnog working direktorijuma, a zatim filtrira prema željenom nazivu (nije bitna veličina slova -i = insenitive).

Primer

ls -la | sort -nk5

Ova kombinacija naredbi izlistava sadržaj trenutnog working direktorijuma, i sortira ga prema numeričkim vrednostima u 5-toj koloni.

Cron job

Cron je naziv programa koji omogućava unix korisnicima da izvršavaju komande ili skripte (grupe komandi) automatski u određeno vreme/datum. Cron je deamon, što znači da ga je potrebno samo jednom pokrenuti, nakon čega će čekati naredbu. Cron deamon koristi cron tabele da u njima definiše koje zadatke treba da pokreće i kada. Svaka linija cron tabele predstavlja jedan posao za izvršavanje u definisanom vremenskom razdoblju.

Cron sintaksa

Format jedne linije cron tabele izgleda ovako:

(Minute 0-59) (Hour 0-23) (Day of Month 1-31) (Month 1-12) (Day of week 0-7) (Command)

Naredba Objašnjenje
@reboot ~/backup-home.sh Skripta će se startovati jednom posle reboot.
@yearly ~/backup-home.sh Skripta će se startovati godišnje
@monthly ~/backup-home.sh Skripta će se startovati mesečno
@weekly ~/backup-home.sh Skripta će se startovati nedeljno
@daily ~/backup-home.sh Skripta će se startovati svakodnevno
@hourly ~/backup-home.sh Skripta će se startovati na svaki sat
*/2 * * * * ~/backup-home.sh U ovome slučaju će skripta biti startovana na svaka 2 minuta.
* 17-20 * * * ~/backup-home.s
Skripta “backup-home.sh” će biti startovana u 17, 18, 19, i 20 sati svakoga dana.
0 5 1,15 * * ~/backup-home.sh Definisano je da se izvrši “backup-home.sh U 5:00 AM svakog 1-og i 15-tog u mesecu.
0 5 1 * * ~/backup-home.sh Definisano je da se izvrši “backup-home.sh U 5:00 AM svakog 1-og u mesecu.

Crontab

Crontab je komanda koja se koristi za izlistavanje tablica koje koristi cron daemon.

Naredba Objašnjenje
crontab -a naziv_cron_fajla
Kreiranje kron fajla
crontab -l
Štampanje sadržaja crontab fajla u terminalu.
crontab -e Editovanje crontab fajla, ili kreiranje ako već ne postoji. Kada prvi put pokušamo da uredimo našu crontab datoteku, od nas će biti zatraženo da izaberemo tekst editor.
crontab -r Brisanje crontab fajla.

Chrome DevTools

Uvod

chrome devtools

U ovome članku je napravljen pregled specijalizovanih alata u okviru “Chrome” browsera, pod nazivom “DevTools”. Chrome DevTools su nezamenjivi set alatki namenjeni web developerima kao pomoć u svakodnevnom radu. Kroz DevTools je omogućen pregled HTML stranice i rad sa DOM elementima, kao i pristup svim CSS svojstvima elemenata.
U ovom paketu alata je naručita pažnja posvećena delu za debagovanje JavaScript koda. Koristeći ovoj alat je omogućeno definisanje raznih načina prekidanja izvršavanja progamskog koda (tzv. breakpoint), što znatno olakšava rad web developerima pri otklanjanju bagova na vebsajtovima. Pri svakom prekidu je omogućen uvid u vrednosti promenjiva kao i njenih oblasti definisanosti.
Pored ovoga postoje sekcije vezane za praćenje performansi web aplikacije, kao i pregled razmene podadaka izmedju klijenta i servera.

Continue reading…


Webpack (osnove)

Uvod

Prednosti i mane modularnog programiranje

webpack logo

Organizacija koda samo u jednom fajlu, čini programiranje veoma komplikovanim. Iz tog razloga se u JavaScript-u kao i u mnogim drugim programskim jezicima, programski kod deli u manje celine tzv. module. Podela se vrši prema odredjenoj šemi, koja omogućava dobru organizaciju i olakšava vizuelnu i strukturnu preglednost.

Pri deljenju na manje delove (module), dešava se da jedan modul zavisi od koda koji se nalazi u drugom modulu. To se prevazilazi “uvoženjem” (eng. import) koda iz jednog modula u drugi. Sve do pojave ES2015 standarda nije postojla sintaksa za module, pa se koristila eksterna sintaksa CommonJS ili AMD. Webpack podrazumevano koristi “CommonJS” sintaksu, pa se tako u okviru webpack.config.js fajla mogu naći ključne reči require() i module.export. Medjutim ako se u projekat implementira “Babel”, preporuka je da se koristi JavaScript sintaksa ugradjena u sam jezik prema ES2015 standardu.

OBJAŠNJENJE:
Externe sintakse nisu JavaScript biblioteke, već odgovarajuće specifikacije i konvencije za definisanje modula. Eksterna sintaksa može da se koristi jedino uz pomoć modul loader-a ili bundler-a koji joj “udahnu život”. Kada modul loader/bundler podržava sintaksu, to znači da zna da primeni ugradjene metode koje su prethodno zamišljene da se koriste kroz odredjenu sintaksu. Više ovome pogledajte u članku Modularno programiranje – eksterna sintaksa (AMD & CommonJS)

JavaScript modul od kojeg zavisi rad drugog modula se zove “zavisnost” (eng. “dependency”). Podela koda na više manjih modula ima svojih prednosti medjutim pri tome se javljaju sledeći problemi koji treba da se prevaziđu:

  • povećan broja request-a za učitavanje tih fajlova ka serveru.
  • organizovanje redosleda učitavanja modula, i svih njihovi zavisnosti (eng. dependencies)

Namena bundler-a

“Modul bundler” rešava probleme nastale usitnjavanjem koda, tako što kompajlira sve module u jedan fajl, pri čemu vodi računa da moduli koji su zavisnost drugome modulu budu učitani pre modula kome trebaju.

Najpoznatiji modul bundler-i su:

  • Browserify – implementira CommonJS sintaksu u browser okruženju. Može da se nadogradjuje raznim plugin-ima. Uz pomoć task runner-a (Gulp ili Grunt) može da završi različite zadatke vezane za obradu programskog koda.

  • Webpack – učitavati module u bilo kom popularnom formatu (CommonJS, UMD, AMD, ES6). Dolazi kao jedan paket i nisu mu potrebni dodatni plugin. Oficijelna stranica za webpack je https://webpack.github.io/, dok se dokumentacija za webpack 2 nalazi na https://webpack.js.org/

    OBJAŠNJENJE:
    Glavna namena “webpack-a” je da objedini sve module u jedan ili više krupnijih fajlova, dok dodatne funkcionalnosti webpack dobija kroz “webpack loader-e” ili “webpack plugin-e”.

Instalacija webpack-a

Pošto se instalacija vrši preko package manager-a, potrebno je imati instaliran node.js i odgovarajući package manager. Nakon toga koristeći “package manager” instaliramo i sam webpack:



NAPOMENA:
Svi primeri iz članka objedinjeni su u jedan projekat. Završna verzija projekta je objavljena na GitHub-u
https://github.com/choslee/webprogramiranje-webpackOsnove.

Osnovna konfiguracija webpack-a

Konfiguraciju webpacka definišemo u okviru webpack.congfig.js fajla. U njemu se koristi common.js sintaksa, pa se primećuju ključne reči require() i module.exports = {…}. Više o common.js pogledajete u članku Modularno programiranje sa eksternom sintaksom

NAPOMENA:
Kad god se promeni webpack.config.js, potrebno je da se ponovo generišu (“build-uju”) fajlovi. Ukoliko se koristi “webpack –watch” opcija, onda je potrebno prekinuti proces sa CTRL + C i ponovo gs uključiti.

Definisanje ulaznog i generisanje izaznog fajla

Pošto smo već pri generisanju package.json fajla definisali šta je ulazna tačka (npr. “index.js”), sada tu činjenicu možemo da iskoristimo da definišemo ulaznu tačku i za webpack. Početni i izlazni fajl za webpack definišemo u okviru webpack.config.js:

Prethodna konfiguracija podrazumeva da će se fajl bundle.js generisati u root-u projekta, medjutim ukoliko želimo da se bundle.js generiše na drugom mestu potrebno je dodati svojstvu output novo svojstvo path. Vrednost svojstva path je apsolutna putanja, stoga koristimo node.js promenjivu __dirname koja predstavlja apsolutnu putanju foldera u kome se nalazi modul.

Umesto path: __dirname + "/dist" možemo da koristimo sa potpuno istim rezultatom i node.js metodu path.resolve([...paths]). Da bi koristili path.resolve() metodu u okviru webpack.config.js fajla moramo da uvezemo modul require ('path') na vrhu fajla.

Definisanje višestrukih ulaznih i generisanje više izlaznih fajlova

U dosadašnjem delu je kroz “entry” i “output” svojstva definisan samo po jedan ulazni i jedan krajnji javascript fajl, što je najčešća konfiguracija za “Single Page Application” (tzv. SPA). Medjutim ako vaša aplikacija ima više stranica velika šansa je da će biti zahteva se na svakoj učitava drugi JavaScript bundle fajl. WebPack obezbedjuje i tu funkcionalnost, samo je potrebno da se u konfiguaracionom fajlu definiše više ulaznih (entry) fajlova i da se napiše kod koji dinamički generiše više krajnjih (“outputh”) JavaScript fajlova:

Ovako definisani ulazni i izlazni fajlovi će generisati dva nova JavaScript bundle fajla: “index.bundle.js” i “druga.bundle.js”. Nazivi entry svojstva indexJS i drugaJS su “chunks” imena, koja se koriste kasnije kod HtmlWebpackPlugin plugina. Na ovaj način smo omogućili da dve različite skripte mogu biti ugradjene na dve različite stranice.

Pored prethodno opisanog definisanja višestrukih ulaza i izlaza, često se javlja potreba za razdvajenjem javascript koda na naš kod i tzv. “third party dependencies”. Ovaj postupak se malo razlikuje od opisanog i za njega je potrebno koristiti plugin koji sprečava dupliranje koda. O ovome možete pročitati u sekciji “CommonsChunkPlugin”.

Pokretanje webpack-a

Standardno pokretanje

Pokretanje webacka je isto kao pokretanje bilo kog drugog npm paketa.



Webpack watch

Da bi izbegli neprestano pozivanje naredbe npm run webpack koja build-uje nove promene, postoji mogućnost da napišemo skriptu u okviru package.json fajla koja uz flag --watch omogućava build-ovanje nakon čuvanja promena unutar projekta.

Posled definisanja skripte u package.json možemo u terminalu pokrenuti naredbu koja će pratiti promene:



Za prekidanje praćenja promena u terminalu koristimo prečicu:

Nakon čega se od nas zahteva potvrdimo prekid i upišemo Y.

Webpack dev server

Webpack obezbedjuje i jednostavni web server koji nam daje mogućnost da automatski učitatvamo promene koda u browseru tzv. “live reloading“, nakon čuvanja promena u editoru.

Instalacija web servera



Konfiguracija webpack-a za dev server

Osnovna konfiguracija se svodi na definisanje foldera koji treba da prikazuje, stoga je potrebno unutar “webpack.config.js” fajla ispod dela gde je konfigurisan “devtool” dodati deo:

Pokretanje dev servera

Za jednostavno pokretanje servera je potrebno definisati skriptu u okviru “package.json” fajla

Ovo nam omogućava da iz terminala jednostavnom naredbom podignemo server i prikažemo sve iz “dist” foldera. Flag --open nam omogućava da se taj prikaz izvrši u novom tabu u okviru browsera.



Webpack dev server će nakon svake promene JS ili CSS fajla, automatski ponovno učitati promene u browseru. Za prekidanje rada servera u terminalu koristimo prečicu:

Nakon čega se od nas zahteva potvrdimo prekid i upišemo Y.

Više o webpack dev serveru možete pogledati na WebPack oficijelnoj stranici u sekciji “Using webpack dev server”

BrowserSync & Webpack dev server

BrowserSync je takodje webserver i može isto kao WebPack dev server samostalno da automatski učitava promene u browser tzv. “Live reloading”. Pored ove mogućnosti BrowserSync omogućava istovremeno sinhronizovano testiranje na više različitih uredjaja (mobilini, tablet…) dok su na lokalnom serveru pod uslovom da se nalaze na istoj mreži. Ovo podrazumeva da se jedna ista radnja (npr. klik na dugme, skrol stranice…) istovremeno izvodi na svim aktivnim uredjajima.
Kada se pored Webpack dev servera instalira BrowserSync onda imamo aktivna dva servera, ali u tom slučaju se BrowserSync ponaša kao medijator (proxy server). Na ovaj način smo u mogućnosti da koristimo najbolje funkcije od ta dva.

Instalacija Browsersync

Browsersync app se samostalno instalira (pogledajte na oficijelnom sajtu browsersync.io/)



Kada se koristi uz webpack instalira se kao plugin.



Konfiguracija BrowserSync plugina

Potrebno je na vrhu webpack.config.js fajla importovati plugin:

A u delu zaduženom za plugine dodati:

Pored ovoga potrebno je isključiti opciju da webpack dev server otvara novi tab, jer se takodje otvara i preko BrowserSynca-a pa bi došlo do dupliranja. Zbog toga je neophodno da obrišemo --open na mestu gde smo prethodno definisali script u okviru package.json fajla.

Startovanje BrowserSync

Browsersync url

BrowserSync se sam startuje kada je Webpack u “watch” modu! Nakon startovanja BrowserSync će na kraju ispisa u terminalu dostaviti url adrese za sinhronizovano pristupanje projektu sa dva ili više uredjaja. Dovoljno je da se u vaš mobilni unese obeležena adresa i uredjaji će biti povezani na vašem projektu. Sve što se radi na jednom uredjaju paralelno se izvršava i na drugom. Više o ovome možete pročitati na oficijlnom sajtu “BrowserSync for webpack”.

Webpack loaders

Namena

Glavna namena Webpacka je da bude bundler tj. da okupi sve JavaScript fajlove u jedan veliki fajl prema odgovarajućem redosledu koji uvažava njihove zavisnosti. Medjutim pre pomenutih radnji mogu da se izrvše odredjene “predradnje” nad tim fajlovima, a za to su zaduženi webpack loaders. Loaderi preprocesuiraju fajlove pre nego što ih sam webpack obradi. Loader mogu:

  • da integrišu CSS fajlove u JavaScript
  • da transformišu fajlove sa drugog jezika u JavaScript (transpiliraju), npr. Typescript u JavaScript ili ES6+ u JavaScript.
  • da minifikuju fajlove (CSS/JavaScript) u JavaScript
  • da transformišu inline slike u base64-encoded URL string koji tako mogu da budu dostupni JavaScript-u, nakon čega on može da ih ubacuje na stranu.
  • da učitavaju i kompajliraju cele framework-e (npr.Vue.js, Angular.js…)
  • da testiraju kod (npr. Mocha…)
  • da lintuju kod (npr. ESlint…)
  • da učitaju i kompajliraju templating sistem u HTML (npr. Handlebar…)

Loaderi mogu da se nadovezuju u serijama (chain together). Listu postojećih loader-a možete pogledati na oficijelnom sajtu webpack.js.org/loaders/

CSS loader

Instalacija paketa za CSS

Ako javascript radi obradu CSS-a (minifikovanje, transpiliranje…) potrebno je uvesti taj CSS fajl u javascript modul koristeći sintaksu import '../css/main.css'. Da bi javascript prepoznao ovu sintaksu potrebno je koristiti “css-loader”. CSS loader “hendluje” importovanje CSS koda tako što ga generiše kao string.
Ukoliko pored toga želimo i da ugradimo CSS u sam Javascript modul, onda koristimo “style-loader”. Style-loader integriše CSS string u <style> tag koji zatim ugradjuje u “head” HTML stranice. Instalacija ovih paketa se vrši sa naredbom:



Konfiguracija wabpack-a za CSS loadere

Unutar “webpack.congfig.js” fajla na postojeću konfiguraciju treba dodati sledeći kod:

NAPOMENA:
Obratiti pažnju da se u ovom nizu loaderi primenjuju u redosledu od poslednjeg ka prvom, stoga “style-loader”, treba da bude pre “css-loader”-a.

Webpack koristi regular expression definisano pod svojstvom “test” sa kojim pronalazi sve CSS fajlove, dok svojstvo “use” definiše koje sve loadere da koristi i kojim redosledom. Više o ovome pogledajte ona oficijelnoj stranici asset menagmente/css loaders. Ukoliko ipak ne želimo da ugradimo obradjeni CSS u JavaScript modul, to možemo postići preko webpack plugina pod nazivom ExtractTextWebpackPlugin

SASS loader

Instalacija paketa za SASS

Ukoliko koristimo SASS unutar nekog JavaScript modula (npr. import './scss/main.scss';), onda je potrebno instalirati pored neophodnih paketa vezanih za CSS: “style-loader” i “css-loader” i paket “sass-loader” koji transpilira SASS u CSS. Pored toga je potrebno instalirati i bibloteku (eng. library) za node.js vezanu za SASS node-sass:



Konfiguracija webpack-a za SASS loader

Kod konfiguracije SASS-a se i dalje koristi css-loader da parsira dobijeni css nakon transpiliranja SASS-a kao i style-loader koji ubacuje u takav css u style tag. Takodje se koristi sass-loader za transpilovanje:

Više o ovome možete pogledati na oficijelnoj stranici sass-loader

PostCSS

PostCSS je alat koji može da dodatno obradjuje i transformiše CSS ili SASS fajlove.

Instalacija PostCSS-a



Webpack konfiguracija za postCSS

Nakon instalacije je potrebno dodati 'postcss-loader' u wepack.config.js fajl, kao na sledećem primeru:

NAPOMENA:
Pošto se u nizu “use” loaderi primenjuju u redosledu od poslednjeg ka prvom, stoga je potrebno postcss-loader staviti posle sass-loader.

PostCSS dodaci

Dodavanje funkcionalnosti postCSS loaderu je omogućeno kroz instalaciju dodataka tzv. plugin-a. Postoji više od 200 regularnih plugina koji mogu da rade različite zadatke, neki od često korišćenih plugina su:

  • autoprefixer – dodaje prefikse vezne za odgovarajuće browser-e koristeći bazu podataka sajta Can I Use.


  • cssnext – omogućava da možemo da koristimo najnoviju CSS sintaksu, tako što transformiše novu CSS sintaksu u staru koja je kompatibilna sa starijim browserima. Tako da nije potrebno čekati podršku browsera. Postoji mogućnost da se instalira paket “cssnext”, medjutim prema zvaničnoj dokumentaciji uz “postcss” je preporučeno da se instalira ovako:


  • cssnano – minifikuje i formatira CSS kroz više optimizacija fa bi dobio što manju veličinu fajla za produkciju.


  • rucksack – dodaje nove mogućnosti za rad sa CSS-om, kao npr. responsive typography (font-size: responsive;), shorthand positioning syntax (position: absolute 0 20px;), native clearfix (clear: fix;), automatic font src generation (font-path: ‘/path/to/font/file’;), quantity pseudo-selectors (li:between(4,6))…


Listu ponudjenih plugina možete pogledati na oficijelnom sajtu kao https://github.com/postcss ili na postcss.parts katalogu.h

“postcss.config.js”

U okviru odvojenog fajla postcss.config.js se učitavju i konfigurišu instalirani dodaci:

Babel

Babel je JavaScript transpiler, koji od novih verzija JavaScripta “pravi” kod prema ES5 standardu. Sastoji se od:

  • babel-core je glavni babel-ov npm package
  • babel-loader je modul koji služi da poveže “Babel” i Webpack

Instalacija paketa za Babel

Instalacija webpack-a se vrši sledećim naredbama:



Više o instalaciji Babel-a možete pogledati na oficijelnoj stranici babeljs.io

Konfiguracija webpack-a za babel

Babel preset

Da bi smo mogli da koristimo pripremljena setovanja (eng. preset), potrebno je da ih instaliramo.
Na ovome primeru ćemo da koristimo “env” preset paket koji se instalira sa babel-preset-env, a koristi se da transpilira javascript kod pisan prema verziji koja je aktuelna u trenutnoj godini (ES2017). Možemo da izaberemo i drugi preset za standard definisan u drugoj godini (npr. ES2016), ali je potrebno da koristimo odgovarajući paket za instaliranje babel-preset-es2016. Više o ovim paketima možete pogledati u dokumentaciji na oficijelnom sajtu babeljs.io/docs/plugins/#presets-official-presets



Pored instalacije potrebno je napraviti fajl pod nazivom .babelrc, koji se stavlja u root projekta. Ovaj fajl je zadužen da čuva babel-ova podešavanja, stoga je potrebno unutar tog fajla ubaciti sledjeći konfiguracioni JSON:

Browser list

Pored ove jednostavne konfiguracije babel preset-a, preporuka je da se koristi “inteligentni” način transpiliranja, koji uzima u obzir da noviji browseri podržavaju nove ES standarde. Ovaj inteligentni način selekcije omogućava da se ne vrši transpiliranje u ES5 ako to nije potrebno, jer to povećava veličinu koda. Stoga je preporuka kondicionalno transpilirati JavaScript u zavisnosti na kome browseru se kompajlira JavaScript. Idealno bi bilo kada bi targetirali tačno one browsere koje podržava naš kod. Dovoljno je programtično izabrati browsere:

Browser List je babel-ova biblioteka koja nam omogućava izbor browsera koristeći neke uslove (npr. "last 2 versions"). Više o Browserlist bibloteci pogledajte na oficijelnim stranicama “BrowserList”. Za dobar odabir uslova koristite sledeću online stranicu “browserl.ist”.

Primer: Philipa Waltona

Kada se startuje babel, ovakva konfiguracija će izbaciti dva production-ready javascript fajla:

  • main.js (the syntax will be ES2015+)
  • main-legacy.js (the syntax will be ES5)

Stoga je nakaon ovoga potrebno ubaciti ove skript u željeni HTML fajl:

Više o ovome pogledajte u članku Philipa Waltona Deploying ES2015+ Code in Production Today a primenu ovoga na njegovom GitHub nalogu “Webpack ESNext Boilerplate”

Image loader

U HTML dokumentu browser povlači slike sa servera tek kada “naleti” na <img> tag (ili ne element koji ima svojstvo “background-image”). Koristeći webpack možemo optimizovati slike pa čak ih i sačuvati kao binarni podatak unutar JavaScript-a. Slike ubačene u javascript možemo da preload-ujemo pa ih browser neće morati da ih preuzme sa dodatnim request-om.

Instalacija paketa za img loader



Konfiguracija webpacka za image loader

“image-webpack-loader” kompresuje sliku, nakon čega “url-loader” takvoj kompresovanoj slici proverava veličinu. Ukoliko je slika manja od željene veličine (veličina se definiše kroz options), “url-loader” je sa “Base64 encoding”s prebacuje u šifrovani binarni padatak koji takav ubacuje direktno u JavaScript modul. Ukoliko je kompresovana slika ipak veća od definisane, onda je webpack ubacuje u dist folder kao odvojeni fajl.

Korišćenje

Za korišćenje slika u JavaScript modulu je potrebno da ih importujemo:

Kao što se vidi slike su smeštene u assets folderu, koji se nalazi u root-u projekta. Nakon importa možemo da sa slikama radimo šta god je potreba, npr. jednostavno prikazivanje:

Nakon build-ovanja projekta sa webpack-om u sklopu dist foldera za produkciju se pojavljuje samo velika slika (jer nije prošla test limit 10000), dok je mala slika ugradjena kao binarni string u JavaScript modul.

eslint-loader

ESlinter je jedan od najpopularnijih lintera koda, standardizuje izgled JavaScript koda i nalazi greške odmah pri kompajliranju.

Instalacija

Potrebno je prvo instalirati “eslint core”:



Nakon čega možemo da instaliramo i “eslint-loader”:



Više o eslint-loader možete pročitati na oficijelnoj stranici plugina github.com/MoOx/eslint-loader

Konfiguracija u webpack.config.a

NAPOMENA:
Obratite pažnju na redosled učitavanja loadera, potrebno je da ovaj loader bude pre (čitaj: “ispod”) babel-loader inače će lintovanje biti nad transpilovanim kodom. Postoji mogućnost da se doda properties enforce: "pre" koji mu omogućava da ovaj loader prvi učita bez obzira na mesto u kodu.

Konfiguracija .eslintrc.json

Potrebno je kofigurisati i sam eslint core. Konfigurisanje se čuva u .eslintrc.json fajlu.

Primer konfigurcije

Sekcija “extends” definiše koji set pravila želimo da primenimo. Možemo da koristimo preporučeni set od eslint-a “eslint:recommended” ili instalirati neki drugi npr. “airbnb”
U sekciji “rules” može da se pojedinačno promeni neko od pravila. Listu svih pravila možete pronaći na oficijelnom sajtu u sekciji “rules”. Dovoljno je izabrati neko pravilo i promeniti mu konfiguraciju.

Primer – deaktiviranje pravila

Ukoliko ne želimo da bude primenjeno neko pravilo dovoljno je da u sekciji “rules” ubacimo kod "nazivPravila": 0, pa ako ne želimo da aktiviramo proveru pravila “no-console”:

Enabling sourcemap

SourceMap je fajl unutar koga je mapirana je veza izmedju koda u krajnjem fajlu prikazanog u browseru i originalnih ne-bundlovanih fajlova (koji još nisu transpilovani, minifikoavani, kompresovani,…). Sourcemap omogućava pregledaču da rekonstruiše početni izvor i prikaže rekonstruisan originalni kod u debugeru, iako se on ustvari nalazi okviru krajnjeg minifikovanog i bundl-ovanog fajla.

JavaScript sourcemap

Za aktiviranje ove funkcionalnosti nije potrebno instaliranje nekog paketa, već je dovoljno definisati odredjene parametre u sklopu webpack.config.js fajla:

Nakon ovoga u inspektoru web browser-a će svaki kod biti linkovan sa svojim početnim (originalnim) fajlom pre bundl-ovanja, a ne za bundle.js. Više o ovome možete pročitati na oficijelnom sajtu pod sekcijom using source maps.

CSS & SCSS sourcemap

Najčešća organizacija u radu sa SASS-om je da se svi fajlovi importuju u jedan Da bi aktivirali ovu mogućnost za CSS ili SCSS fajlove, potrebno je dodati kod SCSS/CSS loadera options:{sourceMap: true} kod svakog loadera:

Nakon ovoga u inspektoru web browser-a će svaki elemenat biti linkovan sa svojim početnim (originalnim) SCSS fajlom pre bundl-ovanja, a ne za main.css.

Webpack dodaci (plugin)

Webpack ima svoje plugin-e preko kojih može da proširi svoje funkcionalnosti. Listu dostupnih plugin-a za webpack 2 možete pogledati na oficijenoj stranici https://webpack.js.org/plugins/.

ExtractTextWebpackPlugin

Već smo u predthodnom delu videli kako se CSS fajl jednostavno integriše u JavaScript, a ova tehnika je odlična kada želimo da pravimo “reusable” komponente koje bi se više puta ugradjivale u različite delove programa. Medjutim nije dobro primeniti ugradjivanje stilova u javascript za sve stilove aplikacije, jer bi stilovi bili učitani kada i javascript a to je najčešće tek nakon učitavanja DOM-a. To je neprihvatljivo sa stanovišta “user experience”, jer bi korisniku u jednom trenutku bio prikazan nestilizovani sadržaj.
ExtractTextWebpackPlugin je webpack plugin koji omogućava da se obradjeni CSS (transpilovan, minifikovan…) ipak izdvoji u zasebni fajl. Tako izdvojeni CSS fajl može da se jednostavno ugradi u vrh HTML-a kroz link tag, što će nam obezbediti da se stilovi učitaju pre DOM-a. Ovakva tehnika nam omogućava da korisnik odmah nakon učitavanja
DOM-a vidi stilizovan sadržaj.

Instalacija ExtractTextWebpackPlugin



Konfiguracija webpack-a za ExtractTextWebpackPlugin

Nakon instalacije potrebno je ažurirati konfiguracioni fajl webpack.config.js. Prvo je potrebno na vrhu fajla importovati plugin modul:

Nakon čega je potrebno editovati deo vezan za CSS i zameniti “style-loader” sa pluginom:

Takodje je slično potrebno uraditi kod SCSS dela:

Pored navedenih izmena potrebno je dodati novu sekciju u webpack.config.js vezanu za plugin, koja “obaveštava” webpack koji plugin koristimo i u koji fajl želimo da izdvojimo CSS iz JavaScript fajla bundle.js.

Nakon startovanja webpack-a, pojaviće se novi fajl “style.css”, koji je potrebno ubaciti u našu HTML stranicu:

HtmlWebpackPlugin

Namena ovog dodatka je da generiše novi HTML fajl na osnovu nekog template-a, koji se dinamički povezuje sa generisanim “bundle.js” fajlom.

Instalacija HtmlWebpackPlugin



Konfiguracija webpacka za HtmlWebpackPlugin

Potrebno je na vrhu fajla importovati zahtevani plugin:

A zatim u delu za vezan za plugine pored prethodno ubačenog ExtractTextPlugin, dodati i ovaj:

Nakon startovanja webpacka-a on će generisati novi HTML fajl index.html, koji u sebi već ima ubačene veze do dva takodje generisana javascript fajla:

Generisanje HTML-a na osnovu template-a

Prethodno generisani HTML fajl osim što ima inkludovane skripte i nije naručito interesantan. Stoga je potrebno napraviti HTML template sa odgovarajućim sadržajem, koji ćemo da iskoristimo za generisanje novog HTML-a. Povezivanje templeta i odgovarajućeg JavaScript fajla se vrši definisanjem objekta koji se prosledjuje kao parametar HtmlWebpackPlugin pluginu. Kroz taj objekat se definiše ime i putanja HTML template-a koji se koristi, kao i naziv odgovarajućeg bundlovanog JavaScript dela.

Medjutim najverovatnije je da se aplikacija ne sastoji samo iz jednog HTML fajla tj. stranice, nego iz više njih, stoga je potrebno da drugačije organizujemo projekat i promenimo konfiguraciju plugina.
Napravićemo novi folder u okviru src foldera koji ćemo da nazovemo “views”, a koji je zadužen da se u njemu čuvaju template HTML stranice. Unutar njega možemo da napravimo dve HTML stranice koje ćemo nazvati “index.html” i “druga.html”. Nakon ovoga je potrebno da promenimo trenutnu konfiguraciju za HtmlWebpackPlugin u okviru webpack.config.js fajla:

Više o ovome pluginu pogledajte na webpack sajtu pod sekcijom “Setting up htmlwebpackplugin”, ili na samoj stranici plugina “Html webpack plugin”, dok se o gotovim templejtima možete pročitati na https://github.com/jaketrent/html-webpack-template.

CleanWebpackPlugin (čišćenje /dist foldera)

Pri svakom menjanju imena fajlova koji treba da se generišu, u folderu za produkciju će se generisati novi preimenovani fajlovi. Medjutim fajl sa starim nazivom neće nestati, iako je nepotreban, tako da se pravi gomila nepotrebnih fajlova u produkcijskom folderu. Iz toga razloga nam je potrebno brišemo stare fajlove pre generisanja novih, pa ćemo da koristimo plugin pod nazivom “clean-webpack-plugin”. Ovaj dodatak pri svakom stratovanju webpack-a, prvo briše sadržaj celog produkciskog foldera “dist”, a zatim generiše nove fajlove u njega.

Instalacija CleanWebpackPlugin



Konfiguracija CleanWebpackPlugin

Prvo je potrebno na vrhu stranice importovati instalirani plugin

A zatim u delu za vezan za plugine dodati i ovaj:

Više o ovome plugin-u pogledajte na oficijelnoj stranici pod sekcijom Cleaning up the dist folder.

CommonsChunkPlugin

Ukoliko aplikacija ima dosta “third party dependencies”, preporuka vezana za optimizaciju aplikacije je da se “third party dependencies” izdvoje u tzv. “Vendor Chunk”. Ovo se radi iz razloga što želimo da browseru omogućimo da kešira ove podatke jer se oni za razliku od našeg koda retko ažuriraju. Ovaj postupak smo već obradili u sekciji “Definisanje višestrukih ulaznih i generisanje više izlaznih fajlova”, stim što ćemo u sada u drugi bundle file da ga nazovemo “vendor” a u njega ćemo da stavimo sve “third party dependencies” a koji se nalaze u package.json fajlu pod “dependencies”. Više o ovome pročitajte na oficijelnom sajtu u sekciji “explicit-vendor-chunk”.

Primer

U ovome primeru je generisan jednostavni Vue.js projekat webpack-simple, u sklopu koga je “vue” kao third party dependencies.

Prethodni kod će da generiše dva fajla: app.bundle.js i vendor.bundle.js, pa će browser moći da kešira vendor.bundle.js. Medjutim pri ovom postupku se pojavio probem da su sada ta dva fajla u zbiru veća nego početni bundle.js fajl pre razdvajanja. Ovo se dešava jer je u ulaznom fajlu index.js na vrhu fajla “ručno” importvan neki od “third party dependencies”, pa je došlo do dupliranja.
Rešenje problema dupliranja je plugin pod nazivom “CommonsChunkPlugin”.

Konfiguracija CommonsChunkPlugin

Ovaj plugin je već ugradjen u sam webpack stoga ga ne treba instalirati, potrebno ga je samo konfigurisati.

Ovakva konfiguracija govori webpack-u da proveri da li unutar “entry” fajlova (u ovome slučjau “app” i “vendor”) postoji neki paket koji se nalazi u oba fajla, i ako postoji da ga stavi samo u onaj pod nazivom “vendor”.

UPDATE:
Webpack 4 je ukinuo “CommonsChunkPlugin” a umesto njega koristi druge dve opcije “optimization.splitChunks” i “optimization.runtimeChunk”, više o ovome pogledajte u članku “RIP CommonsChunkPlugin”.

UglifyjsWebpackPlugin

Glavna namena ovoga plugina je minifikacija JavaScript-a.

Instalacija



Konfiguracija

Da možemo da konfigurišemo, prvo je potrebno da importujemo plugin na vrhu webpack.config.js fajl.

Nakon čega možemo u sekciji zaduženoj za plugine dodamo i ovaj plugin:

Prethodna konfiguracija će biti stalno aktivna, medjutim šta ako želimo da se minifikuje samo kada se build-uje za produkciju – onda se koristi uslov:

Više o ovome pluginu pročitajte na oficijelnom sajtu u sekciji UglifyjsWebpackPlugin, a o setovanju process.env.NODE_ENV promenjive pogledajte u istoimenoj sekciji “process.env.NODE_ENV”

Dinamičko učitavanje JavaScript modula

Dinamičko učitavanje modula podrazumeva da se u okviru jednog JavaScript fajla, dinamički (nakon akcije korisnika) poziva izvršavanje drugog JavaScript fajla. Ceo sistem se zasniva na specifičnom delu koda koji se nalazi u okviru početne stranice iz koje se zahteva učitavanje novog modula, a bavi se dinamičim učitavanjem modula:

Nakon izvršavanja ovog dela koda u stranicu se učitava i dodani JavaScript modul.
Sintaksa “System.import()” nam omogućava dinamičko i kondiciono učitavanje jednog modula. Pisana je prema ES2015 standardu i bazirana je na Promisima stoga vraća Promise.

Više o ovome možete pročitati u specifikaciji ES2015 standarda.

process.env.NODE_ENV

Kada koristite neki od framework-a tokom razvoja aplikacije, framework je stalno na oprezu i vrši česte provere da bi vam pružio potrebna upozorenja kako bi vam pomogao u pogledu uobičajenih grešaka i zamki. Međutim, to postaje beskorisno u krajnjoj produkciji a povećava veličinu aplikacije pri učitavanju i samo opterećuje aplikaciju. Produkciski režim u framework-u se definiše preko promenjive “process.env.NODE_ENV”, stoga je bitno da u wepack-u definišemo ovu promenjivu kada želimo da pošeljemo aplikaciju na produkciju. Za ovu namenu se koristi webpack-ov DefinePlugin, jer on omogućava da se setuju promenjive operativnog sistema. Da bi mogli da koristimo ovaj webpack-ov plugin u okviru “webpack.config.js” fajla, neophodnoje da ga prvo importujemo u fajl:

Zatim da preko ovog plugina da definišemo promenjivu ‘process.env.NODE_ENV’:

Medjutim nepotrebno je da i pri radu u lokalu sa dev serverom, promenjiva “process.env.NODE_ENV” bude setovana na “production”, stoga je potrebno promenjivu definisati programabilno. To se postiže tako što drugačije konfigurišemo DefinePlugin:

Sa prethodnim kodom smo rekli webpack-u da će sistemska promenjiva “process.env.NODE_ENV” biti ista kao što je promenjiva u našem lokalnom sistemu. A definisanje te promenjive u lokalnom sistemu se vrši konfiguracijom kroz “scripts” svojstvo u okviru fajla “package.json”:

Ukoliko ne koristimo “UglifyjsWebpackPlugin” možemo da monifikujemo kod produkcije dodavanjem flag-a -p:

Završna verzija projekta uz članak

Svi primeri iz članka objedinjeni su u jedan projekat. Završna verzija projekta je objavljena na GitHub-u
https://github.com/choslee/webprogramiranje-webpackOsnove.

webpack.config.js

package.json



Front-End alati (pregled)

Package manager

Uvod

frontend

Današnji web development se zasniva na skupu različitih tehnologija koje se istovremeno koriste na jednom projektu, kao što je: Typescript (jezik), Sass (CSS ekstenzija), JSCS (code style linter and formater), JSHint ili TSLint (alat za detekciju grešaka i potencijalnih problema), BrowserSync (alat za sihronizaciju promena u kodu i u browser-u – Live reload )… Za jedan projekat je potrebna instalacija svakog od navedenih programa ali i svih programa (dependencies) od kojih zavise isti a prethode njihovoj instalaciji.
Package manager eliminiše potrebu za ručnim instaliranjem softvera sa svim neophodnim pratećim softverom (dependencies) kao i za ažuriranje svih tih komponenti. Package manager je skup alata zaduženih da automatizuju procesa instaliranja, konfigurisanja i uklanjanja programa. Package manageri rade sa packages tj. sa softwerom ili podacima koji se nalaze u arhivnim fajlovima. Package sadrže meta-data koji opisuju dati softver kao što je naziv softvera, verzija i lista svih dependencies (drugi softver neophodan za rad datog sofvera). Najpoznatiji package menadžeri su:

  • npm
  • bower
  • JSPM (JavaScript Package Manager)
  • Yarn

Continue reading…


Git naredbe

.gitignore

Pre aktiviranja Git-a potrebno je sprečiti čuvanje i praćenje izmena nepotrebih fajlova. Najčešće su to fajlovi koje koristi editor ili fajlovi koji nastaju kompajliranjem i sl. Fajlove ili cele direktorijume koje ne želimo da pratimo definišemo u okviru .gitignore. .gitignore fajl se smešta u okviru projektnog foldera.
Ovaj fajl se popunjava odgovarajućim naredbama uz čiju pomoć Git saznaje koje fajlove ne treba da prati. Princip obeležavanja fajlova i foldera koje ne želimo da pratimo unutar .gitignore je sledeći:

  • Upišemo ekstenzije fajlova sa razmakom koje ne želimo da pratimo kao npr.

    .swo .swp

  • Upišemo foldere koje ne želimo da pratimo:

    ime_foldera

    U slučaju da unutar foldera postoji fajl koji ipak treba da se prati upišemo:

    !nekiFajl.txt

  • Upišemo folder i njegove podfoldere koje ne želimo da pratimo:

    ime_foldera/ime_podfoldera

    Pregled grana

  • Upišemo folder i sve njegove podfoldere koje ne želimo da pratimo:

    ime_foldera/*

  • Upišemo sve objekate i arhive koje želimo da ignorišemo:

    *.[oa]

Postoji na internetu veliki broj primera .gitignore u zavisnosti kakav je projekat u pitanju (WordPress, Android….), a odličan sajt za nalaženje adekvatnog možete naći na sledećem linku: toptal/.gitignore.

Prekid praćenja

Veoma je bitno napraviti .gitignore file pre iniciranja Git-a jer ukoliko Git već započene praćenje odredjenog fajla on neće prestati da ga prati čak i ako taj neželjeni fajl naknadno ubacimo u .gitignore. U nastavku su opisane potrebne radnje za prekid prećenja nekog fajla.

a) Prekid praćenja bez fizičkog brisanja

Ukoliko su greškom commit-ovani neki nebitni fajlovi za projekat, čije promene ne želimo da čuvamo, ali ne želimo ni da ih fizički obrišemo iz radnog direktorijuma, potrebno je da naredimo git-u da prestane da ih prati (tj. da ih izbaci iz repozitorijuma) sa naredbom:

Naredba za prestanak praćenja direktorijuma je:

gde -r govori Git-u da stane da prati sve podirektorijume i fajlove unutar njega.

Nakon naredbe za prekid praćenja, fajl se nalazi u prostoru pripreme (index). Da bi sprečili da fajlovi na sledećem commit-u ponovo ne udju u repozitorijum, potrebno je te fajlove pre commit-ovanja, ubaciti u .gitignore fajl.

NAPOMENA:
Obratiti pažnju da ukoliko naziv fajla sadrži razmak izmedju reči, neophodno je staviti ga u znake navoda, kao na sledećem primeru:
git rm "neki naziv fajla sa razmacima.ekstenzija"

b) Prekid praćenja sa fizičkim brisanjem

Ukoliko postoji potreba da se fajl pored izbacivanja iz repozitorijuma i obriše iz radnog direktorijuma koristimo naredbu:

Ukoliko je u pitanju direktorijum koristimo naredbu:

gde -r govori Git-u da stane da prati sve podirektorijume i fajlove unutar njega. Nakon naredbe za brisanja fajlova je takodje neophodno uraditi commit (bez prethodnog slanja u index).

Više o ovoj naredbi pogledajte na oficijelnoj stranici

Lokalni repozitorijum

Kada želimo da aktiviramo Git tj. da počnemo da pratimo izmene u projektu, potrebno je da unutar projektnog folder-a iniciramo pravljenje “radnog git repozitorijuma” koji se vrši na sledeći način:

Ova naredba unutar našeg projekta kreira novi folder .git (tzv. “repozitorijum”) i u njemu će se nalaziti celokupna baza o našem projektu. Od tog trenutka Git prati projekat i radi snapshot-ove stanja kad uradimo commit. Ukoliko želimo da Git više ne prati naš projekat dovoljno je da obrišemo ovaj folder.

pregled grana nakon kloniranja

Lokalni repozitorijum je u specifičnoj vezi sa udaljenim jer je on “svestan” postojanja udaljenog repozitorijuma. U okviru lokalnog repozitorijuma uvek postoje minimum dve grane (vidi sliku):

  1. Grana pod nazivom “origin/master” koja je lokalna verzija (kopija) udaljenog repozitorijuma. Na ovu granu se ne mogu slati naše izmene, već ona služi da sa nje uzmemo izmene (merge) jer je ona praktično posrednik tj. medjukorak za dobijanje izmena sa udaljenog repozitorijuma.
  2. Grana pod nazivom “master” je naša lokalna grana direktno povezana za projekat (u kojoj pravimo commit-e).

Continue reading…


Grunt

Uvod

Grunt je alat napisan u Node.js, stoga je pre instaliranja Grunt-a potrebno instalirati Node.js i njegov package manager npm. Ukoliko su već instalirani potrebno je proveriti da li su ažurne verzije i ako je potrebno uraditi njihov update. Pošto je jedano od čestih zadataka Grunt-a kompajliranje SASS-a u CSS, potrebno je imati instaliran SASS. Sve ove instalacije su objašnjene u članku Install tools for web development

Npm i početni package.json

Package.json se koristi od strane npm-a jer čuva meta podatke vezane za module koje instalira npm u okviru projekta. Unutar fajla se nalazi lista i mapa sa zavisnostima projekta (dependecies ili devDependecies) koji mogu da se downloaduju. Ovime olakšavamo nekome ko će da koristi naš projekat da ih downloaduje samo ako mu trebaju.

Za lokalnu instalaciju je potrebno da namestimo putanju u komonadnoj liniji na lokalni izabrani folder gde ćemo praviti grunt projekat. Zatim izdajemo naredbu koja pravi osnovni package.json fajl:

npm init

Nakon startovanja naredbe u command prompt-u aplikacija traži da se popune pitanja koja su potrebna za pravljenje package.json fajla, kao što su :

  • name
  • version
  • description
  • keywords
  • ….

Više o popunjavanju pogledajte ovde

Grunt instalacija

Globalna instalacija Grunt-a

Instalacija grunta se vrši iz komandne linije sa naredbom:

npm update -g grunt

Instalacija interfejsa

Zadatak interfejsa je da učitava lokalnu instalaciju Grunt biblioteke i da primenjuje konfiguraciju iz lokalnog Gruntfile-a da bi izvršio zadatke koji su od njega zatraženi

Instaliranje command line interfejsa tzv. grunt-CLI naredbom:

npm install -g grunt-cli

Lokalna instalacija Grunt-a

npm install grunt –save-dev

Instalacija Grunt plugina

Gruntu se najčešće dodaju već pripremljene funkcionalnosti preko plugin-a. Pri instaliranju plugina postoje dve mogućnosti za čuvanje zavisnosti kao:

  • dependeces
    su zavisnosti koje se uvek downloaduju sa vašim modulom
  • devDependeces
    su zavisnosti koje se koriste samo pri razvoju. Kada stavimo neku zavisnost u devDependeces onda možemo da sprečimo da krajnji korisnik ne downloaduje i ove zavisnosti koje se koriste samo pri razvoju modula. Ukoliko želimo plugin bude kao razvojni depenseces onda pri instalaciji uz naredbu dodajemo nastavak “-dev” deo.

Pri instaliranju plugina u package.json fajl se automatski dodaje odogovarajući zapis. U zavisnosti da li smo koristili nastavak “-dev” ili ne zapis će biti sačuvan ili u “dependeces” ili “devDependencies” sekciji.
Spisak i pretragu svih dostupnih grunt plugin-ova možete potražiti na oficijelnom sajtu. ili izlistati jednostavnom naredbom:

npm search grunt

Najčeće korišćeni plugini za grunt su:

Naredbe sa nastavkom ” -dev ” označavaju da će se dependences koristiti pri razvoju projekta (tj. development-u) i pojaviće se u package.json fajlu pod “devDependencies”!

Primer

Pri instalacija lokalnih dev-dependences preko pluginova automatski se unutar package.json fajla popunjava i njegov kod koji po završetku instaliranja može da izgleda ovako:

Definisanje karakteristika Grunta (gruntfile.js)

Kada u package.json fajlu definišemo zavisnosti onda ćemo moći da ih pozovemo u okviru Gruntfile-a jednostavnim komandama. Pravljenje Gruntfile.js počinje kreiranjem samog fajla u root-u našeg projekta i ubacivanjem početnog koda:

Svaki zadatak koji želimo da dodamo mora prvo da prethodno da bude instaliran kao dependences u package.json-u.

Svojstva grunt objekta

  1. InitConfig

    Ovo svojstvo se koristi za konfigurisanje svojstava plugina. Objašnjenje kako se definišu svojstva vezana za primenu svakog plugina je najčešće objašnjeno kroz primere na oficijelnim stranicama plugin-ova:

    Primer

  2. LoadNpmTasks

    Ovo svojstvo se koristi za učitavanje plugina:

  3. RegisterTask

    Ovo svojstvo definiše alias naredbe koje objedinjuju više zadataka u odredjenom redosledu.

    Primer

    Ovo svojstvo će biti bolje objašnjena na sledećem primeru:

    Naredba pod aliasom “dist” iz prethodnog primera će izvršiti dve operacije (concat i uglify) a pokrenuće se u CMD-u sa samo jednom naredbom:

    grunt dist

    Ukoliko za prvi parametar fukcije stavimo default tada će se koristi default-na naredba za alias “grunt”

    Defaultni alias se pokreće sa naredbom:

    grunt

    Pogledajte više o ovome ovde

    NAPOMENA:
    Pri korišćenju naredbe grunt.registerTask zadatak “watch” mora da uvek bude poslednja stavka jer ovaj zadatka traje sve dok ga user ne prekine, što znači da se ne bi nikada startovao zadatak posle njega!

Primer

Na sledećem primeru je prikazan mogući krajnji izgled gruntFile.js:

Kreiranje Grunt projekta koristeći template

Template Grunt projekata se koristi za rapid programming jer omogućava korišćenje već gotovih template-a. Template možete praviti sami ili koristiti neke sa github-a. O korišćenju template-a pročitajte na oficijelnoj stranici ovde.

Instalacija gotovih template

Pre korišćenja pripremljenih template-a, moramo prvo da instaliramo svaki template koji ćemo koristiti na naš komjuter. Da bi instalirali template moramo prvo da imamo globalno instaliran noseći sistem za template (grunt-init), ukoliko ga nemamo instaliranog onda ga instaliramo naredbom:

npm install -g grunt-init

Nakon ovoga nam je dostupna naredba grunt-init i sa njom možemo da instaliramo template.

Pluginovi za template se pri instalaciji smeštaju u folder .grunt-init, pa zbog toga pri instaliranju path u komandnoj linij treba da bude namešten na:

C:\Users\ImeUsera\.grunt-init

U folderu .grunt-init možemo proveriti da li su neki template-ovi već instalirani, mada isto možemo da uradimo i sa naredbom:

grunt-init –help

Svaki template se instalira prema uputstvu na njegovoj oficijelnoj stranici, mada je najčešće ponudjeno da se klonira projekat.
Windows korisnici moraju da obrate pažnju na link sa koga se klonira jer moraju da naprave malu promenu tako što iz linka za kloniranje obrišu ~/

Primer

U ovome primeru je korišćena naredba za kloniranje iz template-a grunt-init-jquery

C:\Users\ImeUsera\.grunt-init>git clone https://github.com/gruntjs/grunt-init-jquery.git ~/.grunt-init/jquery

A da bi se koristio i na windows-u moramo ga prepraviti tako što ćemo obrisati “~/”

C:\Users\ImeUsera\.grunt-init>git clone https://github.com/gruntjs/grunt-init-jquery.git .grunt-init/jquery

Neki od često korišćenih template-a su:

Kreiranje Grunt projekta

Napravimo folder gde ćemo da stavimo naš novi grunt projekat, zatim u komandnoj liniji dok smo unutar projektnog foldera napravimo grunt projekat prema template-u koji smo već prethodno instalirali globalno, koristeći naredbu:

zatim je neophodno da downloadujemo (instaliramo) sve dependeces koje su navedene u package.json sa naredbom:

npm install

Dependeces će biti smešteni u folderu node_modules.

Postoji mogućnost da napravimo naše custom templates ali to je advance tema, više o custom template ovde.


Emmet plugin

Uvod

Emmet je sjajan plugin za ubrzano pisanje koda koji može da se doda mnogim poznatim text editorima i IDE. Poseduje određene skraćenice koje, kada se kombinuju, daju gotov kod koji je mnogo duži i kompleksniji. Instalira se kao dodatak (plugin) a instalacija zavisi od IDE aplikacije u koju se implementira. Opisao sam kako se Emmet plugin instalira u sklopu PHP Storm-a na stranici “Instalacija alata za web development”. Koristi se tako što se u editoru ispiše skraćenica (eng. abbreviation) nakon čega se pritisne “okidač dugme”, default-no dugme je TAB.

Continue reading…


Git osnove i instalacija

Uvod u sisteme za praćenje koda

Postoje dve vrste sistema za praćenje i kontrolu verzija:

  • Sistem sa centralizovanom verzionom kontrolom (CVCS)

    Ovde pripadaju alati kao što su SVN, Perforce i CVS. Kod CVC sistema svi podaci o verzijama se nalaze na centralnom serveru dok korisnici imaju dostupnu samo trenutnu verziju na kojoj rade. Ovaj princip rada omogućava lakše održavanje i administriranje ali je sigurnost podataka problematična ukoliko dodje do otkaza sistema gube se sve informacije.

  • Sistem sa decentralizovanom verzionom kontrolom (DVCS)

    kojoj pripadaju: Mercurial, Bazaar, Darcs i Git. Kod DVC sistema korisnici pored poslednje verzije preuzimaju i kompletnu bazu o svim verzijama na tom repozitorijumu. U slučaju otkaza sistema dovoljno je da samo jedan od klijenata postavi podatke na server.

Continue reading…