MerixGames

16 października 2015

/ code & tools

Gulp.js – co to jest i z czym to się je?

Mateusz Anioła

W codziennej pracy Frontend Developera jest kilka narzędzi, bez których aktualnie nie wyobrażam sobie pracy – jednym z nich jest Gulp. W momencie, kiedy pierwszy raz poznałem jego możliwości wiedziałem, że jest to dokładnie to, czego szukałem.

Czym właściwie jest Gulp?

W ostatnich latach nastąpił wzrost stopnia skomplikowania aplikacji i stron internetowych, co spowodowało ogromny rozwój wszelkich narzędzi frontendowych. Tymczasem nadal jesteśmy ograniczeni do kodu HTML, CSS i JS, który jest w stanie zinterpretować przeglądarka. Aktualnie nie wystarczy ściągnąć jednego lub dwóch pluginów i dodać ich do kodu, aby wszystko sprawnie działało. Im większy projekt, tym szybciej zagubimy się w całym kodzie, który powstaje.

Jednocześnie chcemy, aby nasz kod był prosty, modułowy oraz łatwy do wdrożenia się i dalszego rozwijania w przyszłości. Dlatego zdecydowaliśmy się na konkretny zbiór narzędzi mających na celu ułatwienie i przyspieszenie pracy. W zbiorze tym znajduje się Gulp. Czym on jest i do czego służy?

Gulp.js to, oparty o platformę Node.js, system do automatyzacji pracy. Głównym jego zadaniem jest więc zautomatyzowanie wielu czynności, jakie musi wykonać programista podczas swojej pracy.

Jak działa Gulp?

Gulp składa projekt w całość na podstawie wcześniej zdefiniowanych zadań oraz plików kodu podzielonych na dowolnie małe części.

Kilka zadań, które Gulp najczęściej wykonuje w naszym projekcie to:

  • uruchamia deweloperski serwer do podglądu projektu,
  • odświeża nasze okno przeglądarki za każdym razem kiedy dokonamy zmian w edytorze (na wszystkich urządzeniach, które aktualnie daną stronę wyświetlają),
  • ułatwia korzystanie z takich narzędzi jak Sass, Swig i Browserify,
  • minifikuje i łączy pliki style oraz skrypty.

Instalacja Gulpa - krok po kroku

Całe działanie Gulpa jest możliwe dzięki Node.js – tak więc trzeba go mieć zainstalowanego na komputerze. Dodatkowym atutem jest fakt, że wszystkie nasze zadania piszemy w JavaScript. Razem z Node.js dostajemy npm – node package manager, który będzie dla nas instalował wszystkie potrzebne nam paczki. Z Gulpa korzystamy za pomocą konsoli i aby go zainstalować wpisujemy komendę

npm install gulp -g

Flaga -g oznacza, że dokonamy instalacji globalnie.

Nastepnie możemy zainstalować Gulpa per projekt, aby to zrobić wpisujemy komendę z folderu projektu

npm init

Utworzy ona dla nas plik package.json, gdzie przechowywane są różne dane o naszym projekcie – między innymi, z jakich paczek instalowanych poprzez npm będziemy korzystać.

Samego Gulpa lokalnie instalujemy komendą

npm install gulp --save-dev

dzięki czemu Gulp zostanie dodany do „devDependencies” w pliku package.json.

Za każdym razem kiedy nowa osoba dołączy do projektu wystarczy, że w folderze, w którym znajduje się package.json wpisze komendę

npm install

i zainstaluje u siebie od razu wszystkie niezbędne dla danego projektu moduły.

Wszystkie nasze taski definiujemy w pliku gulpfile.js. Najprostszy task wyglądałby w ten sposób:

var gulp = require('gulp');

    gulp.task('default', function() {

    console.log('Hello!');

});

Pod zmienną gulp ładujemy wcześniej zainstalowaną paczkę za pomocą npm (składnia jest dokładnie taka sama jak require w Node.js) oraz pod zadanie default podpinamy funkcje, która wykona zwykły console.log. Teraz wywołując komendę

gulp

wewnątrz folderu, w którym znajduje się nasz plik gulpfile.js dostaniemy taki wynik w konsoli

λ gulp

[16:58:03] Using gulpfile D:\test\gulpfile.js

[16:58:03] Starting 'default'...

Hello!

[16:58:03] Finished 'default' after 357 μs

Zadanie o nazwie default jest domyślnie podpinany pod komendę gulp, natomiast każdy o innej nazwie wywołujemy podając tę nazwę za komendą gulp.

Przydatne funkcje Gulpa

Gulp.js sam w sobie jest bardzo prosty i opiera się na 4 funkcjach. Po odczytaniu naszych danych przepuszcza je przez zainstalowane wtyczki oraz zapisuje je w wybranym przez nas miejscu.

Główne funkcje Gulpa:

  • gulp.task – służy do definiowana naszych zadań, a jako parametry przyjmuje: nazwę zadania, tablice z zadaniami do wykonania oraz samą funkcję, gdzie zdefiniowany jest nasz kod; tablica jest opcjonalna, a jeśli jest podana jako argument, to funkcja jest wykonywana po zrealizowaniu zadań z tej tablicy
  • gulp.src – wskazuje na pliki z których korzystamy i pozwala na ich modyfikację przez pluginy wykorzystując funkcję .pipe()
  • gulp.dest – wskazuje miejsce, w którym chcemy zapisać nasze pliki wynikowe,
  • gulp.watch – służy do nasłuchiwania zmian w plikach i automatycznie uruchamia odpowiednie zadania; jako parametry przyjmuje: ścieżkę do obserwowanych plików, tablicę zadań oraz opcjonalnie funkcję wykonywaną po wystąpieniu zmian.

