Страницы

Поиск по вопросам

суббота, 4 января 2020 г.

Организация таска компиляции sass в Gulp

#gulp #компиляция #sass #gulp_sass


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

Структура проекта следующая:   

   dev  
     |--component1  // компоненты проекта
     |--component2  
     .....
     |--scss  
       |--base  // базовые подключаемые файлы с миксинами и прочим
       |--elements  // общие для всех страниц элементы оформления (кнопки и т.д.)
       |--componets    
         |--component1     
           |--style.scss     
         |--component2     
          ........    
       |--main.scss    


Собирается все это так:   

app  
   |--component1  // компоненты 
     |--css       // отдельные стили каждого компонента
       |--style.css   
   |--component2   
    .....     
   |--css  // главный css
     |--style.css    


Таск sass для всего этого добра:   

gulp.task('sass', function() {
    return combiner(
        gulp.src([
                    'dev/scss/main.scss' ,
                    'dev/scss/project components/**/*.scss'
        ]),
        debug({title: 'src'}),
        gulpIf(isDevelop, sourcemaps.init()),
        sass( sassOptions ),
        autoprefixer({
                browsers: ['last 4 versions']
            }),
        gulpIf(isDevelop, sourcemaps.write()),
        rename(function (path) {
            path.dirname += '/css';
            path.basename = 'main' ? 'style' : path.basename;
        }),
        gulpIf(!isDevelop, cleanCSS()),
        gulp.dest('app'),
        debug({title: 'dest'})
    ).on('error', notify.onError(function(err){
            return {
                title: 'sass',
                message: err.message
            }
    }))

});


Сейчас при выполнении задачи в папку app помещаются все файлы из папок компонентов
и главный файл стилей, независимо от того модифицировались они или нет. Хотелось бы
что-бы манипуляции производились только с модифицируемыми файлами + непонятен вопрос
с кешированием подключаемых через @import файлов.  

Так же вопрос добавления удаления файлов и переписывания урлов к файлам подключаемым
через css (картинки, шрифты...)    

Буду признателен за подробные ответы и советы по организации таска.
    


Ответы

Ответ 1



