Gulp SASS, autoprefixer, minify and sourcemaps generate huge file - gulp

I'm experiencing strange behaviour using this Gulp configuration to minify my SASS files generating sourcemaps.
'use strict';
var PATH = {
SRC_DIR: 'src/',
SRC: {
IMG: 'img/',
INDEX: 'index.html',
JS: {
DIR: 'js/',
FILE: [
'app.js',
'**/*.js',
'controller/**/*.js',
'factory/**/*.js',
'directive/**/*.js',
'model/**/*.js'
]
},
SASS: 'sass/',
TEMPLATE: 'template/'
},
DEST_DIR: 'dist/',
DEST: {
CSS: {
DIR: 'css/',
FILE: 'full.css'
},
IMG: 'img/',
JS: {
DIR: 'js/',
FILE: 'full.js'
},
LIB: 'lib/',
TEMPLATE: 'template/',
}
};
var gulp = require('gulp'),
autoprefixer = require('gulp-autoprefixer'),
concat = require('gulp-concat'),
minifyCss = require('gulp-minify-css'),
rename = require('gulp-rename'),
sass = require('gulp-ruby-sass'),
sourcemaps = require('gulp-sourcemaps');
gulp.task('styles', function() {
return sass(PATH.SRC_DIR + PATH.SRC.SASS, {
sourcemap: true,
style: 'expanded'
})
.pipe(autoprefixer({
browsers: ['last 2 version', 'safari 5', 'ie 8', 'ie 9'],
cascade: true
}))
.pipe(concat(PATH.DEST.CSS.FILE))
.pipe(gulp.dest(PATH.DEST_DIR + PATH.DEST.CSS.DIR))
.pipe(rename({suffix: '.min'}))
.pipe(minifyCss())
.pipe(sourcemaps.write())
.pipe(gulp.dest(PATH.DEST_DIR + PATH.DEST.CSS.DIR));
});
gulp.task('watch', function() {
gulp.watch(PATH.SRC_DIR + PATH.SRC.SASS + '**/*.scss', ['styles']);
});
gulp.task('default', ['watch', 'styles']);
The first time I run this script using gulp it'll generate a correct full.min.css and it waits for changes in the SASS directory.
When you change something inside SASS files it'll trigger the watch and re-run the styles task, which will build a full.min.css.
You see the changes in the front-end but this minified file becomes bigger and bigger at every rebuild.
If I omit the sourcemaps inside styles task it seems to work fine.
The full.css file is always ok.
What am I missing here? Why the minified version keeps increasing its dimension?

Related

Gulp 4 browsersync does not refresh when changing .less file

Link to Github repo: https://github.com/Greatshock/Netcracker-Study-Course/blob/f9bfb413929feec51064a78abf1450845f867186
I have a file named base.less, where all the styles are #import-ed. When I run the gulpfile (npm run dev), everything is being built, the browser opens the page. However, when I'm changing the content of one of the imported stylesheet, browsersync just writes in the console File event [change] : dist/base.css and nothing happens (even base.css does not actually change). Note that if I change base.less directly by writing some style in it, everything works fine.
Here is my gulpfile.js. Can anyone see the mistake?
'use strict';
const gulp = require('gulp'),
del = require('del'),
autoprefixer = require('gulp-autoprefixer'),
less = require('gulp-less'),
cleanCSS = require('gulp-clean-css'),
gulpIf = require('gulp-if'),
sourceMaps = require('gulp-sourcemaps'),
browserSync = require('browser-sync').create();
const isDevelopment = !process.env.NODE_ENV || process.env.NODE_ENV == 'development';
gulp.task('less', () => {
return gulp.src('src/assets/themes/base/base.less')
.pipe(gulpIf(isDevelopment, sourceMaps.init()))
.pipe(less())
.on('error', onLessError)
.pipe(autoprefixer({
browsers: [
'last 2 versions',
'safari 5',
'ie 10',
'ie 11'
],
cascade: true
}))
.pipe(cleanCSS())
.pipe(gulpIf(isDevelopment, sourceMaps.write()))
.pipe(gulp.dest('prod'));
});
gulp.task('images', () => {
return gulp.src('src/assets/themes/base/images/**/*.*', {base: 'src/assets/themes/base', since: gulp.lastRun('images')})
.pipe(gulp.dest('prod'));
});
gulp.task('index', () => {
return gulp.src('src/index.html', {since: gulp.lastRun('index')})
.pipe(gulp.dest('prod'));
});
gulp.task('clean', () => {
return del('prod');
});
gulp.task('build', gulp.series('clean', gulp.parallel('less', 'images', 'index')));
gulp.task('watch', () => {
gulp.watch('src/assets/themes/base/**/*.less', gulp.series('less'));
gulp.watch('src/assets/themes/base/images/**/*.*', gulp.series('images'));
gulp.watch('src/index.html', gulp.series('index'));
});
gulp.task('serve', function() {
browserSync.init({
server: 'prod'
});
browserSync.watch('prod/**/*.*').on('change', browserSync.reload);
});
gulp.task('dev', gulp.series('build', gulp.parallel('watch', 'serve')));
/***HELPERS FUNCTIONS***/
function onLessError(error) {
console.error(error.message);
this.emit('end');
}
I don't like this hackaround because to me it says one of our plugins isn't working correctly (browser-sync) so we correct it with that broken plugin. I'd maybe try browserify instead.
gulp.task('serve', function() {
browserSync.init({
files: [
{
match: ['src/assets/themes/base/**/*.less'],
fn: function (event, file) {
this.reload()
}
}
],
server: 'prod'
});
browserSync.watch('prod/**/*.*').on('change', browserSync.reload);
});
edit - This could also be a dir issue where the src is different than the watch dir. src/assets/themes/base/**/*.less' should be src/assets/themes/**/*.less' or src/assets/themes/base/*.less' for a distinct folder.
Edit 2- gulp.watch('src/assets/themes/base/*.less', gulp.series('less')); reloads base.less when any other file is changed if added to the gulp command. :D

Watch for changes in subdirectories but target a single file as src in Gulp

I have the following gulp task:
gulp.task("stylePipe", function(){
var postcssPlugins = [
autoprefixer({browsers: ['last 2 version']}), // autoprefixer
cssnano() // css minifier
];
gulp.src("src/sass/*.scss")
.pipe(sourcemaps.init())
.pipe(plumber())
.pipe(sass().on("error", sass.logError)) // scan for errors
.pipe(postcss(postcssPlugins)) // runs postcss plugins listed above
.pipe(rename({ extname: '.min.css' }))
.pipe(sourcemaps.write('maps'))
.pipe(gulp.dest("dist/css")); // compile into dist
});
gulp.task("styleWatch", ["stylePipe"], browsersync.reload);
gulp.task("watch", function(){
browsersync({
server: {
baseDir: "dist/"
}
});
gulp.watch("src/sass/*.scss", ["styleWatch"]);
});
I want to watch for changes in all the subdirectories listed below
using only the main.scss as src in the gulp.src("src/sass/*.scss") (main.scss is the only file that should be preprocessed whenever there is a change in the subdirectories' files).
How can I accomplish this?
I simply modified
gulp.watch("src/sass/*.scss", ["styleWatch"]);
into
gulp.watch("src/sass/**/*.scss", ["styleWatch"]);

pug file compiled to html does not livereload

In my project folder, I have pug files that are located in src/pug/*.pug, one of those files is index.pug. When compiled to html, the compiled files are located in build/templates/*.html. In the serve task, in browsersync.init(), I changed the baseDir from ./ to build/templates/ because the compiled index.html is located there. The problem is, browsersync livereload does not work; I have to refresh the browser just to see the changes I make in index.pug.
Gulpfile.js
const gulp = require('gulp'),
sass = require('gulp-sass'),
pug = require('gulp-pug'),
uglify = require('gulp-uglify'),
plumber = require('gulp-plumber'),
imagemin = require('gulp-imagemin'),
concat = require('gulp-concat'),
autoprefixer = require('gulp-autoprefixer'),
browserSync = require('browser-sync');
gulp.task('templates', () => {
return gulp.src('src/pug/*.pug')
.pipe(plumber())
.pipe(pug({pretty: true}))
.pipe(gulp.dest('build/templates/'))
.pipe(browserSync.stream({stream: true}));
});
gulp.task('styles', () => {
return gulp.src('src/sass/**/*.sass')
.pipe(plumber())
.pipe(sass({outputStyle: 'compressed'}).on('error', sass.logError))
.pipe(autoprefixer('last 2 version', 'safari 5', 'ie 8', 'ie 9', 'opera 12.1', 'ios 6', 'android 4'))
.pipe(gulp.dest('build/css/all/'))
.pipe(concat('style.css'))
.pipe(gulp.dest('build/css/'))
.pipe(browserSync.stream({stream: true}));
});
gulp.task('scripts', () => {
return gulp.src('src/js/*.js')
.pipe(plumber())
.pipe(concat('script.js'))
.pipe(gulp.dest('build/js/'))
.pipe(browserSync.stream({stream: true}));
});
gulp.task('imagemin', () => {
gulp.src('assets/img/src/**/*')
.pipe(imagemin())
.pipe(gulp.dest('assets/img/dist/'));
});
gulp.task('serve', ['templates', 'styles', 'scripts'], () => {
browserSync.init({
server: {
baseDir: 'build/templates/'
},
notify: false
});
gulp.watch('src/pug/*.pug', ['templates']);
gulp.watch('src/sass/**/*.sass', ['styles']);
gulp.watch('src/js/*.js', ['scripts']);
gulp.watch('build/templates/index.html').on('change', browserSync.reload);
});
gulp.task('default', ['imagemin', 'serve']);
Can someone help me fix this?
Not sure why that doesn't work, but I have compared your build file to the official docs, and I came across this approach from the docs: Instead of watching the HTML files, it watches the source (pug files in your case) and calls browserSync.reload after that source compilation task has completed. In your case, the pug line would be replaced by something like this:
gulp.watch('src/pug/*.pug', ['templates-watch']);
And you would create a new task, called templates-watch, that would be defined as follows:
gulp.task('templates-watch', ['templates'], function (done) {
browserSync.reload();
done();
});

Gulp configuration not working

I'm trying to run Gulp to minify CSS, JS and move all the static stuffs (template, font, img) into build folder.
My project directory structure:
- project
|- gulpfile.js
|- package.json
|- src
||- font
||- img
||- js
||- sass
||- template
|- build
||- css
||- font
||- img
||- js
||- template
My gulpfile.js:
var PATH = {
SRC: {
SASS: 'src/sass/',
JS: 'src/js/',
TEMPLATE: 'src/template/',
},
DEST: {
CSS: 'build/css/',
JS: 'build/js/',
TEMPLATE: 'build/template/',
}
};
var gulp = require('gulp'),
autoprefixer = require('gulp-autoprefixer'),
concat = require('gulp-concat'),
minifyCss = require('gulp-minify-css'),
rename = require('gulp-rename'),
sass = require('gulp-ruby-sass'),
uglify = require('gulp-uglify');
gulp.task('compress', function() {
return gulp.src(PATH.SRC.JS + '*.js')
.pipe(concat('all.js'))
.pipe(uglify())
.pipe(gulp.dest(PATH.DEST.JS))
.pipe(rename({suffix: '.min'}))
.pipe(gulp.dest(PATH.DEST.JS));
});
gulp.task('styles', function() {
return gulp.src(PATH.SRC.SASS + '*.scss')
.pipe(sass(PATH.SRC.SASS, { style: 'expanded' }))
.pipe(autoprefixer({
browsers: ['last 2 version', 'safari 5', 'ie 8', 'ie 9'],
cascade: true
}))
.pipe(concat('all.css'))
.pipe(gulp.dest(PATH.DEST.CSS))
.pipe(rename({suffix: '.min'}))
.pipe(minifyCss())
.pipe(gulp.dest(PATH.DEST.CSS));
});
gulp.task('watch', function() {
gulp.watch(PATH.SRC.SASS + '*.scss', ['styles']);
gulp.watch(PATH.SRC.JS + '*.js', ['compress']);
});
gulp.task('default', ['watch', 'styles', 'compress']);
When I run gulp or gulp watch I get this error:
/project/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/readable-stream/lib/_stream_readable.js:623
var written = dest.write(chunk);
^
TypeError: undefined is not a function
at write (/project/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/readable-stream/lib/_stream_readable.js:623:24)
at flow (/project/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/readable-stream/lib/_stream_readable.js:632:7)
at DestroyableTransform.pipeOnReadable (/project/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/readable-stream/lib/_stream_readable.js:664:5)
at DestroyableTransform.emit (events.js:104:17)
at emitReadable_ (/project/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/readable-stream/lib/_stream_readable.js:448:10)
at emitReadable (/project/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/readable-stream/lib/_stream_readable.js:444:5)
at readableAddChunk (/project/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/readable-stream/lib/_stream_readable.js:187:9)
at DestroyableTransform.Readable.push (/project/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/readable-stream/lib/_stream_readable.js:149:10)
at DestroyableTransform.Transform.push (/project/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/readable-stream/lib/_stream_transform.js:145:32)
at afterTransform (/project/node_modules/gulp/node_modules/vinyl-fs/node_modules/through2/node_modules/readable-stream/lib/_stream_transform.js:101:12)
How can I fix this?
gulp-ruby-sass changed it's API recently. So you can't pipe something through to the Sass task, but rather need to start with it. Much like browserify does. gulp-ruby-sass creates a stream, though, so the rest of the pipe should work fine:
gulp.task('styles', function() {
return sass(PATH.SRC.SASS, { style: 'expanded' })
.pipe(autoprefixer({
browsers: ['last 2 version', 'safari 5', 'ie 8', 'ie 9'],
cascade: true
}))
.pipe(concat('all.css'))
.pipe(gulp.dest(PATH.DEST.CSS))
.pipe(rename({suffix: '.min'}))
.pipe(minifyCss())
.pipe(gulp.dest(PATH.DEST.CSS));
});

