Npm

Use last JavaScript version in your gulpfile

Node already supports a lot of ES2015, to avoid compatibility problem we suggest to install Babel and rename your as .

npm install --save-dev babel-register babel-preset-es2015

Then create a .babelrc file with the preset configuration.

{"presets""es2015"}

And here’s the same sample from above written in ES2015.

importgulpfrom'gulp4';importlessfrom'gulp-less';importbabelfrom'gulp-babel';importconcatfrom'gulp-concat';importuglifyfrom'gulp-uglify';importrenamefrom'gulp-rename';importcleanCSSfrom'gulp-clean-css';importdelfrom'del';constpaths={  styles{    src'src/styles/**/*.less',    dest'assets/styles/'},  scripts{    src'src/scripts/**/*.js',    dest'assets/scripts/'}};constclean=()=>del('assets');export{clean};exportfunctionstyles(){returngulp.src(paths.styles.src).pipe(less()).pipe(cleanCSS()).pipe(rename({      basename'main',      suffix'.min'})).pipe(gulp.dest(paths.styles.dest));}exportfunctionscripts(){returngulp.src(paths.scripts.src,{ sourcemapstrue}).pipe(babel()).pipe(uglify()).pipe(concat('main.min.js')).pipe(gulp.dest(paths.scripts.dest));}exportfunctionwatch(){gulp.watch(paths.scripts.src, scripts);gulp.watch(paths.styles.src, styles);}constbuild=gulp.series(clean,gulp.parallel(styles, scripts));export{build};exportdefaultbuild;

API

You can pass an object of options to configure gulp-sass-lint to your specific projects needs the options are listed below.

{  options{    formatter'stylish','merge-default-rules'false}}

By default SassLint includes it’s own configuration file, if you provide one it attempts to merge everything except for the files section below. If you pass options directly into the plugin they take precedence. The order can be visualised below with the SassLint config being the base.

You can disable this behaviour by setting to false within the object that you pass to or you can include it in your config file options that you can pass into with .

Type:

Within the files object you can specify a glob pattern as a string or an array of glob pattern for both the and options. Please note that your include option will currently be ignored as you should be passing the glob patterns / file paths to be linted directly to gulp . The ignore option however will still be respected if you’d rather specify them in your config rather than in the method.

{  files{    include'**/*.scss',    ignore'test/**/*.scss'}}

Type:

{  rules{'no-ids','no-mergeable-selectors'1,'hex-length'2,{'style''long'}}}

You can pass the path to a custom config file via the option. The path will be relative to where you’re running gulp from.

{  configFile'app/config/.my-config.yml'}

The following highlights all of the above options in use

'use strict';var gulp =require('gulp'),    sassLint =require('gulp-sass-lint');gulp.task('default',function(){returngulp.src('sass/**/*.s+(a|c)ss').pipe(sassLint({      options{        formatter'stylish','merge-default-rules'false},      files{ignore'**/*.scss'},      rules{'no-ids'1,'no-mergeable-selectors'},      configFile'config/other/.sass-lint.yml'})).pipe(sassLint.format()).pipe(sassLint.failOnError())});
gulp.task('lint_sass_jenkins',function(){var file =fs.createWriteStream('reports/lint_sass.xml');var stream =gulp.src('public/sass/**/*.scss').pipe(sassLint({            options{                configFile'.sass-lint.yml',                formatter'checkstyle'}})).pipe(sassLint.format(file));stream.on('finish',function(){file.end();});return stream;});

Fails the task and emits a gulp error when all files have been linted if an error has been detected (rules set to severity 2).

What’s new in 4.0?!

  • The task system was rewritten from the ground-up, allowing task composition using and methods
  • The watcher was updated, now using chokidar (no more need for gulp-watch!), with feature parity to our task system
  • First-class support was added for incremental builds using
  • A method was exposed to create symlinks instead of copying files
  • Built-in support for sourcemaps was added — the gulp-sourcemaps plugin is no longer necessary!
  • Task registration of exported functions — using node or ES exports — is now recommended
  • Custom registries were designed, allowing for shared tasks or augmented functionality
  • Stream implementations were improved, allowing for better conditional and phased builds

