Миграция на Grunt v0.4

от автора

Предисловие

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/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *