После посещения TheAntiEvent я понял, что история, которую я написал несколько месяцев назад о Gulp, сильно отличается от сегодняшней реальности: https://medium.com/@jontorrado/working-with-gulp-step-by-step- e0d5fe2d2f23 . Я не буду больше писать о том, как установить Gulp, но я обновлю некоторые из описанных там задач и добавлю новые.

Преобразование SCSS в CSS

Здесь не так много изменений:

var gulp = require('gulp'),
  autoprefixer = require('autoprefixer'),,
  cssnano = require('cssnano'),
  postcss = require('gulp-postcss'),
  rename = require('gulp-rename'),
  sass = require('gulp-sass'),
  sasslint = require('gulp-sass-lint');
var paths = {
  js: contexts.assets + '/js',
  sass: 'app/Resources/assets/scss',
  buildCss: 'web/css',
  buildJs: 'web/js'
};
var watch = {
  js: [
    paths.js + '/**/*.js'
  ],
  sass: [
    paths.sass + '/**/*.scss'
  ]
};
gulp.task('sass', function () {
  var plugins = [
    autoprefixer({browsers: ['last 1 version']}),
    cssnano()
  ];
  return gulp.src(paths.sass  + '/app.scss')
      .pipe(sass())
      .pipe(postcss(plugins))
      .pipe(rename({suffix: '.min'}))
      .pipe(gulp.dest(paths.buildCss));
});
gulp.task('sass-lint', function () {
  return gulp.src(paths.sass  + '/**/*.scss')
      .pipe(sassLint())
      .pipe(sassLint.format())
      .pipe(sassLint.failOnError());
gulp.task('watch', function () {
  gulp.watch(watch.sass, { interval: 500 }, ['sass']);
});

Прежде чем объяснять, что здесь нового по сравнению с последней историей, обязательно добавьте необходимые зависимости (перечисленные в верхней части кода выше) в ваш package.jsonfile. В предыдущем коде вы можете прочитать следующие задачи:

  • sass: берет основной файл app.scss, вызывает sass(), затем минимизирует результат, добавляет .min к имени файла и перемещает его в папку назначения. Элементы new: мы используем postcss для добавления префиксов поставщиков и минимизации итогового файла. cssnano допускает некоторые конфигурации, например cssnano({zindex: false}).
  • sass-lint: если вы новичок в мире подкладки, ДОБРО ПОЖАЛОВАТЬ. С помощью этой задачи вы сможете обнаруживать ошибки SCSS (теперь с Node вместо Ruby). Вы должны добавить свои правила линтинга в sass-lint.yml файл. Проверьте файл с примером здесь.
  • часы: это автоматически вызовет sass задачу при изменении .scss файла. Просто введите gulp watch, чтобы начать просмотр. Параметр interval делает его светлее (подходит для SSD-дисков).

Объединение и минимизация JavaScript

Здесь почти ничего не изменилось.

В предыдущей истории произошла ошибка при использовании livereload. Gulp отправил столько перезагрузок страницы, сколько обработанных им файлов JavaScript. Итак, вопрос был в том, как отправить только 1 перезагрузку страницы после завершения всей задачи JavaScript? Вот и решение:

var gulp = require('gulp'),
  concat = require('gulp-concat'),
  eslint = require('gulp-eslint'),
  uglify = require('gulp-uglify');
// Paths in the code above
var jsFiles = [
  paths.js + '/**/*.js'
];
gulp.task('js', function () {
  return gulp.src(jsFiles)
    .pipe(concat('app.min.js'))
    .pipe(uglify())
    .pipe(gulp.dest(paths.buildJs));
});
gulp.task('eslint', function () {
  return gulp.src(watch.js)
    .pipe(eslint())
    .pipe(eslint.format())
    .pipe(eslint.failAfterError());
});
gulp.task('livereload-js', ['js'], function () {
  livereload.reload();
});
gulp.task('watch', function () {
  gulp.watch(watch.sass, { interval: 500 }, ['sass']);
  gulp.watch(watch.js, { interval: 500 }, ['js', 'livereload-js']);
});

Как видите, новая задача livereload-js зависит от js, поэтому перед ее запуском она будет ждать завершения js задачи. Потрясающий!

Запуск бинарных файлов

Возможно, вы захотите использовать Gulp для каждой отдельной задачи, даже для двоичных файлов (или также для выполнения sh файлов!). Вы можете достичь этой цели с помощью следующего кода:

var cp = require('child_process');
gulp.task('binary', function () {
  return cp.execFile('bin/binary', ['--option=value'], function (err, stdout, stderr) {
    console.log(stdout);
    console.log(stderr);
  });
});

Водопроводчик

Сантехник заменит ваш pipe метод и поймает запущенный error, который прерывает выполнение (например, когда вы делаете что-то не так и метод watch останавливается). Это просто:

// ... plumber = require('gulp-plumber')
gulp.task('sass', function () {
  var plugins = [
    autoprefixer({browsers: ['last 1 version']}),
    cssnano()
  ];
  return gulp.src(paths.sass  + '/app.scss')
      .pipe(plumber())
      .pipe(sass())
      .pipe(postcss(plugins))
      .pipe(rename({suffix: '.min'}))
      .pipe(gulp.dest(paths.buildCss));
});

Включая другие файлы Gulpfile.js

Если вы работаете в большом проекте с некоторыми разделенными подмодулями (например, веб-сайт и администратор), вы можете захотеть иметь один gulpfile, включающий остальные. Вот как это сделать:

var gulp = require('gulp');
var chug = require('gulp-chug');
var argv = require('yargs').argv;
config = [
  '— rootPath',
  argv.rootPath || '../../../../web/assets/',
  '— nodeModulesPath',
  argv.nodeModulesPath || '../../../../node_modules/'
];
gulp.task('admin', function() {
  gulp.src('submodule/path/to/Admin/Gulpfile.js', { read: false })
    .pipe(chug({ args: config }))
  ;
});

Конвертируйте изображения в WebP

Вы должны использовать .webp изображения с тегом <picture>, чтобы пользователи Chrome могли перемещаться намного быстрее (и потребляли меньше трафика!). Вы можете автоматизировать процесс преобразования изображений в webp.

var gulp = require('gulp'),
    webp = require('gulp-webp');

gulp.task('default', function() {
  gulp.src('path/to/images/**.jpg')
    .pipe(webp())
    .pipe(gulp.dest('dist'))
});

Другие полезные плагины

Здесь у вас есть тщательно подобранный список полезных плагинов gulp, о которых вы должны внимательно прочитать: https://gist.github.com/renarsvilnis/ab8581049a3efe4d03d8.