API

Type:
Default:

Transform assets before concat. For example, to integrate source maps:

var gulp =require('gulp'),    sourcemaps =require('gulp-sourcemaps'),    useref =require('gulp-useref'),    lazypipe =require('lazypipe');gulp.task('default',function(){returngulp.src('index.html').pipe(useref({},lazypipe().pipe(sourcemaps.init,{ loadMapstrue}))).pipe(sourcemaps.write('maps')).pipe(gulp.dest('dist'));});

Type: or
Default:

Specify the location to search for asset files, relative to the current working directory. Can be a string or array of strings.

Type:
Default:

Specify the output folder relative to the cwd.

Type:
Default:

Skip assets and only process the HTML files.

Type:
Default:

Skip concatenation and add all assets to the stream instead.

Type:
Default:

Add a string that should separate the concatenated files.

Type:
Default:

Use additional streams as sources of assets. Useful for combining gulp-useref with preprocessing tools. For example, to use with TypeScript:

var ts =require('gulp-typescript');var tsStream =gulp.src('src/**/*.ts').pipe(ts());gulp.task('default',function(){returngulp.src('src/index.html').pipe(useref({ additionalStreamstsStream})).pipe(gulp.dest('dist'));});

Type:
Default:

Add a transformPath function in case the path needs to be modified before search happens.

var gulp =require('gulp'),    useref =require('gulp-useref');gulp.task('default',function(){returngulp.src('app/*.html').pipe(useref({transformPathfunction(filePath){returnfilePath.replace('/rootpath','')}})).pipe(gulp.dest('dist'));});

API

function

Type: .

Function that may manipulate the given url. It takes the url as only parameter.

Note: the function will be run after the options are evaluated.

options

Type: Required if not given.

An object with options or a function that may manipulate css urls.

options.prepend

Type: Default value: .

Prepend the given string to all urls.

options.append

Type: Default value: .

Append the given string to all urls.

options.unsafe

Type: Default value: .

Do not use when prepending to urls.

options.data

Type: Default value: .

Include data URIs such as .

options.sourcemaps

Type: Default value: .

Write sourcemaps.

Разделяем HTML

На нашем сайте будут две тестовые страницы и . Структура на страницах повторяется: есть блоки , , . Поэтому все нужно вынести в отдельные файлы модули.

Разберем все более подробно.

  • — папка для наших страниц, где в корне хранятся непосредственно страницы
  • — хранятся общие блоки для всех страниц
  • — хранятся модули страниц, где внутри еще одна папка, которая соответствует названию страницы

Пройдемся по файлам:

Автоматизируем первую задачу

Теперь подключаем нашу задачу в файле .

Здесь мы создаем серию с одной таски с названием ; потом мы добавим ещё. Теперь в консоли выполните команду , и в папке должны появиться два файла: и .

Стили

Дальше мы добавим вспомогательные плагины:

Пройдемся по каждому плагину:

Файлы styles:

Немного обсудим файл . Есть два варианта организации медиа-запросов.

  1. Писать медиа-запросы ко всему блоку в конце файла.
  2. Писать медиа-запросы в самом селекторе, используя и .

Я поклонник второго варианта, удобно, когда все стили в одном месте, и не нужно никуда скроллить и ничего искать.

Оптимизируем картинки, копируем шрифты, делаем svg-sprite

Устанавливаем плагины
Для картинок используется банальный код, который вы уже на данном этапе без проблем можете понять.

Шрифты мы просто копируем.

Экономим время

Главное — не забыть вызвать функцию-callback, которая сообщит gulp, что задача выполнена.

Lighthouse

Кстати, некоторые заказчики смотрят на эти показатели, так как не знают других способов оценить качество верстки.

Вы можете возразить, зачем ради одной странички заморачиваться, но в реальных проектах их может быть больше 10.

Устанавливаем и создаём задачу.
Результат для каждой странички будет генерироваться в папку . Там будут ‘html’ файлы, они открываются автоматически, но вы сами в любой момент можете их открыть и посмотреть результат.

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

Копируем зависимости