Gulp w praktyce

Dla podsumowania i zaprezentowania wszystkich możliwości napiszemy teraz prosty task, który automatycznie doda do naszych reguł CSS odpowiednie prefixy. Użyjemy do tego gulp-autoprefixer, który instalujemy za pomocą znanej już nam komendy

npm install gulp-autoprefixer --save-dev

W naszym pliku gulpfile.js piszemy:

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

gulp.task('default', ['styles'], function () {
	gulp.watch('styles/main.css', ['styles']);
});

gulp.task('styles', function () {
	gulp.src('styles/main.css')
	.pipe(autoprefixer())
	.pipe(gulp.dest('build'));
});

Po wykonaniu komendy gulp nasze pliki wynikowe znajda się w folderze build, dodatkowo Gulp będzie cały czas reagować na zmiany w pliku main.css i za każdym razem kiedy taką zmianę wykryje automatycznie wykona ponownie zadanie styles. Listę pluginów można znaleźć na oficjalnej stronie Gulpa.

Gulp vs. Grunt

Istnieje oczywiście więcej narzędzi do automatyzacji pracy (task runners): webpack, brunch, broccoli oraz największy z nich – Grunt. Czym tak naprawdę rózni się Gulp od Grunta?

Pierwszą różnicą, jaka od razu rzuca się w oczy jest sposób definiowana tasków. Zadania dla Grunt ustalamy poprzez konfigurację obiektu, który jest przekazywany do funkcji grunt.initConfig. W odróżnieniu od pisania funkcji zgodnych ze składnią Node.js, może być to trochę bardziej uciążliwe, lecz jest to także w dużej mierze kwestia własnych preferencji. Gruntfile (odpowiednik gulpfile) może bardzo szybko stać się bardzo długi i mało czytelny. Przykładowy plik konfiguracyjny do Grunta zaczęrpnięty z oficjalnej strony wygląda następująco:

module.exports = function(grunt) {

 

  grunt.initConfig({

    pkg: grunt.file.readJSON('package.json'),

    concat: {

      options: {

        separator: ';'

      },

      dist: {

        src: ['src/**/*.js'],

        dest: 'dist/<%= pkg.name %>.js'

      }

    },

    uglify: {

      options: {

        banner: '/*! <%= pkg.name %> <%= grunt.template.today("dd-mm-yyyy") %> */\n'

      },

      dist: {

        files: {

          'dist/<%= pkg.name %>.min.js': ['<%= concat.dist.dest %>']

        }

      }

    },

    qunit: {

      files: ['test/**/*.html']

    },

    jshint: {

      files: ['Gruntfile.js', 'src/**/*.js', 'test/**/*.js'],

      options: {

        // options here to override JSHint defaults

        globals: {

          jQuery: true,

          console: true,

          module: true,

          document: true

        }

      }

    },

    watch: {

      files: ['<%= jshint.files %>'],

      tasks: ['jshint', 'qunit']

    }

  });

 

  grunt.loadNpmTasks('grunt-contrib-uglify');

  grunt.loadNpmTasks('grunt-contrib-jshint');

  grunt.loadNpmTasks('grunt-contrib-qunit');

  grunt.loadNpmTasks('grunt-contrib-watch');

  grunt.loadNpmTasks('grunt-contrib-concat');

 

  grunt.registerTask('test', ['jshint', 'qunit']);

 

  grunt.registerTask('default', ['jshint', 'qunit', 'concat', 'uglify']);

 

};

Kolejną różnicą wartą wspomnienia jest prędkość wykonywania zadań. W tym przypadku Gulp wypada dużo lepiej, ponieważ wszystkie operacje są wykonywane w pamięci, a pliki wynikowe są zapisywane na dysk tylko raz. Grunt natomiast operuje na plikach tymczasowych, co zwiększa ilość zapisywania i odczytywania plików z dysku. Tak naprawdę nie ma to większego znaczenia przy małych projektach, różnice w czasie oscylują na poziomie kilkuset ms.

Przy podejmowaniu decyzji dotyczącej wyboru narzędzia, istotne jest również środowisko developerów rozwijających istniejące oraz piszących nowe wtyczki. Grunt istnieje dłużej niż Gulp, dlatego ma ich z pewnością więcej – oficjalna lista pokazuje 5236 wtyczek, natomiast Gulp ma ich 1879. Jeżeli liczba wtyczek jest dla nas istotnym czynnikiem, to należy mieć na uwadze, że Gulp ma wtyczkę pozwalająca korzystać z wtyczek Grunta, i na odwrót również. Google Trends pokazuje wizualizacje zainteresowania konkretnymi narzędziami. W momencie pisania tego artykułu Gulp minimalnie wyprzedza Grunta.

Podsumowując – wybór między wspomnianymi narzędziami zależy tak naprawdę od własnych preferencji. Jeżeli już korzystacie z któregoś z nich i dobrze się sprawdza przy waszych projektach, to chyba nie ma większego powodu, który przekonałby was do zmiany. Natomiast jeżeli taki wybór jest nadal przed wami, polecam Gulpa głównie dlatego, że zadania konfiguruje się łatwo i szybko, a zaoszczędzony czas poświecić można na pisanie właściwego kodu projektu.

Myślisz o realizacji projektu?

Skontaktuj się z nami. Przygotujemy wycenę, opowiemy o szczegółach i procesie wdrożenia.

Napisz do nas

Strona używa plików cookies. Wyrażasz zgodę na używanie cookies, zgodnie z aktualnymi ustawieniami przeglądarki.