Як об'єднати та мінімізувати декілька файлів CSS та JavaScript за допомогою Grunt.js (0.3.x)


99

Примітка. Це запитання стосується лише Grunt 0.3.x і залишилось для ознайомлення. За допомогою останнього випуску Grunt 1.x дивіться мій коментар під цим питанням.

Зараз я намагаюся використовувати Grunt.js для налаштування автоматичного процесу збирання для спочатку об'єднання, а потім мінімізації файлів CSS та JavaScript.

Мені вдалося об'єднати та мінімізувати свої файли JavaScript, хоча кожен раз, коли я запускаю грунт, здається, що він просто додає файл, а не перезаписує їх.

Що стосується мінімізації або навіть об'єднання CSS, я поки що не міг цього зробити!

З точки зору рубаки модулів CSS Я спробував з допомогою consolidate-css, grunt-cssі , cssminале безрезультатно. Не вдалося розібратися, як ними користуватися!

Структура мого каталогу така (типова програма node.js):

  • app.js
  • grunt.js
  • /public/index.html
  • / public / css / [різні файли css]
  • / public / js / [різні файли javascript]

Ось як виглядає мій файл grunt.js в кореневій папці моєї програми:

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');

};

Отже, підсумовуючи, мені потрібна допомога з двома питаннями:

  1. Як об'єднати і мінімізувати всі мої файли css під папкою /public/css/в один файл, скажімоmain.min.css
  2. Чому grunt.js продовжує додавати до об'єднаних та мінімізованих файлів javascript concat.jsта concat.min.jsпід, /public/js/а не перезаписувати їх щоразу, коли команда gruntвиконується?

Оновлено 5 липня 2016 року - оновлення з Grunt 0.3.x до Grunt 0.4.x або 1.x

Grunt.jsперейшов до нової структури в Grunt 0.4.x(файл тепер називається Gruntfile.js). Перегляньте мій проект із відкритим кодом Grunt.js Skeleton для отримання довідки щодо налаштування процесу збирання Grunt 1.x.

Перехід від Grunt 0.4.xдо Grunt 1.x не повинен вносити багато великих змін .

Відповіді:


107

concat.js включається concatдо вихідних файлів завдання public/js/*.js. Ви можете мати завдання, яке видаляє concat.js(якщо файл існує) перед тим, як знову об'єднатися, передайте масив, щоб чітко визначити, які файли потрібно об'єднати та їх порядок, або змінити структуру вашого проекту.

Якщо ви робите останнє, ви можете помістити всі свої джерела під ./srcі вбудовані файли./dest

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

Потім поставте своє коротке завдання

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

Ваше мінімальне завдання

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

У завданні min для вбудовування використовується UglifyJS, тому вам потрібна заміна. Я знайшов grunt-css досить гарним. Після встановлення завантажте його у ваш грунт-файл

grunt.loadNpmTasks('grunt-css');

А потім налаштуйте його

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

Зауважте, що використання схоже на вбудований хв.

Змініть своє defaultзавдання на

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

Тепер біг gruntдасть потрібні результати.

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

1
Ви геній! Мені, звичайно, ніколи не спадало на думку, щоби я включив concatу ту саму jsпапку, що б її зірвати і додати! Я почав використовувати cssmin, і він чудово працює! Знову дякую.
Джасдіп Халса

1
Чудово, справді чудово! Але імена файлів завжди є concat.min.cssі concat.min.js. Якщо я щось модифікую, повторюю та розгортаю, люди не отримають найновішу версію, оскільки браузер її вже кешував. Є якийсь спосіб довільно назвати файл і зв’язати їх відповідно до відповідних <link>та <script>тегів?
Tárcio Zemel

3
@ TárcioZemel Ви можете включити версію package.json до імені файлу:concat.min-<%= pkg.version %>.js
Rui Nunes

1
Ви можете використовувати .destтак cssmin: { css:{ src: '<%= concat.css.dest %>', dest: './css/all.min.css'}} `Це результат операціїconcat -> css
Іван Чорний,

12

Я хочу згадати тут дуже, ДУЖЕ цікаву техніку, яка використовується у величезних проектах, таких як jQuery та Modernizr для об'єднання речей.

Обидва ці проекти повністю розроблені з модулями Requjs (ви можете бачити це в їхніх репортажах github), і тоді вони використовують оптимізатор Requjs як дуже розумний конкатенатор. Цікавим є те, що, як бачите, ні jQuery, ні Modernizr не потребують роботи вимагає, і це трапляється тому, що вони стирають синтатичний ритуал Requjs, щоб позбутися від Requjs у своєму коді. Таким чином, вони отримують окрему бібліотеку, розроблену з модулів Requjs! Завдяки цьому вони, серед інших переваг, здатні виконувати нарізки своїх бібліотек.

Для всіх, хто зацікавлений у поєднанні з оптимізатором Requjs, перегляньте цю публікацію

Також є невеличкий інструмент, який резюмує всі котлопластини процесу: AlbanilJS


Це дуже цікаво, але не стосується питання, оскільки RequireJS є модульним навантажувачем, він не об'єднує і не
применшує

Дякую! Ви маєте рацію, RequireJS - це завантажувач модулів, і він не об'єднує і не зменшує. Але r.js (оптимізатор RequireJS -> Requjs.org/docs/optimization.html ) робить це. Більш конкретно, він об'єднує ваші модулі, упорядковуючи їх залежностями. Хлопці з Modernizr та jQuery скористалися алгоритмом замовлення інструменту та спеціально використовували його як розумний конкатенатор. Ви можете перевірити їх репост, щоб побачити, що вони роблять.
Аугусто Альтман Каранта

Використовуючи конкрет або угліфікувати grunt, отриманий файл складається з використанням порядку із вказаних вихідних файлів, налаштованих. Тоді як RequireJS заснований на залежності. Однак різний підхід може досягти однакового результату.
priyabagus

10

Я згоден з наведеною вище відповіддю. Але ось ще один спосіб стиснення CSS.

Ви можете стиснути свій CSS, використовуючи компресор 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;
    });
  });
}; 

У випадку, якщо ви використовуєте 'grunt-css', вам знадобиться модуль Locale Npm, тому переконайтесь, що при установці 'grunt-css' у, повинен бути в модулі Locale Npm.
Аншул

7
Чому ви хочете виконати всю цю складність і викликати jvm у процесі збирання? Просто гальмує все це без причини.
лосось michael

3

Вам не потрібно додавати пакет concat, ви можете зробити це через cssmin, як це:

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']
        }
      }
    }

А для js використовуйте uglify так:

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.