Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core 7
Grunt представляет еще один инструмент для автоматизации задач на JavaScript, который позволяет минифицировать скрипты, компилировать код TypeScript в javascript и ряд других вещей. Хотя в проектах на ASP.NET по умолчанию для автоматизации используется BundlerMinifier, Visual Studio также имеет полноценную поддержку для Grunt.
Для работы с Grunt создадим новый проект по типу ASP.NET Core Web App (Model-View-Controller). Новый проект по умолчанию не содержит никакой функциональности Grunt, поэтому нам ее надо добавить. Grunt также, как и Gulp, можно добавить через npm. Поэтому вначале добавим конфигурационный файл для NPM, который назовем package.json:
Далее откроем добавленный файл package.json и изменим его содержание следующим образом:
{ "version": "1.0.0", "name": "asp.net", "private": true, "devDependencies": { "grunt": "1.0.1", "grunt-contrib-clean": "1.0.0", "grunt-contrib-copy": "1.0.0", "grunt-contrib-concat": "1.0.1", "grunt-contrib-uglify": "2.0.0", "grunt-contrib-watch": "1.0.0", "grunt-contrib-cssmin": "1.0.2" } }
После сохранения файла в проект будут добавлены пакеты grunt. А в узле Dependencies/npm мы можем увидеть все установленные модули:
Что представляют все эти модули?
grunt: основной пакет инструментария Grunt
grunt-contrib-clean: задача, которая удаляет файлы и папки
grunt-contrib-copy: задача, которая управляет копированием файлов и папок в новое место
grunt-contrib-concat: задача, которая соединяет все файлы в один
grunt-contrib-uglify: задача, которая минимизирует файлы JavaScript
grunt-contrib-cssmin: задача, которая минимизирует файлы CSS
grunt-contrib-watch: задача, которая отслеживает изменения в файлах
Вообще в Grunt имеется гораздо больше задач, но в данном случае мы ограничимся этими.
Grunt настраивается с помощью файла gruntfile.js, который регистрирует задачи, запускаемые в зависимости от различных событий в Visual Studio. Поэтому добавить в корень проекта новый файл javascript, который назовем gruntfile.js:
После добавления изменим содержимое файла gruntfile.js следующим образом:
module.exports = function (grunt) { grunt.initConfig({ concat: { build: { src: ['wwwroot/js/*'], dest: 'wwwroot/js/app.js' } }, uglify: { build: { files: { 'wwwroot/bundles/jquery.js': ['wwwroot/lib/jquery/dist/jquery.js'], 'wwwroot/bundles/jqueryval.js': ['wwwroot/lib/jquery-validation/dist/jquery.validate.js', 'lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js'], 'wwwroot/bundles/bootstrap.js': ['wwwroot/lib/bootstrap/dist/js/bootstrap.min.js'], 'wwwroot/bundles/app.js': ['wwwroot/js/app.js'] } } }, clean: ["wwwroot/js/app.js"], cssmin: { build: { files: { 'wwwroot/bundles/main.css': ['wwwroot/lib/bootstrap/dist/css/bootstrap.css', 'wwwroot/css/site.css'] } } } }); grunt.loadNpmTasks('grunt-contrib-cssmin'); grunt.loadNpmTasks('grunt-contrib-concat'); grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.loadNpmTasks('grunt-contrib-clean'); grunt.registerTask('build', ['copy', 'concat', 'uglify', 'cssmin', 'clean']); };
Разберем этот файл по секциям. Вначале идет задача concat
:
concat: { build: { src: ['wwwroot/js/*'], dest: 'wwwroot/js/app.js' } }
Build
указывает на общее название задачи, которое потом будет использоваться для вызова задачи concat. Параметр src
указывает на набор файлов, который надо соединить в один. А параметр dest
указывает на название нового файла, в который файлы из src
будут объединяться. Здесь применяется синтаксис подстановок. С помощью звездочки указывается, что все файлы из папки wwwroot/js/
будут соединяться в файл wwwroot/js/app.js
Затем идет задача uglify
:
uglify: { build: { files: { 'wwwroot/bundles/jquery.js': ['wwwroot/lib/jquery/dist/jquery.js'], 'wwwroot/bundles/jqueryval.js': ['wwwroot/lib/jquery-validation/dist/jquery.validate.js', 'lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js'], 'wwwroot/bundles/bootstrap.js': ['wwwroot/lib/bootstrap/dist/js/bootstrap.min.js'], 'wwwroot/bundles/app.js': ['wwwroot/js/app.js'] } } }
Задача uglify управляет минимизацией файлов javascript. Параметр files
указывает набор пар "минимизированный файл: [массив оригинальных файлов]".
Например, из файла wwwroot/js/app.js будет создаваться минимизированный файл wwwroot/bundles/app.js. Из нескольких файлов можно создать один минимизированный файл,
что позволяет одновременно провести их соединение.
Далее задача clean
удаляет ранее созданный файл wwwroot/js/app.js, так как он был минимизирован в файл в другом месте:
clean: ["wwwroot/js/app.js"],
Затем минимизируем css-файлы задачей cssmin
:
cssmin: { build: { files: { 'wwwroot/bundles/main.css': ['wwwroot/lib/bootstrap/dist/css/bootstrap.css', 'wwwroot/css/site.css'] } } }
Принцип минимизации здесь аналогичен задаче uglify.
После определения задач идет код для загрузки используемых модулей:
grunt.loadNpmTasks('grunt-contrib-cssmin'); grunt.loadNpmTasks('grunt-contrib-concat'); grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.loadNpmTasks('grunt-contrib-clean');
И в самом конце регистрируется общая задача build
, которая будет запускать все выше определенные задачи:
grunt.registerTask('build', ['concat', 'uglify', 'cssmin', 'clean']);
После сохранения файла gruntfile.js нажмем на него правой кнопкой мыши и в выпадающем меню выберем Task Runner Explorer.
И в этом окне откроется список задач Grunt. (Если окно Task Runner не отображает задач Grunt, то следует нажать на кнопку обновления в окне Task Runner).
В самом низу окна найдем пункт Alias Tasks. Нажмем правой кнопкой на build
, который располагается под этим пунктом, и в контекстном меню выберем команду Run
:
После запуска консоль отобразит нам диагностическую информацию
Подобным образом можно запускать отдельные задачи. Например, при построении видно, что на момент выполнения задачи "clean" еще не существует файл app.js, который надо удалить, поэтому данную задачу можно запустить отдельно от других после того, как остальные задачи отработают.
И после выполнения всех задач в папке wwwroot появятся новые файлы:
Все эти созданные файлы мы можем затем подключить в представлении или на мастер-странице:
<link href="~/bundles/main.css" rel="stylesheet" /> <script src="~/bundles/jquery.js"></script> <script src="~/bundles/jqueryval.js"></script> <script src="~/bundles/bootstrap.js"></script> <script src="~/bundles/app.js"></script>