В нашей команде есть правило, что все нужно загружать в репозиторий. Это было связано с тем, что иногда может пропасть интернет в стране. Вручную скачивать пакеты с сайтов и загружать их в папку не очень удобно, ещё сложно следить за версиями пакетов, и каждый раз из node_modules обновлять также не очень удобно, поэтому мы должны оптимизировать этот процесс.

Теперь сделаем, чтобы при изменении вызывался плагин. Не вижу смысла сильно заморачиваться и следить только за изменениями объекта , поэтому будем просто следить за файлом.

NPM-скрипты

Последняя оптимизация. Часто сложно и лень запоминать консольные команды, там много параметров, вводить все эти пути занимает время,
поэтому запишем длинные команды в более краткие команды.

Рассмотрим такую ситуацию: вы скопировали большой кусок кода с постороннего ресурса, и
он не соответствует вашим правилам форматирования.
Не будете же вы всё править руками? Можно просто в консоли ввести команду, которая все исправит
за вас , команда длинная, поэтому запишем ее в NPM-скрипт

Как видим на скрине, теперь в консоли можно вводить .

Напишем еще несколько команд:

  • — вместо , привык, что любой проект у меня запускается этой командой
  • — вместо , такая же ситуация, как в прошлом пункте
  • — вместо , сначала собираем проект, а потом уже тестируем
  • — запуск разных линтеров, хорошей практикой будет запускать перед комитом

Usage

The following example will parse the build blocks in the HTML, replace them and pass those files through. Assets inside the build blocks will be concatenated and passed through in a stream as well.

var gulp =require('gulp'),    useref =require('gulp-useref');gulp.task('default',function(){returngulp.src('app/*.html').pipe(useref()).pipe(gulp.dest('dist'));});

With options:

var gulp =require('gulp'),    useref =require('gulp-useref');gulp.task('default',function(){returngulp.src('app/*.html').pipe(useref({ searchPath'.tmp'})).pipe(gulp.dest('dist'));});
var gulp =require('gulp'),    useref =require('gulp-useref'),    gulpif =require('gulp-if'),    uglify =require('gulp-uglify'),    minifyCss =require('gulp-clean-css');gulp.task('html',function(){returngulp.src('app/*.html').pipe(useref()).pipe(gulpif('*.js',uglify())).pipe(gulpif('*.css',minifyCss())).pipe(gulp.dest('dist'));});

Blocks are expressed as:

... HTML Markup, list of script / link tags.
  • type: either , or ; will remove the build block entirely without generating a file
  • alternate search path: (optional) By default the input files are relative to the treated file. Alternate search path allows one to change that. The path can also contain a sequence of paths processed from right to left, using JSON brace array notation e.g .
  • path: the file path of the optimized file, the target output
  • parameters: extra parameters that should be added to the tag

An example of this in completed form can be seen below:

html>head>linkhref="css/one.css"rel="stylesheet">linkhref="css/two.css"rel="stylesheet">head>body>scripttype="text/javascript"src="scripts/one.js">script>scripttype="text/javascript"src="scripts/two.js">script>body>html>

The resulting HTML would be:

html>head>linkrel="stylesheet"href="css/combined.css"/>head>body>scriptsrc="scripts/combined.js">script>body>html>

Отслеживание файлов

Gulp имеет возможность следить за изменением файлов и выполнять задачу или задачи при обнаружении изменений. Эта функция удивительно полезна (для меня, наверное, одна из самых полезных в Gulp). Вы можете сохранить Less-файл, а Gulp превратит его в CSS и обновит браузер без каких-либо действий с вашей стороны.

Для слежения за файлом или файлами используйте функцию gulp.watch(), которая принимает шаблон файлов или их массив (такой как gulp.src()), либо массив задач для их запуска или выполнения функции обратного вызова.

Предположим, что у нас есть задача build, она превращает наши файлы шаблонов в HTML и мы хотим определить задачу watch, которая отслеживает изменение шаблонов и запускает задачу для преобразования их в HTML. Мы можем использовать функцию watch следующим образом:

Теперь при изменении файла шаблона будет запущена задача build, которая создаст HTML.

Вы также можете указать для watch функцию обратного вызова вместо массива задач. В этом случае функция получает объект event содержащий информацию о событии, которое вызвало функцию:

