Jak łączyć i zmniejszać wiele plików CSS i JavaScript za pomocą Grunt.js (0.3.x)


99

Uwaga: to pytanie dotyczy tylko Grunt 0.3.x i zostało pozostawione w celach informacyjnych. Aby uzyskać pomoc dotyczącą najnowszej wersji Grunt 1.x, zobacz mój komentarz pod tym pytaniem.

Obecnie próbuję użyć Grunt.js do skonfigurowania automatycznego procesu kompilacji, aby najpierw połączyć, a następnie minifikować pliki CSS i JavaScript.

Udało mi się pomyślnie połączyć i zminimalizować moje pliki JavaScript, chociaż za każdym razem, gdy uruchamiam grunt, wydaje się, że po prostu dołącza do pliku, zamiast je nadpisywać.

Jeśli chodzi o minifikację, a nawet konkatenację CSS, na razie nie mogłem tego zrobić!

Grunt pod względem modułów CSS Próbowałem, używając consolidate-css, grunt-css& cssmin, ale bezskutecznie. Nie mogłem się dowiedzieć, jak ich używać!

Moja struktura katalogów jest następująca (jest to typowa aplikacja node.js):

  • app.js
  • grunt.js
  • /public/index.html
  • / public / css / [różne pliki css]
  • / public / js / [różne pliki javascript]

Oto jak obecnie wygląda mój plik grunt.js w folderze głównym mojej aplikacji:

module.exports = function(grunt) {

  // Project configuration.
  grunt.initConfig({
    pkg: '<json:package.json>',
    concat: {
      dist: {
        src: 'public/js/*.js',
        dest: 'public/js/concat.js'
      }
    },
    min: {
      dist: {
        src: 'public/js/concat.js',
        dest: 'public/js/concat.min.js'
      }
    },
    jshint: {
      options: {
        curly: true,
        eqeqeq: true,
        immed: true,
        latedef: true,
        newcap: true,
        noarg: true,
        sub: true,
        undef: true,
        boss: true,
        eqnull: true,
        node: true
      },
      globals: {
        exports: true,
        module: false
      }
    },
    uglify: {}
  });

  // Default task.
  grunt.registerTask('default', 'concat min');

};

Podsumowując, potrzebuję pomocy z dwoma pytaniami:

  1. /public/css/Powiedzmy, jak połączyć i zminimalizować wszystkie moje pliki css w folderze w jeden plikmain.min.css
  2. Dlaczego grunt.js zachować na dołączenie do łączone i minified plików javascript concat.jsi concat.min.jspod /public/js/zamiast nadpisywania ich za każdym razem, gdy polecenie gruntjest uruchamiane?

Zaktualizowano 5 lipca 2016 r. - Aktualizacja z Grunt 0.3.x do Grunt 0.4.x lub 1.x

Grunt.jsprzeniósł się do nowej struktury w Grunt 0.4.x(plik ma teraz nazwę Gruntfile.js). Proszę zobaczyć mój projekt Open Source Grunt.js Skeleton, aby uzyskać pomoc w konfiguracji procesu kompilacji dla Grunt 1.x.

Przejście z Grunt 0.4.xdo Grunt 1.x nie powinno wprowadzać wielu większych zmian .

Odpowiedzi:


107

concat.js jest dołączany do concat plików źródłowych zadania public/js/*.js. Możesz mieć zadanie, które usuwa concat.js(jeśli plik istnieje) przed ponownym połączeniem, przekazuje tablicę, aby jawnie określić, które pliki chcesz połączyć i ich kolejność, lub zmienić strukturę projektu.

Jeśli robisz to drugie, możesz umieścić wszystkie swoje źródła pod, ./srca zbudowane pliki pod./dest

src
├── css
│   ├── 1.css
│   ├── 2.css
│   └── 3.css
└── js
    ├── 1.js
    ├── 2.js
    └── 3.js

Następnie skonfiguruj konkat zadanie

concat: {
  js: {
    src: 'src/js/*.js',
    dest: 'dest/js/concat.js'
  },
  css: {
    src: 'src/css/*.css',
    dest: 'dest/css/concat.css'
  }
},

Twój min zadanie

min: {
  js: {
    src: 'dest/js/concat.js',
    dest: 'dest/js/concat.min.js'
  }
},

Nagromadzenie w min zadania wykorzystuje UglifyJS, więc trzeba wymienić. Znalazłem grunt-css jest całkiem niezły. Po zainstalowaniu załaduj go do swojego pliku gruntowego

grunt.loadNpmTasks('grunt-css');

A potem skonfiguruj

cssmin: {
  css:{
    src: 'dest/css/concat.css',
    dest: 'dest/css/concat.min.css'
  }
}

Zwróć uwagę, że użycie jest podobne do wbudowanego min.

Zmień swoje defaultzadanie na

grunt.registerTask('default', 'concat min cssmin');

Teraz bieganie gruntprzyniesie oczekiwane rezultaty.

dest
├── css
│   ├── concat.css
│   └── concat.min.css
└── js
    ├── concat.js
    └── concat.min.js

1
Jesteś geniuszem! Nigdy nie przyszło mi do głowy, że oczywiście gdybym umieścił concatw tym samym jsfolderze, zgarnąłby go i dołączył! Zacząłem używać cssmin i działa świetnie! Dzięki jeszcze raz.
— Jasdeep Khalsa

1
Świetnie, naprawdę świetnie! Ale nazwy plików to zawsze concat.min.cssi concat.min.js. Jeśli coś zmodyfikuję, uruchomię ponownie i wdrożę, ludzie nie otrzymają najnowszej wersji, ponieważ przeglądarka już ją zapisała w pamięci podręcznej. Czy istnieje sposób, aby losowo nazwać plik i połączyć je zgodnie z właściwymi tagami <link>i <script>?
— Tárcio Zemel

3
@ TárcioZemel Możesz dołączyć wersję package.json do nazwy pliku:concat.min-<%= pkg.version %>.js
— Rui Nunes

1
Możesz użyć w .destten sposób cssmin: { css:{ src: '<%= concat.css.dest %>', dest: './css/all.min.css'}} `To wynik operacjiconcat -> css
— Ivan Black

12

Chcę tutaj wspomnieć o bardzo, BARDZO, interesującej technice, która jest używana w dużych projektach, takich jak jQuery i Modernizr, do łączenia rzeczy.

Oba te projekty są w całości opracowane z modułami requirejs (widać to w ich repozytoriach na githubie), a następnie używają optymalizatora requirejs jako bardzo inteligentnego konkatenatora. Ciekawostką jest to, że jak widać, ani jQuery, ani Modernizr nie potrzebuje do działania requirejs, a dzieje się tak, ponieważ wymazują rytuał syntatyczny requirejs, aby pozbyć się requirejs w swoim kodzie. W rezultacie otrzymali samodzielną bibliotekę, która została opracowana z modułami requirejs! Dzięki temu są w stanie między innymi wykonywać skromne kompilacje swoich bibliotek.

Dla wszystkich zainteresowanych konkatenacją z optymalizatorem requirejs, sprawdź ten post

Jest też małe narzędzie, które wyabstrahuje wszystkie schematy tego procesu: AlbanilJS


Jest to bardzo interesujące, ale nie dotyczy pytania, ponieważ RequireJS to moduł ładujący, nie łączy ani nie
— minimalizuje

Dzięki! Masz rację, RequireJS to program ładujący moduły, który nie łączy się ani nie minifikuje. Ale r.js (optymalizator RequireJS -> requirejs.org/docs/optimization.html ) to robi. Dokładniej, łączy moduły, porządkując je według zależności. Faceci z Modernizr i jQuery wykorzystali algorytm porządkowania narzędzia i używają go specjalnie jako inteligentnego konkatenatora. Możesz sprawdzić ich repozytoria, aby zobaczyć, co robią.
— Augusto Altman Quaranta,

Używając concat lub uglify grunta, plik wynikowy jest tworzony przy użyciu kolejności z określonych skonfigurowanych plików źródłowych. Podczas gdy RequireJS jest oparta na zależności. Inne podejście może jednak przynieść ten sam rezultat.
— priyabagus

10

Zgadzam się z powyższą odpowiedzią. Ale oto inny sposób kompresji CSS.

Możesz połączyć swoje CSS za pomocą kompresora YUI :

module.exports = function(grunt) {
  var exec = require('child_process').exec;
   grunt.registerTask('cssmin', function() {
    var cmd = 'java -jar -Xss2048k '
      + __dirname + '/../yuicompressor-2.4.7.jar --type css '
      + grunt.template.process('/css/style.css') + ' -o '
      + grunt.template.process('/css/style.min.css')
    exec(cmd, function(err, stdout, stderr) {
      if(err) throw err;
    });
  });
}; 

W przypadku, gdy używasz 'grunt-css', musisz mieć moduł Locale Npm, więc upewnij się, że podczas instalacji 'grunt-css' musi znajdować się w module Locale Npm.
— Anshul

7
Dlaczego miałbyś chcieć robić całą tę złożoność i wywoływać jvm w procesie budowania? Po prostu spowalnia to wszystko bez powodu.
— michael łosoś

3

Nie musisz dodawać pakietu concat, możesz to zrobić za pomocą cssmin w następujący sposób:

cssmin : {
      options: {
            keepSpecialComments: 0
      },
      minify : {
            expand : true,
            cwd : '/library/css',
            src : ['*.css', '!*.min.css'],
            dest : '/library/css',
            ext : '.min.css'
      },
      combine : {
        files: {
            '/library/css/app.combined.min.css': ['/library/css/main.min.css', '/library/css/font-awesome.min.css']
        }
      }
    }

A dla js użyj uglify w ten sposób:

uglify: {
      my_target: {
        files: {
            '/library/js/app.combined.min.js' : ['/app.js', '/controllers/*.js']
        }
      }
    }

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.