.

.

środa, 10 maja 2017

Gulp - pierwsze kroki

Ostatnio nie wiem, w co ręce włożyć. Chcąc złapać kilka srok za ogon, rozgrzebałam parę różnych tematów, luźno powiązanych ze sobą. W efekcie: dużo jest zaczęte, mało jest skończone. Wszystkiemu winna... pogoda! ;)

Wśród wspomnianych "rozgrzebek" znalazł się też Gulp, z którym próbuję zawrzeć bliższą znajomość.

Gulp - logo

Gulp służy do automatyzowania powtarzalnych zadań (głównie dotyczących plików). Szczerze mówiąc, nie odczuwam teraz szczególnie palącej potrzeby używania go (BUKA to mały projekt, a ja sama, będąc na początku programistycznej drogi, chyba nie do końca mam świadomość, co tracę, nie korzystając z żadnego narzędzia do automatyzacji). Niemniej - mówią na mieście, że warto coś takiego znać i umieć używać. Dlatego poczyniłam pierwsze kroki w tym kierunku. Opisuję je poniżej, by były mi (a może i innym mnie podobnym) pomocą w potrzebie.


Zatem - co trzeba zrobić, by włączyć Gulpa do swojego projektu?


KROK 1: INSTALACJA

npm install -g gulp-cli

  • instaluje program Gulp (runner) na danym komputerze
  • oznacza to, że Gulp staje się dostępny w linii poleceń (jeszcze nie w node modules)
  • polecenie wykonywane raz per maszyna

npm install --save-dev gulp
  • instaluje lokalnie (do mojego projektu) Gulpa jako takiego
  • oznacza to, że Gulp staje się dostępny w danym projekcie w node modules
  • polecenie wykonywane osobno per każdy projekt
  • zależność jest dopisywana automatycznie w pliku package.json w devDependencies

npm install --save-dev gulp-concat
  • instaluje lokalnie (do mojego projektu) gulpowy plugin o nazwie 'concat', który łączy (konkatenuje) wiele plików w jeden
  • zależność jest dopisywana automatycznie w pliku package.json w devDependencies


KROK 2: DODANIE PLIKU GULPFILE.JS


Następnie należy stworzyć w projekcie nowy plik gulpfile.js (taka nazwa jest wymagana przez Gulp), który będzie zawierać konfigurację tasków Gulpa:

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

Słowem komentarza:
  • w node.js jest dostępna specjalna funkcja require (niedostępna w przeglądarce), która ładuje zawartość modułu js do zmiennej (tutaj modułem jest 'gulp');
  • ładowanie odbywa się tutaj synchroniczne, bo node.js operuje w tym przypadku w ramach jednego komputera, więc wszystkie rzeczy "ma" pod ręką (nie ma tu potrzeby ładownia asynchronicznego);
  • zmienna gulp to Gulp sam w sobie, zmienna concat to plugin Gulpa (odpowiadający za wspomnianą wcześniej konkatenację plików);
  • każdy plugin Gulpa będzie miał swoją osobną zmienną i swój osobny moduł (będzie osobno instalowany npm-em i osobno require'owany do pliku gulpfile.js);
  • natomiast require('gulp') jest wykonywane tylko raz


KROK 3: STWORZENIE PIERWSZEGO TASKA


Przykładowy task wygląda tak:

gulp.task('scripts', function() {
  return gulp.src(['./app.js', './utils.js', './model.js'])
  .pipe(concat('all.js'))
  .pipe(gulp.dest('./dist/'));
});

Słowem komentarza:
  • gulp.task - tworzy nowy task
  • pierwszy parametr 'scripts' to nazwa taska; wg tej nazwy będzie on uruchamiany z linii poleceń (dla powyższego przykładu będzie to polecenie: gulp scripts):
  • drugi parametr, czyli function, określa, co ten task ma robić (w powyższym przypadku: co i skąd wziąć, co z tym zrobić, gdzie zrzucić wynik)


Co się zmieniło na tym etapie w projekcie?

Do tego momentu miałam tylko pliki źródłowe, zawierające kod aplikacji: app.js, utils.js, model.js. Od tej pory mam pliki źródłowe oraz tzw. zbudowaną aplikację (z ang. build files, bundles), czyli dotychczasowe osobne pliki połączone w jeden plik - all.js. Co istotne - jedne muszą być oddzielone od drugich. I tak:

  • pliki źródłowe trafiają do folderu src (nazwę można dowolnie określić, src to popularna konwencja); trzeba więc zaktualizować ścieżki w index.html, aby były aktualne, jeśli zdarzy się skorzystać ze źródłowych plików do odpalenia apki
  • zbudowana apka trafia do folderu dist (nazwa - jw.; inna popularna nazwa to build)


KROK 4: AKTUALIZACJA PLIKU .GITIGNORE

Zbudowana apka jest wtórna względem źródeł, dlatego w repozytorium należy trzymać tylko pliki źródłowe. Build powinien być ignorowany przez gita (tj. powinien pozostawać poza repo), dlatego do .gitignore trzeba dodać nazwę folderu, w którym znajduje się utworzony teraz build (i w którym znajdą się wszystkie inne pliki, które zostaną stworzone innymi taskami Gulpa w przyszłości) - u mnie jest to folder o nazwie 'dist'.



KROK 5: TWORZENIE KOLEJNYCH TASKÓW


gulp.task('default', ['scripts']);

  • powyższa linijka tworzy gulpowy task o nazwie 'default', który będzie uruchamiać stworzony wcześniej task o nazwie 'scripts'
  • dzięki temu nie będę musiała za każdym razem pisać gulp scripts, chcąc uruchomić task 'scripts' (wystarczy samo gulp):


gulp.task('watch', ['default'], function() {
  gulp.watch([appJs], ['scripts']);
});
  • tworzy task o nazwie 'watch'
  • ustawia on pojedynczego 'watchera', który nasłuchuje na plikach podanych w lewej tablicy [appJs] - jeśli coś się w nich zmieni, zostaną wykonane taski zdefiniowane w prawej tablicy (u mnie na razie jest jeden task), czyli ['scripts']

  • każdy gulp.watch to osobny, niezależny 'watcher', którego działanie można streścić tak:
    • gulp.watch nasłuchuje na plikach i folderach na dysku twardym;
    • jeśli system operacyjny wyśle sygnał, że nastąpiła zmiana w jakiejś ścieżce - gulp.watch sprawdza, czy jest to ścieżka, na której nasłuchuje
    • jeśli okaże się, że tak, to wtedy gulp odpala odpowiednie taski
  • zmianą na plikach/folderach może być:
    • zmiana zawartości
    • stworzenie
    • zmiana ścieżki
    • zmiana nazwy


Na koniec dnia mój plik gulpfile.js wygląda tak:


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

var appJs = ['./src/app.js', './src/utils.js', './src/model.js'];

gulp.task('scripts', function() {
  return gulp.src(appJs)
    .pipe(concat('all.js'))
    .pipe(gulp.dest('./dist/'));
});

gulp.task('watch', ['default'], function() {
    gulp.watch([appJs], ['scripts']);
});

gulp.task('default', ['scripts']);


Brak komentarzy:

Prześlij komentarz