Другой отличительной особенностью gulp.watch() является то, что она возвращает watcher. Используйте его для прослушивания дополнительных событий или для добавления файлов в watch. Например, чтобы одновременно запустить список задач и вызвать функцию, вы можете добавить слушателя в событие change при возвращении watcher:

В дополнение к событию change вы можете прослушивать ряд других событий:

  • end Срабатывает, когда watcher завершается (это означает, что задачи и функции обратного вызова не будут больше вызываться при изменении файлов).
  • error Срабатывает, когда происходит ошибка.
  • ready Срабатывает, когда файлы были найдены и готовы к отслеживанию.
  • nomatch Срабатывает, когда запросу не соответствует ни один файл.

Объект watcher также содержит некоторые методы, которые можно вызывать:

  • watcher.end() Останавливает watcher (при этом задачи или функции обратных вызовов не будут больше вызываться).
  • watcher.files() Возвращает список файлов за которыми следит watcher.
  • watcher.add(glob) Добавляет файлы в watcher, которые соответствуют указанному шаблону glob (также принимает необязательную функцию обратного вызова в качестве второго аргумента).
  • watcher.remove(filepath) Удаляет определённый файл из watcher.

Gulp

Disabling

Autoprefixer was designed to have no interface – it just works.
If you need some browser specific hack just write a prefixed property
after the unprefixed one.

a{transformscale(0.5);-moz-transformscale(0.6);}

You can use these plugin options to control some of Autoprefixer’s features.

  • will disable parameters prefixing.
  • will disable flexbox properties prefixing.
    Or will add prefixes only for final and IE
    versions of specification.
  • will disable cleaning outdated prefixes.

You should set them inside the plugin like so:

autoprefixer({ grid'autoplace'})

If you do not need Autoprefixer in some part of your CSS,
you can use control comments to disable Autoprefixer.

.a{transition1s;}.b{transition1s;}.c{transition1s;maskurl(image.png);}

There are three types of control comments:

  • : enable/disable all Autoprefixer translations for the
    whole block both before and after the comment.
  • : disable Autoprefixer only for the next property
    or next rule selector or at-rule parameters (but not rule/at‑rule body).
  • : control how Autoprefixer handles
    grid translations for the whole block:

    • : enable grid translations with autoplacement support.
    • : enable grid translations with autoplacement
      support disabled (alias for deprecated value ).
    • : disable all grid translations.

You can also use comments recursively:

@supports (transition: all) {a {}}

Note that comments that disable the whole block should not be featured in the same
block twice:

.do-not-do-this{transition1s;transformrotate(20deg);}

Gulp

Начнем с главного в нашей сборке.

Gulp — это наш фундамент, потому что он будет управлять всеми нашими задачами, другими словами, . Концепция задач очень проста. Название асинхронной javascript функции равно названию задачи, и работает она по принципу: берет данные, трансформирует их и записывает результат.

Как видим, все просто: называем нашу задачу , вызываем функцию , которая берет данные по определенному шаблону и передает данные по трубе (функция ). Внутри вызываем функцию плагина, которая трансформирует наши данные и результат передает функцию . — записывает результат по указанному пути.

С можно выстраивать любые цепочки.

В четвертой версии много чего изменилось, но на что нужно точно обратить внимание — это на и. Позже мы разберем параллельное выполнение задач

Как вы заметили, в примерах я экспортировал функции, в старом API использовали :

Больше не рекомендуется использовать .

Экспортирование функций позволяет разделять на публичные и приватные задачи.

  • — экспортируются из вашего gulpfile, что позволяет запускать их командой gulp.
  • — создаются для внутреннего использования, как правило, в составе или

Пару слов о шаблонах поиска файлов в функции .

  • — ищет файлы с расширением в папке
  • — ищет файлы с расширением во всех папках, которые в

Структура проекта

После того, как мы разобрались с фундаментом нашего проекта, начнем делать первые шаги. Проверяем, установлены ли и .

Создаем папку для нашего проекта. Внутри инициализируем npm
Ключ означает автоматические ответы вопрос по проекту.

