Grunt — это фантастическая система сборки для веб-разработки, но ее сложно настроить. В этом руководстве вы научитесь настраивать Grunt для создания современного веб-проекта. Когда вы закончите, ваш Gruntfile сможет:
- Копировать файлы из исходного каталога в каталог сборки
- Удалить файлы сборки
- Скомпилируйте файлы Stylus и добавьте к ним префиксы поставщиков.
- Компилировать CoffeeScript
- Сократить CSS и JavaScript
- Компиляция Jade
- Автоматически создавать исходные файлы при их изменении
- Запустите сервер разработки
Начиная
Если вы еще этого не сделали, установите Node.js и NPM . Вам также необходимо установить интерфейс командной строки Grunt, выполнив команду npm install -g grunt-cli
. Это позволяет вам запускать команду grunt
из любой точки вашей системы.
Создайте package.json
с содержимым ниже.
json { "name": "grunt_tutorial", "description": "An example of how to set up Grunt for web development.", "author": , "dependencies": { "grunt": "0.xx", "grunt-autoprefixer": "0.2.x", "grunt-contrib-clean": "0.5.x", "grunt-contrib-coffee": "0.7.x", "grunt-contrib-connect": "0.4.x", "grunt-contrib-copy": "0.4.x", "grunt-contrib-cssmin": "0.6.x", "grunt-contrib-jade": "0.8.x", "grunt-contrib-jshint": "0.6.x", "grunt-contrib-stylus": "0.8.x", "grunt-contrib-uglify": "0.2.x", "grunt-contrib-watch": "0.5.x" }, "engine": "node >= 0.10" }
Этот файл определяет ваш проект как пакет NPM и объявляет зависимости вашего проекта. У каждой зависимости есть номер версии. Например, grunt-contrib-copy: "0.4.x"
указывает NPM установить последнюю версию 0.4 пакета grunt-contrib-copy
. Запустите в консоли npm install
чтобы установить зависимости.
копия
Хороший скрипт сборки всегда хранит исходный код отдельно от файлов сборки. Это разделение позволяет вам уничтожить сборку, не затрагивая ваш источник, и предотвращает случайное редактирование сборки.
Для начала вы заставите Grunt скопировать файлы из source
каталога в каталог build
. Создайте файл Gruntfile.js
и вставьте в него следующее:
javascript module.exports = function(grunt) { // configure the tasks grunt.initConfig({ copy: { build: { cwd: 'source', src: [ '**' ], dest: 'build', expand: true }, }, }); // load the tasks grunt.loadNpmTasks('grunt-contrib-copy'); // define the tasks };
Давайте разберемся с этим. В Node, когда вам require
модуль, вызывается функция modules.exports
и возвращается результат. Установив modules.exports
`в Gruntfile, вы говорите Node возвращать функцию, которая определяет конфигурацию Grunt. grunt.initConfig
— это метод, который принимает один аргумент: объект, свойства которого настраивают отдельные задачи Grunt.
Внутри конфигурации Grunt вы добавили конфигурацию для задачи copy
. Эта задача имеет одну подзадачу, которая называется build
. В Grunt некоторые задачи, называемые многозадачными , могут иметь несколько подзадач, которые можно вызывать отдельно. Для copy
вам не нужна эта функция, но все равно необходимо иметь хотя бы одну подзадачу.
Внутри подзадачи build
находится формат массива файлов Grunt. Этот формат является одним из способов, которыми Grunt позволяет вам предоставлять исходные файлы для задачи. cwd
указывает на каталог с исходными файлами, а src указывает исходные файлы. '**'
— это шаблон, который указывает Grunt на совпадение с любым файлом. dest
— это то, где Grunt будет выводить результат задачи. Вы установили его на "build"
чтобы сказать grunt скопировать содержимое в каталог сборки. Если есть файл source/index.html
, эта конфигурация выведет build/index.html
. Наконец, вы устанавливаете параметр expand
на true
чтобы включить все эти параметры.
grunt.loadNpmTasks("grunt-contrib-copy");
говорит Grunt загрузить задачи из пакета grunt-contrib-copy
. Это дает нам команду copy
, которую вы можете запустить, набрав grunt copy
в вашей консоли.
чистый
Теперь, когда у вас есть каталог для build
, пришло время написать задачу, которая его очистит. После настройки копирования добавьте следующее:
javascript clean: { build: { src: [ 'build' ] }, },
Как и у copy
, у вас есть clean
цель с конфигурацией задачи. src
clean
конфигурации имеет значение "build"
для удаления каталога build
.
После grunt.loadNpmTasks("grunt-contrib-copy");
, загрузите задачу clean
, которая позволит вам запустить grunt clean
из консоли.
javascript grunt.loadNpmTasks('grunt-contrib-clean');
Сложение
Разве не было бы замечательно, если бы у вас была задача build
, которая удаляла бы старую сборку перед копированием новых исходных файлов? Давайте добавим один!
javascript // define the tasks grunt.registerTask( 'build', 'Compiles all of the assets and copies the files to the build directory.', [ 'clean', 'copy' ] );
Метод registerTask
создает новую задачу. Первый аргумент, "build"
, определяет имя задачи. Второе — это описание задачи. Последний представляет собой массив задач, которые будут выполняться. Задача build
запускает задачу clean
за которой следует задача copy
.
стилус
Стилус — это отличный язык, который компилируется в CSS. Он улучшает CSS несколькими способами, включая добавление переменных, вложенности и функций.
javascript stylus: { build: { options: { linenos: true, compress: false }, files: [{ expand: true, cwd: 'source', src: [ '**/*.styl' ], dest: 'build', ext: '.css' }] } },
Это немного отличается от других конфигураций задач. Подзадача build
все еще существует, но теперь у нее есть два свойства: options
и files
. options
указывает, как мы хотим, чтобы задача велась. Мы добавили две опции: compress
определяет, должен ли сжатый вывод CSS, и linenos
добавляет номера строк селекторов в исходных файлах linenos
.
files
используется тот же формат отображения массивов файлов, что и раньше. Это запустит задачу для всех файлов в source
каталоге, которые заканчиваются на .styl
. ext
изменяет расширение выходных файлов на .css
.
Теперь, когда задача stylus
выводит файлы CSS в каталог build
, больше нет причин копировать файлы stylus
в каталог build
. Давайте изменим конфигурацию copy
чтобы предотвратить это.
javascript copy: { build: { cwd: 'source', src: [ '**', '!**/*.styl' ], dest: 'build', expand: true }, },
!
в начале пути предотвращает включение файлов, соответствующих шаблону. Не забудьте добавить "stylus"
в задачу build
.
javascript grunt.registerTask( 'build', 'Compiles all of the assets and copies the files to the build directory.', [ 'clean', 'copy', 'stylus' ] );
Autoprefixer
Autoprefixer — это плагин, который добавляет префиксы вендора в свойства CSS3 после компиляции файлов стилуса в CSS. Это отличная замена для библиотек, таких как Nib и Compass .
Идите вперед и добавьте конфигурацию autoprefixer
.
javascript autoprefixer: { build: { expand: true, cwd: 'build', src: [ '**/*.css' ], dest: 'build' } },
Заметив шаблон? Эта конфигурация очень похожа на другие задачи. Одно заметное отличие — это cwd
и dest
которые установлены на "build"
. Это заставляет autoprefixer
выводить файлы в ту же папку, из которой он их читает, что заменяет исходные файлы.
Как и раньше, вам также нужно загрузить задачу Autoprefixer.
javascript grunt.loadNpmTasks('grunt-autoprefixer');
Вместо того, чтобы помещать все задачи CSS в build
, создайте новую задачу для таблиц стилей и добавьте эту задачу для сборки.
javascript // define the tasks grunt.registerTask( 'stylesheets', 'Compiles the stylesheets.', [ 'stylus', 'autoprefixer' ] ); grunt.registerTask( 'build', 'Compiles all of the assets and copies the files to the build directory.', [ 'clean', 'copy', 'stylesheets' ] );
Минификация CSS
Передача клиенту множества громоздких CSS-файлов может реально замедлить время загрузки сайта. К счастью, пакет grunt-contrib-cssmin
минимизирует CSS-файлы и объединяет их в один файл. Еще раз начнем с настройки.
javascript cssmin: { build: { files: { 'build/application.css': [ 'build/**/*.css' ] } } },
Вместо использования формата массива файлов эта конфигурация использует формат объектов файлов Grunt, который отображает несколько файлов в одно место назначения. Все CSS-файлы в каталоге build
будут минимизированы и выведены в build/application.css
.
Загрузите пакет и добавьте минимизацию CSS в задачу stylesheets
.
javascript grunt.loadNpmTasks('grunt-contrib-cssmin');
javascript grunt.registerTask( 'stylesheets', 'Compiles the stylesheets.', [ 'stylus', 'autoprefixer', 'cssmin' ] );
CoffeeScript
CoffeeScript — это фантастический язык, который компилируется в JavaScript. Он имеет чистый, красивый синтаксис, включает в себя классы и скрывает множество уродливых аспектов JavaScript.
Добавить CoffeeScript в проект легко! Сначала добавьте конфигурацию.
javascript coffee: { build: { expand: true, cwd: 'source', src: [ '**/*.coffee' ], dest: 'build', ext: '.js' } },
Это извлекает исходные файлы CoffeeScript, изменяет их расширения на .js
и выводит их в каталог build
. Затем загрузите пакет grunt-contrib-coffee
.
javascript grunt.loadNpmTasks('grunt-contrib-coffee');
Добавьте задачу scripts
и добавьте ее в задачу build
.
javascript grunt.registerTask( 'scripts', 'Compiles the JavaScript files.', [ 'coffee' ] ); grunt.registerTask( 'build', 'Compiles all of the assets and copies the files to the build directory.', [ 'clean', 'copy', 'stylesheets', 'scripts' ] );
Еще раз, вам нужно добавить исключение для copy
чтобы файлы CoffeeScript не копировались в каталог build
.
javascript copy: { build: { cwd: 'source', src: [ '**', '!**/*.styl', '!**/*.coffee' ], dest: 'build', expand: true }, },
Уродовать
Как и cssmin
, UglifyJS минимизирует файлы JavaScript и объединяет их в один файл. Вот конфигурация:
javascript uglify: { build: { options: { mangle: false }, files: { 'build/application.js': [ 'build/**/*.js' ] } } },
По умолчанию UglifyJS заменит имена переменных и функций в ваших скриптах на более короткие имена. Это удобно, если код вашего проекта автономен, но если он используется совместно с другим проектом, это может вызвать проблемы. Установка mangle в false
отключает это поведение.
Как и задача cssmin
, в этой задаче также используется формат объекта files.
Загрузите пакет и добавьте "uglify"
в задачу scripts
.
javascript grunt.loadNpmTasks('grunt-contrib-uglify');
javascript grunt.registerTask( 'scripts', 'Compiles the JavaScript files.', [ 'coffee', 'uglify' ] );
Убираться
Когда вы запускаете grunt build
, в дополнение к build/application.css
и build/application.js
все остальные файлы CSS и JavaScript находятся в каталоге build
. Поскольку они вам не нужны, добавьте подзадачи, чтобы удалить их в clean
конфигурации.
javascript clean: { build: { src: [ 'build' ] }, stylesheets: { src: [ 'build/**/*.css', '!build/application.css' ] }, scripts: { src: [ 'build/**/*.js', '!build/application.js' ] }, },
При запуске задачи, если вы не указали подзадачу, Grunt запустит их все. Если вы запустите grunt clean
из консоли, он запустит clean:build
, clean:stylesheets
и clean:scripts
. Это не проблема, потому что если clean
задача не может удалить файл, она просто игнорирует его.
Обратите внимание, как build/application.css
и build/application.js
исключены из подзадач stylesheets
и scripts
. Вы не хотите, чтобы удалить эти ложные после всей вашей тяжелой работы!
Обновите задачи, чтобы использовать соответствующие подзадачи.
javascript // define the tasks grunt.registerTask( 'stylesheets', 'Compiles the stylesheets.', [ 'stylus', 'autoprefixer', 'cssmin', 'clean:stylesheets' ] ); grunt.registerTask( 'scripts', 'Compiles the JavaScript files.', [ 'coffee', 'uglify', 'clean:scripts' ] ); grunt.registerTask( 'build', 'Compiles all of the assets and copies the files to the build directory.', [ 'clean:build', 'copy', 'stylesheets', 'scripts' ] );
нефрит
Jade — это язык шаблонов, который делает написание HTML увлекательным. Добавьте Jade в свой проект с помощью пакета grunt-contrib-jade
.
javascript jade: { compile: { options: { data: {} }, files: [{ expand: true, cwd: 'source', src: [ '**/*.jade' ], dest: 'build', ext: '.html' }] } },
Как и задачи со stylus
и coffee
, jade
настраивается с использованием формата массива файлов. Заметьте объект data
внутри options
? Этот объект передается каждому шаблону при компиляции файлов Jade. Это удобно для таких вещей, как создание отдельных сборок для разработки и производства или создание динамического контента.
Как и прежде, вам нужно добавить исключение в задачу copy
чтобы предотвратить копирование файлов Jade.
javascript copy: { build: { cwd: 'source', src: [ '**', '!**/*.styl', '!**/*.coffee', '!**/*.jade' ], dest: 'build', expand: true }, },
Не забудьте загрузить grunt-contrib-jade
и добавить его в `build`.
javascript grunt.loadNpmTasks('grunt-contrib-jade');
javascript grunt.registerTask( 'build', 'Compiles all of the assets and copies the files to the build directory.', [ 'clean:build', 'copy', 'stylesheets', 'scripts', 'jade' ] );
Часы
Ваш Gruntfile действительно начинает сиять, но разве не было бы хорошо, если бы вам не приходилось запускать grunt build
каждый раз, когда вы вносили изменения? С grunt-contrib-watch
вам не нужно! Давайте настроим задачу, которая будет следить за изменениями в вашем исходном коде и автоматически создавать их.
javascript watch: { stylesheets: { files: 'source/**/*.styl', tasks: [ 'stylesheets' ] }, scripts: { files: 'source/**/*.coffee', tasks: [ 'scripts' ] }, jade: { files: 'source/**/*.jade', tasks: [ 'jade' ] }, copy: { files: [ 'source/**', '!source/**/*.styl', '!source/**/*.coffee', '!source/**/*.jade' ], tasks: [ 'copy' ] } },
stylesheets
, scripts
и подзадачи Jade следят за изменениями в файлах Stylus, CoffeeScript и Jade и выполняют соответствующие задачи. Задача copy
просматривает все остальные файлы в приложении и копирует их в каталог сборки.
Опять же, вам нужно загрузить задание.
javascipt grunt.loadNpmTasks('grunt-contrib-watch');
Сервер разработки
Ни одна среда веб-разработки не обходится без сервера разработки. Пакет grunt-contrib-connect
— это полнофункциональный статический файловый сервер, который идеально подходит для вашего проекта.
javascript connect: { server: { options: { port: 4000, base: 'build', hostname: '*' } } }
Вы настроили сервер для размещения каталога build
на порту 4000. По умолчанию Connect будет размещать сайт только на localhost
хосте, что ограничивает доступ к серверу за пределами вашего компьютера. Установка hostname
в "*"
позволяет получить доступ к серверу из любого места.
Как и раньше, вам также нужно загрузить задачу NPM.
javascript grunt.loadNpmTasks('grunt-contrib-connect');
Если вы попытаетесь запустить grunt connect
из командной строки, сервер запустится, а затем сразу остановится. Это связано с тем, что по умолчанию задача grunt connect не выполняется бесконечно. Вы узнаете, как это исправить, в следующем разделе.
По умолчанию
Разве не было бы замечательно, если бы у вас была задача, которая объединяла все другие задачи в одну? Задача по default
идеально подходит для этого.
javascript grunt.registerTask( 'default', 'Watches the project for changes, automatically builds them and runs a server.', [ 'build', 'connect', 'watch' ] );
Задача по default
запускает `build` для создания начальной сборки. Затем он запускает сервер Connect. Наконец, он запускает watch
чтобы посмотреть файлы на предмет изменений и собрать их. Поскольку watch
продолжается до тех пор, пока оно не будет уничтожено, сервер Connect будет работать неограниченное время. Запустите grunt
в консоли и перейдите по адресу http: // localhost: 4000, чтобы увидеть ваш проект!
Вывод
Мы многое рассмотрели в этом уроке, и Грант может сделать гораздо больше. Полный список всех плагинов, доступных для Grunt, можно найти на сайте плагинов Grunt . Счастливое ворчание!