search check home clock-o tag tags chevron-left chevron-right chevron-up chevron-down twitter facebook github rss comment comments terminal code

[JS] Jak lepiej zorganizować swoją pracę z Grunt.js?

[JS] Jak lepiej zorganizować swoją pracę z Grunt.js?

Grunt.js jest wspaniałym narzędziem, dzięki któremu możemy usprawnić naszą codzienną pracę przy tworzeniu kodu stron WWW czy też aplikacji internetowych. Praca z Grunt.js w głównej mierze polega na odpowiednim konfigurowaniu dostępnych modułów. W miarę upływu czasu, plik konfiguracyjny - Gruntfile.js, może urosnąć znacząco przez co zarządzanie modułami będzie utrudnione. Czy da się to usprawnić? Jasne, że tak.

Dotychczasowa praca z Grunt.js

Być może pamiętasz wpis, który napisałem jakiś czas temu odnośnie tego w jaki sposób Grunt.js wpływa na polepszenie pracy webdevelopera, dlatego nie będę się powtarzał. Skupię się natomiast na tym jak można usprawnić pracę z jego plikiem konfiguracyjnym. W tamtym artykule możesz znaleźć przykład pliku konfiguracyjnego, który z biegiem czasu może się rozrosnąć i utrudnić pracę podczas kodowania.

Przygotowanie narzędzi do usprawnienia

Aby rozpocząć usprawnianie zarządzaniem kodu Gruntfile.js musimy zainstalować 2 dodatkowe rozszerzenia do Grunt.js - load-grunt-config oraz load-grunt-tasks. Zrobimy to za pomocą następujących komend:

Instalacja load-grunt-config

npm install load-grunt-config --save-dev

Instalacja load-grunt-tasks

npm install load-grunt-tasks --save-dev

Przenoszenie konfiguracji do osobnych plików

Następnie, konfigurację rozszerzeń w pliku Gruntfile.js musimy przepisać do osobnych plików w folderze grunt - który jest domyślnym folderem, gdzie rozszerzenie load-grunt-config szuka plików konfiguracyjnych (można to zmienić w razie potrzeby).

Dotychczas w pliku Gruntfile.js można było znaleźć taki zapis:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Gruntfile.js
grunt.initConfig({
  uglify  : {
    build : {
      src     : ['**/*.js', '!*.min.js'],
      cwd     : 'dev/js/',
      dest    : 'dev/js/min/',
      expand  : true,
      rename  : function (dest, src) {
        var folder    = src.substring(0, src.lastIndexOf('/'));
        var filename  = src.substring(src.lastIndexOf('/'), src.length);
 
        filename  = filename.substring(0, filename.lastIndexOf('.'));
 
        return dest + folder + filename + '.min.js';
      }
    }
  }
});

Konfigurację rozszerzenia uglify przenosimy do folderu grunt:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// grunt/uglify.js
module.exports = {
  build : {
    src     : ['**/*.js', '!*.min.js'],
    cwd     : 'dev/js/',
    dest    : 'dev/js/min/',
    expand  : true,
    rename  : function (dest, src) {
      var folder    = src.substring(0, src.lastIndexOf('/'));
      var filename  = src.substring(src.lastIndexOf('/'), src.length);
 
      filename  = filename.substring(0, filename.lastIndexOf('.'));
 
      return dest + folder + filename + '.min.js';
    }
  }
};

Następnie z pliku Gruntfile.js usuwamy całą dotychczasową konfigurację i kod odpowiadający za ładowanie zadań (tasków) rozszerzeń i zastępujemy to następującym kodem:

1
2
3
4
5
6
7
// Gruntfile.js
module.exports = function(grunt) {
  require('load-grunt-config')(grunt);
  require('load-grunt-tasks')(grunt);
 
  grunt.registerTask('default', ['uglify']);
};

Voila! Plik Gruntfile.js jest teraz czysty i można łatwiej definiować nowe zadania (taski) wg własnego upodobania. Cała konfiguracja wymaganych rozszerzeń znajduje się teraz w osobnych plikach - dla każdego rozszerzenia osobno, w folderze grunt.

Podsumowanie

Jak widać, można znacząco sobie ułatwić proces zarządzania konfiguracjami rozszerzeń poprzez przeniesienie ich z pliku Gruntfile.js do osobnych plików odpowiedzialnych za dane rozszerzenie. Należy jednak pamiętać o tym, aby nazwa pliku posiadała nazwę zadania danego rozszerzenia, tzn. plik z konfiguracją dla rozszerzenia grunt-contrib-uglify będzie nazywał się uglify.js, ponieważ uglify jest nazwą zadania (taska) tego rozszerzenia.

  • Nie wyobrażam sobie zabawy z Gruntem bez load-grunt-config. Ominąłeś jednak trzy jego ważne aspekty:
    1) wewnętrznie używa load-grunt-tasks, więc nie ma potrzeby załączać go osobno
    2) ma genialny system aliasów: https://github.com/firstandthird/load-grunt-config#aliases (wywal tę super brzydką linijkę grunt.registerTask :P)
    3) obsługuje JS, YAML oraz CS – czyli de facto Grunt właśnie stał się uniwersalnym build toolem dla każdego 😉

    Do load-grunt-config dorzucam sobie jeszcze time-grunt, żeby wiedzieć ile mi mój build zżera czasu i co można by w nim zoptymalizować (tak, jestem zdolny optymalizować build tool ;))