Создадим три папки:

  • — оптимизированные файлы для использования на сервере
  • — рабочая папка, где будут храниться все наши исходники
  • — здесь будут храниться наши tasks

Еще добавим файл , чтобы системные файлы не попадали в репозиторий.
Папка задокументирована, потому что часто использую для демонстрации работы.

Не забудьте установить gulp:

4.0.0

Task system changes

  • replaced 3.x task system (orchestrator) with new task system (bach)
    • removed gulp.reset
    • removed 3 argument syntax for
    • should only be used when you will call the task with the CLI
    • added and methods for composing tasks. Everything must use these now.
    • added single argument syntax for which allows a named function to be used as the name of the task and task function.
    • added method for retrieving the task tree. Pass for an compatible node list.
    • added for setting custom registries.

CLI changes

  • split CLI out into a module if you want to save bandwidth/disk space. you can install the gulp CLI using either or , where gulp-cli is the smaller one (no module code included)
  • add flag to CLI to dump the whole tree out for other tools to consume
  • added flag to check the dependencies in package.json against the plugin blacklist.

vinyl/vinyl-fs changes

  • added which functions exactly like , but symlinks instead.
  • added param to and which allows better control over the mode of the destination folder that is created.
  • globs passed to will be evaluated in order, which means this is possible (exclude every JS file that starts with a b except bad.js)
  • performance for gulp.src has improved massively
  • added option to which lets you only match files that have been modified since a certain date (for incremental builds)
  • fixed not following symlinks
  • added option to which allows you to enable or disable overwriting of existing files

Использование Gulp

Давайте создадим задачу Gulp для минимизации одного из наших файлов JavaScript. Создайте файл с именем gulpfile.js. В нём будут определяться ваши задачи, которые запускаются с помощью команды gulp.

Добавьте следующие команды в ваш файл gulpfile.js:

Установите gulp-uglify через npm выполнив npm install —save-dev gulp-uglify, а затем запустите задачу через gulp minify. Предположим, у вас есть файл с именем app.js в папке js, новый app.js будет создан в папке build и содержать сжатую версию js/app.js.

Что на самом деле здесь происходит?

Мы делаем несколько вещей в нашем файле gulpfile.js. Вначале мы загружаем модули gulp и gulp-uglify:

Затем определяем задачу с именем minify, которая при запуске вызывает функцию, заданную в качестве второго аргумента:

В конце, и это самое сложное, мы определяем, что наша задача должна делать:

Если вы не знакомы с потоками, а большинство фронтенд-разработчиков с ними не знакомы, то код выше ничего вам не скажет.

Usage

Passing an options object:

var gulp =require('gulp');var cssUrls =require('gulp-css-urls');gulp.task('cssUrls',function(){returngulp.src('./src/*.css').pipe(cssUrls({      prepend'http://example.com',      append'?version=2',})).pipe(gulp.dest('./dist/'));});

Or passing a function:

var gulp =require('gulp');var cssUrls =require('gulp-css-urls');gulp.task('cssUrls',function(){returngulp.src('./src/*.css').pipe(cssUrls(function(url){return'http://example.com'+ url +'?version=2';},{      sourcemapstrue,})).pipe(gulp.dest('./dist/'));});

Should change:

div{background-imageurl("/images/lemonade.jpg");}

Into:

div{background-imageurl("http://example.com/images/lemonade.jpg?version=2");}

Шаг 7: Пожинаем плоды!

Другие плагины, которые могут быть полезны:

  • gulp-load-plugins: загружает все модули плагинов Gulp автоматически;
  • gulp-preprocess: простой препроцессор HTML и JavaScript;
  • gulp-less: плагин препроцессора Less CSS;
  • gulp-stylus: плагин препроцессора Stylus CSS;
  • gulp-size: отображает размеры файлов;
  • gulp-nodemon: использует nodemon для автоматического перезапуска приложений Node.js при их изменении.

Таски Gulp могут запускать любой JavaScript- код или модули Node.js. Они не обязательно должны быть плагинами. Например:

  • browser-sync: автоматически перезагружает ресурсы, когда происходят изменения;
  • del: удаляет файлы и папки (может очищать папку build в начале каждого запуска).