how can i change my gulp file so that it runs build task whenever there's a change in the codebase?

Currently I've this gulp, everytime I make a change in the application to view the changes I've to run gulp build, how can i improve this gulp file by adding a watch task so that it automatically detects that a change has been introduces somewhere in the js folder / in html files and it would automatically run the build task for me.
var gulp = require('gulp'),
csso = require('gulp-csso'),
uglify = require('gulp-uglify'),
concat = require('gulp-concat'),
ngAnnotate = require('gulp-ng-annotate'),
minifyHtml = require("gulp-minify-html"),
ngHtml2Js = require('gulp-ng-html2js');
gulp.task('build', function () {
gulp.src(['../css/bootstrap_min.css', '../css/inputs.css', '../css/main.css',
'../css/recording.css','../css/images.css','../css/responsive.css','../css/calendar.css'])
.pipe(concat('index.min.css'))
.pipe(csso())
.pipe(gulp.dest('../css/'));
gulp.src(['../lib/date.js', '../lib/angular/angular-1.2.17.js','../lib/angular/angular-resource.js',
'../lib/ui-bootstrap-tpls-0.11.0.js','../lib/angular-ui-router.js',
'../lib/underscore.min.js','../lib/sortable.js','../lib/localize.js','../lib/bindonce.min.js',
'../lib/screenfull.js', '../lib/zeroclipboard.min.js'])
.pipe(concat('libs.min.js'))
.pipe(ngAnnotate())
.pipe(uglify())
.pipe(gulp.dest('../lib'));
gulp.src(['../js/app.js','../js/services.js','../js/controllers.js','../js/filters.js','../js/directives.js'])
.pipe(concat('index.min.js'))
.pipe(ngAnnotate())
.pipe(uglify())
.pipe(gulp.dest('../js'));
gulp.src("../partials/*.html")
.pipe(minifyHtml({
empty: true,
spare: true,
quotes: true
}))
.pipe(ngHtml2Js({
moduleName: "Partials",
prefix: "partials/"
}))
.pipe(concat("partials.min.js"))
.pipe(uglify())
.pipe(gulp.dest("../js"));
});
gulp.task('partials', function () {
gulp.src("../partials/*.html")
.pipe(minifyHtml({
empty: true,
spare: true,
quotes: true
}))
.pipe(ngHtml2Js({
moduleName: "Partials",
prefix: "partials/"
}))
.pipe(concat("partials.min.js"))
.pipe(uglify())
.pipe(gulp.dest("../js"));
});
You can just add watch task like this
gulp.task('watch', function() {
gulp.watch('../js/**/*.js', ['build']);
gulp.watch('../css/**/*.css', ['build']);
gulp.watch('../partials/**/*.html', ['build']);
})
Hope this help!
The other answer works for older versions of gulp. The syntax changed in version 4.0.
gulp.task('watch', function() {
gulp.watch('../js/**/*.js', gulp.series('build'));
gulp.watch('../css/**/*.css', gulp.series('build'));
gulp.watch('../partials/**/*.html', gulp.series('build'));
})