В идеале сборка должна быть такая, чтобы скомпилированный файлы, которые будут отдаваться пользователю, лежали отдельно от исходников и их можно было спокойно удалить при необходимости. К тому же, это позволит делать дополнительные оптимизации с исходными файлами и не менять пути в сборке. Организация стилей В целом, вы отлично организовали сборку стилей: организовали переменные окружения, добавили афтопрефиксер. Однако я бы посоветовал создать два отдельных таска для разного окружения, чтобы исключить дополнительные условия. К тому же, можно было бы в качестве путей добавить лишь 'dev/scss/main.scss' и в нем же делать @import'ы к остальным файлам. Также бы посоветовал добавить livereload(), чтобы при изменении файлов ваш локальный сервер автоматически подгружал все изменения. Также не пойму, как вы бы хотели, чтобы манипуляции производились только с модифицируемыми файлами. Если вы компилируете все scss-файлы в один main.css, то операции будут производиться над всем main.css, уже после сборки. Если вы хотите, чтобы манипуляции производились лишь с тем файлом, который вы меняете, нужно каждый из этих файлов подключать к документу и не объединять при разработке. Организация картинок Я бы посоветовал хранить исходные картинки отдельно и переносить их при компиляции в папку сборки (назовем ее public). Кроме обычного переноса было бы хорошо эти картинки сжать: К примеру, картинки можно легко сжать без потери качества только за счет удаление exif-данных. На реальном сайте можно сократить размер картинок в среднем на 70%, что на современном сайте равняется примерно 4 МБ. Пример на gulp: var gulp = require('gulp'), imagemin = require('gulp-imagemin'), imageminJR = require('imagemin-jpeg-recompress'), imageminSvgo = require('imagemin-svgo'); // Optimizing images gulp.task('imagemin', function() { gulp.src('./img/**/*') .pipe(imagemin([ imageminJR({ method: 'ms-ssim' }), imageminSvgo({ plugins: [ {removeViewBox: false} ] }) ])) .pipe(gulp.dest('./public/img/')) }); А для браузеров, которые понимают легковесный формат webp (формат разработан Google), можно сделать еще такой вариант изображений: var gulp = require('gulp'), webp = require('gulp-webp'); // Generate Webp gulp.task('webp', function() { gulp.src('./img/**/*') .pipe(webp()) .pipe(gulp.dest('./public/img/')) }); Организация шрифтов Тоже самое касается шрифтов, однако их нужно лишь перемещать в public: // Replace fonts gulp.task('fonts', function () { gulp.src('./fonts/text-font/*') .pipe(gulp.dest('./public/fonts/')) }); Создание иконочного шрифта Предпочтительней было бы использование иконичного шрифта вместо картинок-спрайтов. И у этого метода есть ряд преимуществ: Более меньший вес шрифта, чем спрайта; Гибкость стилизации через CSS; Меньший вес CSS; Гибкий размер и ненадобность создание версий для Retina-дисплеев. Для генерации иконочного шрифта я бы посоветовал такую комбинацию: // Generate icon font gulp.task('iconfont', function() { var fontName = 'icon-font', cssClass = 'i'; // Исходные SVG-файлы gulp.src(['./fonts/icon-font/*.svg']) .pipe(iconfontCss({ fontName: fontName, cssClass: cssClass, path: './styl/mixins/icon-font.styl', targetPath: '../../styl/components/font/icon-font.styl', fontPath: '../fonts/' })) .pipe(iconfont({ fontName: fontName, prependUnicode: true, normalize: true, formats: ['svg','ttf','woff','woff2'] })) .pipe(gulp.dest('./public/fonts/')); }); Миски для стилей, который берется из этой строки path: './styl/mixins/icon-font.styl' будет выглядеть так: @font-face font-family "<%= fontName %>" src: url('<%= fontPath %><%= fontName %>.woff2') format('woff2'), url('<%= fontPath %><%= fontName %>.woff') format('woff'), url('<%= fontPath %><%= fontName %>.ttf') format('truetype'), url('<%= fontPath %><%= fontName %>.svg#<%= fontName %>') format('svg') [class*="i-"] position relative display inline-block width 1em height 1em &:before font 14px '<%= fontName %>' font-size inherit text-rendering auto speak none font-variant normal text-transform none color inherit position absolute top 50% left 50% transform translate(-50%, -50%) <% _.each(glyphs, function(glyph) { %> .<%= cssClass %>-<%= glyph.fileName %>:before content "\<%= glyph.codePoint %>" <% }); %> После генерации шрифта все, что вам нужно будет сделать, это подключить сгенированный CSS к вашему сайту или инглудить его к главному CSS-файлу, а затем использовать таким образом:

Ответ 2



Для ускорения процесса компиляции в целом, можно начать пользоваться модулем gulp-load-plugins. При помощи него вам не придется подключать все плагины, даже если они вам не нужны в данный момент, достаточно подключать их во время выполнения определенного таска. Т. е. в обычном виде вы запускаете таск styles, а подключаются все плагины — от минификации картинок до бабель-транспайлера. Этот плагин автоматически собирает содержимое packages.json и обрезает часть gulp- для использования. В результате, например, использование gulp-uglify будет выглядеть так: const $ = require('gulp-load-plugins')() ... .pipe($.uglify({preserveComments: 'some'})) Вместо: const uglify = require('gulp-uglify'); ... .pipe(uglify({preserveComments: 'some'})) Для ускорения процесса компиляции в частности, а именно таска по обработке стилей, можно воспользоваться gulp-newer. Вот примерный код, которым можно воспользоваться. Обратите внимание на строчку .pipe($.newer('.tmp/styles')) и промежуточное сохранение в папку tmp после работы плагина SASS. Знак $ — это горячее подключение плагинов при помощи gulp-load-plugins. gulp.task('styles', () => { return gulp.src([ 'app/styles/**/*.scss', 'app/styles/**/*.css' ]) .pipe($.newer('.tmp/styles')) .pipe($.sass({ precision: 10, includePaths: require('node-bourbon').includePaths }).on('error', $.sass.logError)) .pipe($.rename({ suffix: '.min' })) .pipe(gulp.dest('.tmp/styles')) .pipe(gcmq()) .pipe($.if('*.css', $.cssnano({ discardUnused: false }))) .pipe($.autoprefixer({ browsers: "last 4 versions" })) .pipe($.size({title: 'styles'})) .pipe(gulp.dest('dist/styles')) .pipe(browserSync.stream({match: '**/*.css'})); }); «непонятен вопрос с кешированием подключаемых через @import файлов» — уточните, что именно вы имеете в виду. Пока что мне кажется, что эта часть никак не связана с галп-тасками. «Так же вопрос добавления удаления файлов и переписывания урлов к файлам подключаемым через css (картинки, шрифты...)» — аналогично, поясните что имеется в виду.

Комментариев нет:

Отправить комментарий