Преимущества Gulp:

  • множество плагинов;
  • конфигурация с использованием pipe легко читаема и понятна;
  • js можно адаптировать для использования в других проектах;
  • упрощает развертывание;

Полезные ссылки:

  • домашняя страница Gulp;
  • плагины Gulp;
  • домашняя страница npm.

После применения описанных выше процессов к простому сайту его общий вес уменьшился более чем на 50%.

Gulp – это отличный вариант для автоматического запуска заданий и упрощения процесса разработки.

Данная публикация представляет собой перевод статьи «An Introduction to Gulp.js» , подготовленной дружной командой проекта Интернет-технологии.ру

Sample gulpfile.js

This file is just a quick sample to give you a taste of what gulp does.

var gulp =require('gulp4');var less =require('gulp-less');var babel =require('gulp-babel');var concat =require('gulp-concat');var uglify =require('gulp-uglify');var rename =require('gulp-rename');var cleanCSS =require('gulp-clean-css');var del =require('del');var paths ={  styles{    src'src/styles/**/*.less',    dest'assets/styles/'},  scripts{    src'src/scripts/**/*.js',    dest'assets/scripts/'}};functionclean(){returndel('assets');}functionstyles(){returngulp.src(paths.styles.src).pipe(less()).pipe(cleanCSS()).pipe(rename({      basename'main',      suffix'.min'})).pipe(gulp.dest(paths.styles.dest));}functionscripts(){returngulp.src(paths.scripts.src,{ sourcemapstrue}).pipe(babel()).pipe(uglify()).pipe(concat('main.min.js')).pipe(gulp.dest(paths.scripts.dest));}functionwatch(){gulp.watch(paths.scripts.src, scripts);gulp.watch(paths.styles.src, styles);}exports.clean= clean;exports.styles= styles;exports.scripts= scripts;exports.watch= watch;var build =gulp.series(clean,gulp.parallel(styles, scripts));gulp.task('build', build);gulp.task('default', build);

License

The MIT License (MIT)

Copyright (c) 2015 Jack Scott

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the «Software»), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED «AS IS», WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Шаг 1: установите Node.js

Node.js можно загрузить для Windows, macOS и Linux с nodejs.org/download/. Доступны различные варианты платформы для установки из бинарных файлов, модульных сборщиков и Docker-образов.

Примечание: Node.js и Gulp работают в Windows, но некоторые плагины могут работать некорректно, если они зависят от собственных бинарных файлов Linux. Одним из вариантов решения проблемы в Windows 10 является подсистема Windows для Linux.

После установки запустите командную строку и введите следующую команду. Она позволит узнать номер версии:

node -v

Вскоре вы станете активно использовать npm – менеджер пакетов Node.js, который необходим для установки модулей. Узнайте номер его версии:

npm –v

Примечание: модули Node.js можно устанавливать глобально, чтобы они были доступны во всей ОС. Но большинство пользователей не будут иметь права на запись в глобальные библиотеки, если у команд npm не будет префикса sudo. Существует несколько вариантов, как исправить разрешения npm. Но можно изменить каталог по умолчанию. Например, в Ubuntu/Debian:

cd ~
  mkdir .node_modules_global
  npm config set prefix=$HOME/.node_modules_global
  npm install npm -g

Затем добавьте следующую строку в конце ~/.bashrc:

export PATH="$HOME/.node_modules_global/bin:$PATH"

Снова обновите:

source ~/.bashrc

gulp.src()

Функция gulp.src() берёт один или несколько файлов или массив и возвращает поток, который может быть передан в плагины.

Gulp использует node-glob для получения указанных файлов. Проще всего объяснить на примерах:

  • js/app.js Соответствует определённому файлу.
  • js/*.js Соответствует всем файлам, заканчивающихся на .js в папке js.
  • js/**/*.js Соответствует всем файлам с расширением .js в папке js и всех вложенных папках.
  • !js/app.js Исключает js/app.js из соответствия, что полезно если вы желаете выбрать все файлы в папке за исключением определённого файла.
  • *.+(js|css) Соответствует всем файлам, заканчивающихся на .js или .css.

Другие функции также доступны, но в Gulp они обычно не применяются. Посмотрите документацию Minimatch ради подробностей.

