Gulp
Gulp – automatyzacja pracy. Jeżeli jeszcze tego nie zrobiłeś, możesz przeczytać wstęp do pakietów i zależności WordPress oraz informacje o NPM.
Kiedy pracujemy, tworzymy strony, szczególnie wtyczki i szablony WordPress (co jest celem naszego kursu), warto postawić na automatyzację pracy. Gulp, którego sobie zainstalowaliśmy w projekcie „Hello World” za pomocą NPM, właśnie na to nam pozwala. Podobnie, jak przy NPM, Gulp też ma swój plik konfiguracyjny. Nazywa się gulpfile.js
i jest, tak naprawdę, kodem JavaScript. No, to zaczynajmy, nie ma na co czekać. Od razu wpiszemy też trochę treści:
Od razu rozpoznajemy dwa problemy. Pierwszy jest dosyć oczywisty. Deklarujemy sobie zmienną gulp
a następnie nic z nią nie robimy. Drugi problem – phpStorm nie rozpoznał funkcji require. Co robić, jak żyć? Cóż, spróbujmy sobie to uruchomić. Punkt pierwszy jest dosyć oczywisty, ale dlaczego phpStorm nie rozpoznaje require? Bo… możemy go nie mieć! Dlatego wracamy do ustawień phpStorm, Languages & Frameworks, Node.js and NPM. Klikamy plusik z prawej strony i wybieramy pakiet RequireJS. Klikamy Install i już go mamy! Potrwa to chwilkę, zanim phpStorm się zorientuje, ale już po chwili require nie jest podkreślone.
Tasks – zadania
Gulp pracuje na zasadzie zadań. Na początek zdefiniujemy zadanie domyślne (default task), które będzie się wykonywało wtedy, kiedy wciśniemy odpowiedni przycisk w phpStorm. Wygląda to prosto, łatwo i przyjemnie:
1 2 3 4 5 6 7 |
'use strict'; let gulp = require('gulp'); gulp.task('default', function () { }); |
The following tasks did not complete: default
Did you forget to signal async completion?
Teraz możemy kliknąć prawym przyciskiem myszy na plik gulpfile.js i z menu kontekstowego wybrać opcję „Run default” lub nacisnąć Control-Shift-F10. Po pierwszym uruchomieniu stanie się też aktywny zielony przycisk uruchamiania zadań (podobnego kształtu co „Play” w odtwarzaczach). Po uruchomieniu zadania, otrzymamy błąd, który mówi nam: „The following tasks did not complete: default / Did you forget to signal async completion?”. Dzieje się tak, dlatego że Gulp od wersji 4 wymaga zwracania określonych wartości, aby sygnalizować zakończenie pracy funkcji. Wcześniej zakładał, że zadanie jest synchroniczne i jeżeli funkcja się zakończyła, to zakończyło się zadanie. Teraz musimy system o tym poinformować, zwracając określoną wartość.
Co możemy zwrócić?
Callback function – to akurat ja lubię robić. Do funkcji dopisuję parametr done a następnie go wywołuję, jak funkcję.
Stream – chyba najczęściej wybierana metoda. Zwróć po prostu łańcuch znaków.
Promise – zwracamy obiekt Promise. Dosyć często ten obiekt występuje w używanych pakietach, nawet nie trzeba go tworzyć.
RxJS Observable – jeżeli akurat tego używasz, możesz zwrócić obiekt Observable.
Child process – zwrócenie procesu potomnego, przydatne gdy chcesz korzystać z funkcji w linii poleceń.
Ponieważ zrobię to, co lubię, teraz nasza funkcja wygląda tak:
1 2 3 4 5 6 7 |
'use strict'; let gulp = require('gulp'); gulp.task('default', function (done) { done(); }); |
Uruchamiany zadanie i co dostajemy?
1 2 3 4 5 6 |
"C:\Program Files\JetBrains\PhpStorm 2018.1.6\bin\runnerw.exe" "C:\Program Files\nodejs\node.exe" C:\bin\projects\kursy\hello-world\node_modules\gulp\bin\gulp.js --color --gulpfile C:\bin\projects\kursy\hello-world\gulpfile.js default [21:43:20] Using gulpfile C:\bin\projects\kursy\hello-world\gulpfile.js [21:43:20] Starting 'default'... [21:43:20] Finished 'default' after 2.16 ms Process finished with exit code 0 |
Działa! Tak, działa. Ale nic więcej nie robi. Zmieńmy to!
Gulp zaczyna automatyzować pracę
Wyobraźmy sobie… zresztą nic sobie nie wyobrażajmy. Przecież nasza wtyczka, nawet jeżeli to zwykłe Hello World!, będzie potrzebowała jakiegoś arkusza stylów. Cóż, nie bez powodu dobierałem pierwsze pakiety. A więc do dzieła. Teraz zmieniło się sporo!
gulpfile.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
'use strict'; let stylesheet_path = './source/stylesheets/', assets_path = './wordpress/wp-content/plugins/hello-world/assets/', gulp = require('gulp'), auto_prefix = require('gulp-autoprefixer'), sass = require('gulp-sass'), concat = require('gulp-concat'); gulp.task('styles', function (done) { gulp.src([ stylesheet_path + 'css/*.css', stylesheet_path + 'sass/*.scss', ]) .pipe(auto_prefix()) .pipe(sass({outputStyle: 'compressed'})) .pipe(concat('hello-world.min.css')) .pipe(gulp.dest(assets_path + 'css/')); done(); }); gulp.task('default', gulp.parallel('styles')); |
Tak, tak teraz wygląda nasz plik Gulp. Prawda, że zmiany są spore? Jak możecie się łatwo domyślić, pojawią się problemy. Zacznijmy od najbardziej trywialnego. Tym razem phpStorm podkreśla nam pipe
, uznając, że nie wie co to jest. Ma do tego prawo. Standardowo, wchodzimy w ustawienia… Languages & Frameworks -> JavaScript -> Libraries. Klikamy „Download” i z listy wybieramy „node” (bez żadnych dodatków). Klikamy „Download and Install”. Ściągnie się, zainstaluje. Na liście pojawi się jako @types/node, polecam ustawić jako Global. I już się pipe
nie podkreśla. Teraz dalej, z kodu źródłowego wnioskujemy, że powinniśmy stworzyć katalog source
a do tego podkatalogi, pliki… Ja to zrobiłem tak, jak na obrazku z prawej strony. Zauważamy trzy nowe pliki. Ich zawartość wygląda tak:
1 2 3 4 5 6 |
html { box-sizing: border-box; } *, *:before, *:after { box-sizing: inherit; } |
Co prawda większość przeglądarek już ustawia odpowiednio box-sizing, ale nie wszystkie, więc warto od tego zacząć. Nie potrzebujemy tutaj pre-procesora, używamy standardowego i krótkiego kodu CSS wymyślonego przez Pana Chrisa Coyiera.
1 2 |
$page_background: hsl(0, 0%, 100%); $page_text: hsl(0, 0%, 20%); |
Tak, wiem, że tego w tym projekcie nie potrzebujemy. Ale nie chodzi o to, czy to jest przydatne, ale jak działa.
1 2 3 4 5 6 |
@import "./../variables.scss"; body { background: $page_background; color: $page_text; } |
Czasami słyszę pytania, czym się różnią plik .sass od .scss. Powiedzmy sobie tak, jeżeli nie chcesz definiować bloków wcięciami (a nie chcesz!) to użyj .scss zamiast .sass. Jest… bardziej nowocześnie.
Uważny czytelnik zauważy, że odwołujemy się też do katalogu wordpress/wp-content/plugins/hello-world/assets/css
a wcale go nie mamy. Prawda. Ale jak sobie uruchomimy gulpfile.js, to nam się stworzy. To nasze miejsce docelowe. To jak, włączamy? Włączamy! Po chwili otrzymujemy rezultaty, które wyglądają tak:
Jak to działa?
W telegraficznym skrócie, w końcu rozmawiam z programistami. Definiujemy zadanie „styles”. W zadaniu tym określamy źródła, jako katalog z plikami css oraz katalog z plikami scss. Następnie pozwalamy gulpowi dodać prefiksy do kodu CSS, jeżeli są wymagane. Tutaj akurat nie były, ale kto wie co dopiszmy sobie jutro? Potem kod SASS jest interpretowany i przekształcany do zwykłego CSS, jednocześnie podlegając zmniejszeniu, kompresji. Następnie wszystkie te pliki łączymy w jeden, nazywając go hello-world.min.css
. Ostatni krok to poinformowanie gulpa gdzie ma zapisać plik wynikowy. No i oczywiście sygnalizujemy zakończenie zadania.
Możemy uruchomić zadanie „styles”, możemy uruchomić zadanie domyślne. Na razie zadanie domyślne uruchamia tylko zadanie „styles”, więc jest to równoznaczne. Ale do czasu, niedługo popracujemy nad innymi zadaniami dla default. I rozszerzymy nieco to zadanie, które już mamy.
Gulp i skrypty oraz uaktualnienie styles: przepisałem .pipe na .pump.