Настройка среды разработки: инструкция для новичков

Выбираем среду разработки.
7 минут15409

Первые шаги в разработке могут быть сложными – ведь вы еще не знаете об инструментах и средствах, которые могут облегчить вашу задачу. О них – эта статья от преподавателя GeekBrains Артема Шашкова.  Здесь состоится ваше знакомство со средой разработки, с Node.js и NPM, а также Gulp. Интересно? Тогда загляните и в вебинар Артема Шашкова «Настройка среды разработки Frontend-разработчика» – чтобы увидеть, как применить на практике материал статьи.

Выбираем среду разработки

IDE – Integrated Development Environment, или интегрированная среда разработки – это система программных средств, предназначенная для создания ПО. Сред существует много: от бесплатных, с минимально достаточным функционалом, до мощных платных программ с внушительной ценой. Рекомендация новичкам – бесплатный Visual Studio или Brackets. Если цена для вас – не преграда, то попробуйте продукт от JetBrains.

Выбираем IDE, устанавливаем и запускаем ее, и создаем пока пустой проект. Еще немного теории – и начнем писать «магические заклинания», которые помогут в разработке.

Таск-менеджер и Ко

Чтобы «творить магию», потребуется таск-менеджер, предназначенный для автоматического выполнения часто возникающих задач. Наиболее популярны Grunt, Webpack и Gulp.  Первый уже устарел и не блещет скоростью, второй быстро новичку не поддастся – сложноват в освоении. А Gulp – то, что нужно: быстрый и простой.

Gulp написан на JavaScript. Для работы с ним используется командная строка, а задачи описываются в специальном файле – gulpfile. Для работы с Gulp понадобятся Node.js и NPM.

Node или Node.js – это программная платформа. Она основана на движке V8, который транслирует JavaScript в машинный код. Node.js превращает JavaScript из узкоспециализированного – в язык общего назначения. Берем платформу отсюда и ставим LTS-версию, так как она протестирована и стабильна.

NPM (Node.js Package Manager) – это менеджер пакетов, входящий в состав Node.js. С его помощью будем устанавливать все необходимое для работы.

Устанавливаем и настраиваем инструментарий

Работать будем в консоли (терминале), так что открываем ее либо в IDE, либо отдельно. Создаем в IDE новый проект (например, «frontend»). Проверяем, успешно ли установился Node.js: набираем в консоли:

node -v

или

npm -v

Если все сделано правильно, в консоли увидим версию ПО. Если нет – пробуем перезапустить консоль или переустановить Node.

Node установилась, NPM на месте – можно инициализировать проект. Переходим в консоли в корневую папку проекта и пишем там же:

npm init

На все вопросы отвечаем утвердительно – нажимаем «Enter» (эти настройки пока нам не интересны). По завершении в корне проекта получаем файл package.json – это своего рода «инструкция по сборке». В нем хранится информация о всех зависимостях, задействованных в проекте.

Устанавливаем Gulp: сначала глобально, а далее уже локально – в каждом проекте, где планируется его использовать. Будем работать с четвертой версией, где есть интересные и полезные новые фишки.

Пишем в консоли:

npm i -g gulpjs/gulp#4.0
npm i gulpjs/gulp#4.0

Первая команда ставит Gulp глобально, а вторая – непосредственно в наш проект.

Процесс может занять некоторое время – ждем.

После успешной установки в проекте появится папка node_modules, а в файле package.json – следующие строки:

"dependencies": {
  "gulp": "github:gulpjs/gulp#4.0"
}

Это наша новая зависимость! В больших проектах таких могут быть десятки.

Теперь все готово для того, чтобы создать первую задачу.

Пишем первый таск

Создадим в корне проекта отдельный файл для описания и назовем его gulpfile.js. Открываем его и пишем первый таск (задачу):

const gulp = require('gulp');

gulp.task('hello', function (callback) {
   console.log('Hello!');
   callback();
});

В первой строке подключаем Gulp (далее будем действовать аналогично с остальными необходимыми модулями).