Предположим, у нас есть папка с именем js, содержащая файлы JavaScript, некоторые минимизированы, а некоторые нет. Мы хотим создать задачу по минимизации ещё не уменьшенных файлов. Чтобы сделать это, мы выбираем все файлы JavaScript в папке, за исключением всех файлов, оканчивающиеся на .min.js:

Incremental Builds

You can filter out unchanged files between runs of a task using
the function’s option and :

constpaths={...  images{    src'src/images/**/*.{jpg,jpeg,png}',    dest'build/img/'}}functionimages(){returngulp.src(paths.images.src,{sincegulp.lastRun(images)}).pipe(imagemin({optimizationLevel5})).pipe(gulp.dest(paths.images.dest));}functionwatch(){gulp.watch(paths.images.src, images);}

Task run times are saved in memory and are lost when gulp exits. It will only
save time during the task when running the task
for a second time.

If you want to compare modification time between files instead, we recommend these plugins:

functionimages(){var dest ='build/img';returngulp.src(paths.images).pipe(newer(dest)).pipe(imagemin({optimizationLevel5})).pipe(gulp.dest(dest));}

If you can’t simply filter out unchanged files, but need them in a later phase
of the stream, we recommend these plugins:

functionscripts(){returngulp.src(scriptsGlob).pipe(cache('scripts')).pipe(header('(function () {')).pipe(footer('})();')).pipe(remember('scripts')).pipe(concat('app.js')).pipe(gulp.dest('public/'))}

Потоки

Потоки позволяют пройти некоторым данным через ряд, как правило, небольших функций, которые модифицируют данные, а затем передают их следующей функции.

В приведённом выше примере функция gulp.src() получает строку, которая соответствует файлу или набору файлов, и создаёт поток объектов представляющих эти файлы. Затем они переходят (или перетекают) в функцию uglify(), которая принимает объекты файлов и возвращает новые объекты файлов с минимизированным исходником. Этот результат затем перетекает в функцию gulp.dest(), которая сохраняет изменённые файлы.

Вот что происходит в виде схемы:

Когда есть только одна задача, функция ничего не делает. Тем не менее, рассмотрим следующий код:

Чтобы запустить это самостоятельно, установите gulp, gulp-jshint, gulp-uglify и gulp-concat.

