Предисловие
18 февраля вышел релиз Grunt v0.4.0, с чем всех и поздравляю. Если вы еще не знакомы с Грантом — прошу пройти на официальный сайт или почитать ознакомительную статью на Хабре. Вкратце, Грант позволяет автоматизировать склеивание и минификацию js-файлов, запуск тестов, проверку кода с помощью JSHint и многое другое.
Данная статья — история миграции одного приложения с Гранта v0.3.9 на вышедшую v0.4.0. Версии несовместимы и переезд оказался не таким простым делом, как я изначально предполагал. Полная инструкция по миграции на английском находится здесь, она подробнее чем мое описание.
Зачем я использую Grunt
Как любому ленивому frontend-разработчику, мне нужен был инструмент, который автоматизирует рутинные задачи, позволяя сосредоточиться непосредственно на разработке. Так я нашел Грант, который делал за меня следующее:
- компиляция stylus в css;
- склеивание js-файлов;
- проверка JavaScript линтером;
- минификация склеенных js-файлов;
- запуск unit-тестов (qUnit);
- отслеживание изменений исходных файлов и автоматический перезапуск вышеперечисленных задач.
Все эти важные, но скучные задачи выполнялись одной командой:
→ grunt Running "stylus:compile" (stylus) task File 'css/styles.css' created. Running "concat:js" (concat) task File "project.js" created. Running "lint:files" (lint) task Lint free. Running "min:js" (min) task File "project.min.js" created. Uncompressed size: 130468 bytes. Compressed size: 20937 bytes gzipped (74246 bytes minified). Running "qunit:all" (qunit) task Testing index.html...............OK >> 95 assertions passed (594ms) Running "watch" task Waiting...
Все задачи описываются в специальном грант-файле: grunt.js. Для вышеприведенного лога он схематично выглядит так:
module.exports = function(grunt) { grunt.initConfig({ stylus: { // Компиляция Stylus в CSS compile: { options: { 'compress': true, 'paths': ['css/styl/'] }, files: { 'css/styles.css': 'css/styles.styl' } } }, concat: { // Склеивание js-файлов js: { src: [ /* Здесь большой список файлов */ ], dest: 'project.js' } }, min: { // Минификация js: { src: ['<config:concat.js.dest>'], dest: 'project.min.js' } }, jshint: { options: { smarttabs: true } }, lint: { // Проверка кода files: ['<config:concat.js.dest>'] }, watch: { // Перекомпиляция стилей при изменении styl-файлов stylus: { files: ['css/styl/*.styl'], tasks: 'stylus' }, // Пересобирание скриптов и запуск lint при изменении исходных js-файлов js: { files: ['src/*.js'], tasks: 'concat lint' } }, qunit: { // Запуск написанных qUnit-тестов all: ['../test/index.html'] } }); // Загрузка модуля для компиляции Стилуса grunt.loadNpmTasks('grunt-stylus'); // Объявление тасков grunt.registerTask('default', 'stylus concat:js lint min:js qunit watch'); grunt.registerTask('test', 'qunit'); };
Не буду подробно его разбирать, комментариев в коде должно быть достаточно.
Миграция
Переустановка модуля
Ранее установленный глобально модуль grunt (если таковой имеется) удаляем: npm uninstall -g grunt
И устанавливаем модуль интерфейса командной строки Гранта: npm install -g grunt-cli
Сам grunt теперь ставится локально в папку проекта: npm install grunt
Проверяем версии модулей:
→ grunt --version grunt-cli v0.1.6 grunt v0.4.0
Глобально разрешено поставить модуль grunt-init, но в моем приложении он не используется.
Перед установкой убедитесь, что версия node.js >= 0.8.0.
Переименование грант-файла
mv grunt.js Gruntfile.js
Грант-файл со старым именем больше не поддерживается, без переименования увидим ошибку:
Fatal error: Unable to find Gruntfile.
В новое версии грант-файл можно писать на CoffeeScript: Gruntfile.coffee.
Установка плагинов
У обновленного Гранта больше нет встроенных задач, таких как concat, min, watch и др. Их необходимо добавлять в виде отдельных плагинов:
- concat → grunt-contrib-concat
- lint → grunt-contrib-jshint
- min → grunt-contrib-uglify
- qunit → grunt-contrib-qunit
- watch → grunt-contrib-watch
Несложно заметить, что плагины Гранта имеют префикс grunt-contrib-.
Устанавливаем:
→ npm install grunt-contrib-concat → npm install grunt-contrib-jshint → npm install grunt-contrib-uglify → npm install grunt-contrib-qunit → npm install grunt-contrib-watch → npm install grunt-contrib-stylus
При установке рекомендуется использовать параметр --save-dev
, чтобы автоматически обновлялись зависимости devDependencies в package.json.
Подключаем плагины в грант-файле:
grunt.loadNpmTasks('grunt-contrib-concat'); grunt.loadNpmTasks('grunt-contrib-jshint'); grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.loadNpmTasks('grunt-contrib-qunit'); grunt.loadNpmTasks('grunt-contrib-watch'); grunt.loadNpmTasks('grunt-contrib-stylus');
Изменения в грант-файле
Методу registerTask теперь нельзя передать список задач одной строкой с пробелами-разделителями. Строкой разрешено передать только одну задачу: grunt.registerTask('test', 'qunit');
Для списка задач обязательно используем массив:
grunt.registerTask('default', ['stylus', 'concat:js', 'jshint', 'min:js', 'qunit', 'watch']);
Вместо деректив вида <config:concat.js.dest>
теперь используем шаблоны: <%= concat.js.dest %>
.
Задача lint с опциями jshint теперь объединена в задачу jshint, где сразу можно указать опции:
jshint: { options: { smarttabs: true }, js: ['project.js'] }
Задачу min переименовываем в uglify. Вместо объектов src/dest используем объект files:
uglify: { js: { files: { 'project.min.js': ['<%= concat.js.dest %>'] } } }
В задаче watch перечисляем выполняемые таски в виде массива:
watch: { js: { files: ['src/*.js'], tasks: ['concat', 'lint'] } }
На этом мой переезд был завершен, и Грант отработал без ошибок. Все изменения грант-файла собраны в этом шаблоне:
module.exports = function(grunt) { grunt.initConfig({ // Компиляция Stylus в CSS stylus: { compile: { options: { 'compress': true, 'paths': ['css/styl/'] }, files: { 'css/styles.css': 'css/styles.styl' } } }, concat: { // Склеивание js-файлов js: { src: [ /* Здесь большой список файлов */ ], dest: 'project.js' } }, uglify: { // Минификация js: { files: { 'project.min.js': ['<%= concat.js.dest %>'] } } }, jshint: { // Проверка кода options: { smarttabs: true }, js: ['<%= concat.js.dest %>'] }, watch: { // Перекомпиляция стилей при изменении styl-файлов stylus: { files: ['css/styl/*.styl'], tasks: 'stylus' }, // Пересобирание скриптов и запуск lint при изменении исходных js-файлов js: { files: ['src/*.js'], tasks: ['concat', 'lint'] } }, qunit: { // Запуск написанных qUnit-тестов all: ['../test/index.html'] } }); grunt.loadNpmTasks('grunt-contrib-concat'); grunt.loadNpmTasks('grunt-contrib-jshint'); grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.loadNpmTasks('grunt-contrib-qunit'); grunt.loadNpmTasks('grunt-contrib-watch'); grunt.loadNpmTasks('grunt-contrib-stylus'); // Объявление тасков grunt.registerTask('default', ['stylus', 'concat:js', 'jshint', 'uglify:js', 'qunit', 'watch']); grunt.registerTask('test', 'qunit'); };
Материалы по теме
ссылка на оригинал статьи http://habrahabr.ru/post/170937/
Добавить комментарий