Любой таск в Gulp создается методом .task(), который принимает два аргумента – название задачи и функцию-обработчик. Отметим, что в Gulp задачи асинхронны: надо дать знать, что задача выполнена,  и ее выполняет callback() (в данном таске это просто функция-пустышка, так как нам нечего возвращать). Если этого не сделать, то в консоли мы увидим:

[01:57:52] Using gulpfile ~\WebstormProjects\frontend\gulpfile.js
[01:57:52] Starting 'hello'...
Hello!
[01:57:52] The following tasks did not complete: hello
[01:57:52] Did you forget to signal async completion?

Первый таск создан: можно запускать его в консоли! Пишем команду:

gulp hello

Здесь gulp – это вызов собственно gulp, а hello – название таска, который хотим выполнить. Все очень просто.

Усложняемся – работаем с препроцессором

Создадим что-то более сложное и функциональное, а попутно познакомимся с оставшимися методами Gulp.

Выстраиваем структуру папок. При разработке принято хранить исходники и сборку в разных папках. Создаем их: src для исходных материалов и build для готовой сборки.

Чтобы усложнить задачу, добавим в разработку препроцессор pcss (CSS-препроцессор). Это надстройка, которая с помощью новых синтаксических конструкций добавляет CSS ранее недоступные возможности. Происходит преобразование кода, написанного с использованием препроцессорного языка, в чистый и валидный CSS-код.

Установим препроцессор и несколько вспомогательных библиотек для работы с css.

Ставим сам препроцессор:

npm i gulp-postcss

Далее устанавливаем autoprefixer, cssnext и precss

npm i autoprefixer
npm i cssnext
npm I precss

В файле package.json появляются следующие строки:

"gulp-postcss": "^7.0.0",
"autoprefixer": "^7.1.6",
"cssnext": "^1.8.4",
"precss": "^2.0.0"
"gulp-dest": "^0.2.3",

Понимаете, для чего это нужно? Скоро сами удивитесь, как это полезно.

Подключаем препроцессор и дополнительные модули (в начале файла):

const postcss = require('gulp-postcss');
const autoprefixer = require('autoprefixer');
const cssnext = require('cssnext');
const precss = require('precss');
const dest = require('gulp-dest');

Создадим в src папку pcss, где будем хранить стили. Добавим файл style.pcss и опишем несколько стилей в синтаксисе pcss:

* {
 padding: 0;
 margin: 0;
}

.firstClass {
 background: #f00;

 &__active {
   border: 1px solid #000;

   &-on {
     border-color: #0f0;
   }
 }
}

.hello {
 font-size: 60px;
 color: #000000;
}

Файл готов! Создадим «таск», который будет переписывать pcss в css и класть в папку build/css. Для удобства работы с директориями добавим в gulpfile объект конфигурации:

const config = {
   src: "./src", // директория с исходниками
   build: "./build" // Директория сборки
};

Теперь напишем сам таск и назовем его «css»:

gulp.task('css', function () {
   const processors = [autoprefixer, cssnext, precss];
   return gulp.src(`${config.src}/pcss/**/*.pcss`)
       .pipe(postcss(processors))
       .pipe(dest('css', {ext: '.css'}))
       .pipe(gulp.dest(config.build))
});

Разберемся, что тут происходит:

const processors = [autoprefixer, cssnext, precss];

Задан массив с дополнительными модулями для нашего postcss. Далее идет возврат (return) «цепочки» потоков (.pipe в каждом таком потоке выполняются какие-то задачи).

Метод .src у gulp указывает, откуда брать файлы для обработки (/**/*.pcss говорит о том, что нужно сканировать текущую и все вложенные папки на наличие файлов с расширением pcss).

Gulp.dest задает, куда положить результат обработки. Postcss вызывает обработку .pcss-файлов с параметрами из processors. dest (не путать с gulp.dest), дает возможность задать расширение выходного файла (в нашем случае – .css) и папку, в которую нужно положить файл.