Эта задача берёт все файлы соответствующие js/*.js (иными словами все файлы JavaScript из папки js), запускает для них JSHint, выводит отчёт, минимизирует каждый файл, а затем объединяет их, сохраняя их в build/app.js. В виде схемы:

Если вы знакомы с Grunt, то заметите, что это довольно сильно отличается от того, как работает Grunt. Grunt не использует потоки. Вместо этого он берёт файлы, запускает одну задачу для каждого файла и сохраняет в новые файлы, повторяя весь процесс для каждой задачи. В результате множества обращений к файловой системе, Grunt работает медленнее, чем Gulp.

Для лучшего понимания потоков прочтите Stream Handbook.

Options

To not trigger the install use as CLI parameter when running or .

Type:

Default:

Use this option(s) to specify any arguments for any command, e.g:

var install =require("gulp-install");gulp.src(__dirname+'/templates/**').pipe(gulp.dest('')).pipe(install({    npm'--production',    bower{allowRoottrue},    pip'--target','.'}));

Type:

Default:

Use this option to add any command to be run for any file, e.g:

var install =require("gulp-install");gulp.src(__dirname+'/templates/**').pipe(gulp.dest('')).pipe(install({    commands{'package.json''yarn'},    yarn'--extra','--args','--here'}));

Type:

Default:

Set to if should be appended with the parameter when stream contains .

Example:

var install =require("gulp-install");gulp.src(__dirname+'/templates/**').pipe(gulp.dest('')).pipe(install({productiontrue}));

Type:

Default:

Set to if should be appended with the parameter when stream contains . Useful for skipping scripts with .

Example:

var install =require("gulp-install");gulp.src(__dirname+'/templates/**').pipe(gulp.dest('')).pipe(install({ignoreScriptstrue}));

Type:

Default:

Set to if should be appended with the parameter which will prevent optional dependencies from being installed.

Example:

var install =require("gulp-install");gulp.src(__dirname+'/templates/**').pipe(gulp.dest('')).pipe(install({noOptionaltrue}));

Type:

Default:

Set to if should be appended with the parameter when stream contains .

Example:

var install =require("gulp-install");gulp.src(__dirname+'/templates/**').pipe(gulp.dest('')).pipe(install({allowRoottrue}));

Type:

Default:

Specify additional arguments that will be passed to the install command(s).

Example:

var install =require("gulp-install");gulp.src(__dirname+'/templates/**').pipe(gulp.dest('')).pipe(install({      args'dev','--no-shrinkwrap'}));

Современная сборка 2020 для frontend. Gulp4 +10

  • 17.02.20 02:04


Den-V

#484714

Хабрахабр


Tutorial

4900

JavaScript, Node.JS, Разработка веб-сайтов, CSS, HTML

Начало

Посмотрев на календарь, я понял, что уже 2020, а посмотрев на свою сборку, которая была с 2018 года, я понял, что пора её менять. В этой статье мы разберем структуру проекта, плагины (минимальный набор функционала) и их новые возможности, которые добавились за такое большое время. Мы разберем все моменты, чтобы новичок мог себе скачать эту сборку и начать с ней работать.

Не только древность моей сборки мотивировала на эту статью, но и еще одна причина: мне больно смотреть, когда заходят на онлайн-сервисы для конвертации , минификации и других рутинных задач. Самое забавное — когда сделали мелкую правку, снова нужно проходить все круги ада копипаста.

Рекомендации по использованию

Компонентный подход к разработке сайтов

  • аждый БЭМ-блок имеет свою папку внутри 
  • папка одного БЭМ-блока содержит в себе один HTML-файл, один SCSS-файл и один JS-файл (если у блока используется скрипт)
    • HTML-файл блока импортируется в файл  (или в необходимый файл страницы, откуда будет вызываться блок)
    • SCSS-файл блока импортируется в файл 
    • JS-файл блока импортируется в 

Пример структуры папки с БЭМ-блоком:

Чтобы вручную не создавать соответствующие папку и файлы, достаточно в консоли прописать команду  — для создания папки БЭМ-блока, где  — имя БЭМ-блока

Сторонние библиотеки

  • все сторонние библиотеки устанавливаются в папку 
    • для их загрузки воспользуйтеcь командой 
    • для подключения JS-файлов библиотек импортируйте их в самом начале JS-файла БЭМ-блока (то есть тот БЭМ-блок, который использует скрипт), например:
    import $ from "jquery";
    • для подключения стилевых файлов библиотек импортируйте их в файл 
    • JS-файлы и стилевые файлы библиотек самостоятельно изменять нельзя

️ Если в вашем проекте используется несколько библиотек, которые необходимо подключать на нескольких страницах, во избежании ошибок нужно:

  • по пути  создать папку 
  • в папке  создать js-файл для страницы, например, , и импортировать туда библиотеку, которая будет использоваться только на этой странице
  • в файле  в точку входа добавить js-файлы страниц, пример:
entry {
    main "./src/js/index.js",
    pageA "./src/js/import/pages/pageA.js",
    pageB "./src/js/import/pages/pageB.js"
}

подключить скомпилированные js-файлы на необходимых страницах

CSS-сетка smart-grid

SCSS

.items{
    @include row-flex();
    @include md(justify-content, center);
 
    .item{
        @include col();
        @include size(3);
        @include size-md(5);
        @include size-xs(10);
    }
}

Результат

.items {
    display: flex;
    flex-wrap: wrap;
    margin-left: -15px;
    margin-right: -15px;
}
.items .item {
    box-sizing: border-box;
    margin-left: 15px;
    margin-right: 15px;
    word-wrap: break-word;
    width: calc(100%  12 * 3 - 30px);
}
@media screen and (max-width: 992px) {
    .items {
        justify-content: center;
    }
    .items .item {
        width: calc(100%  12 * 5 - 30px);
    }
}
@media screen and (max-width: 576px) {
    .items .item {
        width: calc(100%  12 * 10 - 30px);
    }
} 
Ссылка на основную публикацию