Задача написана – протестируем ее! Набираем в консоли:

gulp css

Наблюдаем следующее:

$ gulp css
[13:29:26] Using gulpfile ~/Downloads/frontend/gulpfile.js
[13:29:26] Starting 'css'...
[13:29:27] Finished 'css' after 1.08 s

Переходим в build и видим, что там появилась папка css, а в ней – файл style.css с таким содержанием:

* {
  padding: 0;
  margin: 0;
}

.firstClass {
  background: #f00;
}

.firstClass__active {
    border: 1px solid #000;
  }

.firstClass__active-on {
      border-color: #0f0;
    }

.hello {
  font-size: 60px;
  color: #000000;
}

Перед нами привычный CSS-код, который можно подключить html-файлу.

Собираем js

Будем используем ES6-синтаксис – понадобится соответствующий плагин, чтобы сохранить кроссбраузерность приложения. Ставим Babel (занимается преобразованием ES6 в ES5):

npm i babel-core
npm i gulp-babel babel-preset-env

Подключаем Babel:

const babel = require('gulp-babel');

Напишем задачу ‘js’, которая будет обрабатывать js-файлы:

gulp.task('js', function () {
    return gulp.src('./src/js/**/*.js')
        .pipe(babel({
            presets: ['env']
        }))
        .pipe(gulp.dest(`${config.build}/js`))
});

Все аналогично задаче css, только вместо postcss в дело вступает babel.

Напишем простенький js-файл с ES6-кодом (пусть это будет script.js, размещенный в папке src/js). Испытаем работу таска:

function hello(name) {
    return `Hello! ${name}`;
}

console.log(hello('Петя!'));

Выполним задачу:

gulp js

Результатом будет файл script.js в папке build/js со следующим содержанием:

'use strict';

function hello() {
    var name = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'n/a';

    return 'Hello! ' + name;
}

console.log(hello('Петя'));

В результате работы Babel код немного усложнился по сравнению с исходным.

С одним файлом все хорошо, но что произойдет, если их будет 2, 3, 10 и больше? Совсем неудобно все это подключать к странице. Эту проблему поможет решить модуль gulp-concat.

Поставим его:

npm i gulp-concat

Скорректируем gulpfile:

const concat = require('gulp-concat');

Доработаем таск js:

gulp.task('js', function () {
    return gulp.src(`${config.src}/js/**/*.js`)
        .pipe(babel({
            presets: ['env']
        }))
        .pipe(concat('main.js'))
        .pipe(gulp.dest(`${config.build}/js`))
});

Теперь concat(‘main.js’) объединяет все файлы в один – main.js, который удобно подключать к странице (попробуйте создать несколько файлов и понаблюдайте за результатом).

Научившись обрабатывать стили, JavaScript-код, вы все еще каждый раз набираете gulp ‘task’ в консоли. Это не очень удобно. Можно ли объединить все в одной задаче?

Да, и прежде чем это сделать, напишем еще пару вспомогательных тасков для очистки папки сборки и переноса остальных файлов (html, картинок, шрифтов и т.д.).

Ставим ‘del’:

npm i del

Подключаем:

const del = require('del');

Напишем задачи ‘clr’ и ‘assets’. Первая будет вычищать папку build перед сборкой, а вторая – просто переносить файлы.

gulp.task('clr', function () {
    return del('${config.build}/*')
});
gulp.task('assets', function () {
    return gulp.src('./src/assets/**')
        .pipe(gulp.dest('./build/'));
});

Создадим отдельный таск для html:

gulp.task('html', function () {
    return gulp.src(`${config.src}/assets/*.html`)
        .pipe(gulp.dest('./build'))
});

Теперь можем вычищать нашу директорию сборки и переносить остальные файлы. Но при разработке изменения происходят во многих файлах, и каждый раз нужно пересобирать проект вручную. Чтобы избавиться от этой рутины, воспользуемся методом gulp.watch.

Напишем задачу ‘watch’, которая будет отслеживать изменения в нужных файлах и при необходимости запускать соответствующие таски:

gulp.task('watch', function () {
    gulp.watch(`${config.src}/pcss/**/*.pcss`, gulp.series('css'));
    gulp.watch(`${config.src}/js/**/*.js`, gulp.series('js'));
    gulp.watch(`${config.src}/assets/*.html`, gulp.series('html'));
});

В данной задаче мы следим за изменениями в файлах стилей, скриптов и html.

Осталось написать задачу для первичной сборки – назовем ее ‘build’, а также задачу ‘default’, которая позволит, просто набрав команду ‘gulp’, собрать проект и запустить «вотчеры».

Задача ‘build’:

gulp.task('build', gulp.series(
    'clr',
    gulp.parallel('css', 'js', 'assets', 'html')
));

Используем метод .parallel, чтобы ускорить процесс и запустить все задачи в параллельных потоках.

Задача ‘default’:

gulp.task('default', gulp.series('build', gulp.parallel('watch', 'server')));

Метод .series запускает задачи последовательно: сначала выполнится ‘build’, а далее параллельно стартуют ‘watch’ и ‘server’.

Пишем задачу ‘server’

Стоп, что за задача ‘server’ – откуда, зачем? Это для «полного фэншуя» в разработке. Она «поднимает» виртуальный сервер, перезагружает браузеры и синхронизирует их в случае изменений. И все это – при помощи одной команды ‘gulp’, введенной перед началом работы. Далее все происходит автоматически. Magic!

Ставим модуль ‘browser-sync’ для задачи ‘server’:

npm i browser-sync

Подключаем:

const browserSync = require('browser-sync').create();

И пишем таск ‘server’:

gulp.task('server', function () {
    browserSync.init({
        server: {
            baseDir: config.build,
            index: 'index.html'
        }
    });
    browserSync.watch(`${config.build}/**/*.*`).on('change', browserSync.reload)
});

Запускаем сервер, в настройках которого указываем базовую директорию (config.build) и индекс-файл, который будет открываться в браузере.

Остается набрать в консоли gulp и наслаждаться разработкой.

Сжимаем код

В заключение – небольшой бонус. Минифицируем JavaScript-код, чтобы уменьшить конечный размер файла.

Ставим gulp-uglifyjs:

npm i gulp-uglifyjs

Дорабатываем таск ‘js’:

gulp.task('js', function () {
    return gulp.src(`${config.src}/js/**/*.js`)
        .pipe(babel({
            presets: ['env']
        }))
        .pipe(concat('main.js'))
        .pipe(uglifyJs())
        .pipe(gulp.dest(`${config.build}/js`))
});

Перезапускаем и снова выполняем ‘gulp’ (остановить предыдущий можно нажатием ctrl+c), чтобы применились изменения. Код в main.js теперь сжат: читаемость стала хуже, но функциональность сохранилась.

P.S. Помните, мы говорили про зависимости и package.json? Попробуйте удалить папку build и node_ modules, а затем выполнить задачи. Оп, ничего не работает!.. А теперь – еще немного магии. В консоли в корне проекта пишем команду npm i и дожидаемся ее выполнения. Пробуем выполнить задачи теперь... Бинго!

Так вы можете легко развернуть ваш проект на любой другой машине. Помните: никогда не переносите проект полностью, то есть с папкой node_modules и папкой со сборкой. Ведь на разных операционных системах различные модули могут работать некорректно – их нужно ставить под конкретную ОС. Перенося проект, который разрабатывался на Win, на машину с MacOS, вы рискуете – может и «не завестись». Скорее всего, вам придется частично или полностью переустанавливать модули.

Код из этой статьи можно использовать как основу при автоматизации разработки в ваших проектах. Вы можете легко модифицировать gulpfile.js, добавляя или удаляя новые модули и задачи. Удачи в кодинге!

web_developerwebdevelopmentcssjavascript
Нашли ошибку в тексте? Напишите нам.
Спасибо,
что читаете наш блог!