Gulp-replace not working with SCSS - gulp

I tried
gulp.task('sass', function () {
return gulp.src(['./scss/*.scss'])
.pipe($.replace(/_VIEWPORT_WIDTH_/g,conf.project.viewport||640))
.pipe($.sass({errLogToConsole: true}))
.pipe(gulp.dest('./resources/css/'));
});
still not working.
pipe replace after SCSS will work,but SCSS can not do math during the process.
gulp.task('sass', function () {
return gulp.src(['./scss/*.scss'])
.pipe($.sass({errLogToConsole: true}))
.pipe($.replace(/_VIEWPORT_WIDTH_/g,conf.project.viewport||640))
.pipe(gulp.dest('./resources/css/'));
});
any suggestion?I know there is an ugly way,but that's too Grunt
gulp.task('sass', function () {
return gulp.src(['./scss/*.scss'],{buffer:true})
.pipe($.replace(/_VIEWPORT_WIDTH_/g,conf.project.viewport||640))
.pipe(gulp.dest('./tmp/scss/'))
.pipe($.sass({errLogToConsole: true}))
.pipe(gulp.dest('./resources/css/')).on('end',function(){
del(['./tmp/scss/'], {force: true});
});
});

It's because the latest version of gulp-sass (and perhaps every previous version) has a serious bug / design flaw -- it discards changes to file contents from earlier in the pipeline. I reported this at dlmanning/gulp-sass#158 and it's supposed to be fixed in the next major version (v2) I believe.

Related

gulpfile.js - version 3 to 4 migration

Years back I setup vs code to somewhat replicate the current methods I was using to design my sites (using standalone apps). I decided at the time I would just stick to what I was using. Since those apps are no longer maintained I am coming across compiling issues now - the time has come to make the jump.
I am having trouble with my gulpfile.js which is from back when I originally tried this all out. I saved it in case I needed to return to using vs code. Problem is apparently this format no longer works because gulp has updated. All of this is basically foreign to me right now and while I understand what things are doing I don't understand enough to modify this to the current method for gulp 4^.
Any chance someone can help me out with this one? I've looked at the guides about series and parallel and so on. I guess it's easier for me to understand by looking at a working example.
my old gulpfile.js
var gulp = require('gulp');
var sass = require('gulp-sass');
var cleanCSS = require('gulp-clean-css');
var uglify = require('gulp-uglify');
//processes the scss files in this folder
//minimizes them
gulp.task('sass', function () {
return gulp.src('_config/scss/**/*.scss')
.pipe(sass().on('error', sass.logError))
.pipe(cleanCSS())
.pipe(gulp.dest('assets/css'));
});
//minifies all js files in this folder
gulp.task('js', function () {
return gulp.src('_config/js/**/*.js')
.pipe(uglify())
.pipe(gulp.dest('assets/js'));
});
//minifies all js files in this folder
gulp.task('scripts', function () {
return gulp.src('_config/scripts/**/*.js')
.pipe(uglify())
.pipe(gulp.dest('assets/scripts'));
});
//creates 'watchers' that run tasks on specific activities
gulp.task('watch', function () {
gulp.watch('_config/scss/**/*.scss', ['sass']);
gulp.watch('_config/js/**/*.js', ['js']);
gulp.watch('_config/scripts/**/*.js', ['scripts']);
gulp.watch('_config/img/**/*', ['img']);
});
//this is the default task that runs everything
gulp.task('default', ['sass', 'js', 'scripts', 'watch']);
You are not that far from where you need to be. Change this code:
gulp.task('watch', function () {
gulp.watch('_config/scss/**/*.scss', ['sass']);
gulp.watch('_config/js/**/*.js', ['js']);
gulp.watch('_config/scripts/**/*.js', ['scripts']);
gulp.watch('_config/img/**/*', ['img']);
});
gulp.task('default', ['sass', 'js', 'scripts', 'watch']);
to
gulp.task('watch', function () {
gulp.watch('_config/scss/**/*.scss', gulp.series('sass'));
gulp.watch('_config/js/**/*.js', gulp.series('js'));
gulp.watch('_config/scripts/**/*.js', gulp.series('scripts'));
gulp.watch('_config/img/**/*', gulp.series('img'));
});
gulp.task('default', gulp.series('sass', 'js', 'scripts', 'watch'));
gulp.task now has this signature: gulp.task([taskName], taskFunction)
Before gulp v3 used an array of tasks as the second argument. gulp v4 uses a function, like gulp.series() or gulp.parallel(), as the second argument. And gulp.series() takes a list of tasks as its arguments. Since you used the gulp.task() method to create your tasks, the task names in series should appear as strings, like 'sass', 'js', etc.
Note: The preferred way to create tasks in v4 is as functions like:
function scripts() {
return gulp.src('_config/scripts/**/*.js')
.pipe(uglify())
.pipe(gulp.dest('assets/scripts'));
});
Then you would use those function names in series as gulp.series(scripts, js) - not as strings. You should look into using this form of tasks.
gulp.watch() signature: gulp.watch(globs, [options], [task])
The [task] can be a single task name, like your 'sass' or a composed task, which just means one generated using series or parallel.
In your case, you are running only one task in each watch statement, so
gulp.watch('_config/scss/**/*.scss', 'sass');
should suffice. I showed them as composed tasks like:
gulp.watch('_config/scss/**/*.scss', gulp.series('sass'));
in case in the future you want to run more than one task upon a file change. In which case you could use something like:
gulp.watch('_config/scss/**/*.scss', gulp.series('sass', 'serve'));
for example.
Finally switch out gulp-uglify for gulp-terser. gulp-terser will handle es6 syntax that gulp-uglify cannot. gulp-terser

gulp less compile only changed file

i have problem, when i run gulp watch -> run task styles:build, and all of my less files was recompile. How i can compile only changed file?
gulp.task('styles:build', function () {
return gulp.src(pathes.src.styles)
.pipe(changed(pathes.build.styles), {extension: '.css'})
.pipe(print(function(filepath) {
return "➔ file was changed: " + filepath;
}))
.pipe(plumber())
.pipe(less({
plugins: [autoprefix, cleanCSSPlugin],
paths: ['./', 'web/styles']
}))
.pipe(gulp.dest(pathes.build.styles))
});
gulp.task('watch', function() {
gulp.watch(pathes.src.styles, ['styles:build'])
});
You need to modify the line below to add a closing parenthsis:
.pipe(changed(pathes.build.styles, {extension: '.css'}))
Also as I cautioned the first time the task is run it probably will pass through all files.
i think i found solution
just install lessChanged = require('gulp-less-changed')
and include him before less pipe
.pipe(lessChanged())
.pipe(less())

gulp stops server on error even with jshint included in gulpfile.js

I don't know why the server still stops whenever there's an error in my js files even though I have jshint in my gulpfile. I installed jshint and included it in my project because it reports errors in js files, but it's still failing. How can I fix this?
gulp.task('scripts', () => {
return gulp.src('assets/js/src/*.js')
.pipe(jshint())
.pipe(jshint.reporter('jshint-stylish', {beep: true}))
.pipe(concat('main.js'))
.pipe(gulp.dest('assets/js/build/'))
.pipe(uglify())
.pipe(gulp.dest('assets/js/'))
.pipe(browserSync.stream({stream: true}));
});
gulp-jshint does what you says it does: it reports errors in JavaScript files. Nothing more, nothing less. It doesn't prevent defective JavaScript files from reaching later pipe stages like uglify() (which throws up and thus stops your server if there's any error in a JavaScript file).
If you want to prevent defective JavaScript files from wrecking your server, you need to put all the jshint stuff into it's own task and make sure that task fails when any JavaScript file has an error:
gulp.task('jshint', () => {
return gulp.src('assets/js/src/*.js')
.pipe(jshint())
.pipe(jshint.reporter('jshint-stylish', {beep: true}))
.pipe(jshint.reporter('fail'))
});
Then you need to make your scripts task depend on that jshint task:
gulp.task('scripts', ['jshint'], () => {
return gulp.src('assets/js/src/*.js')
.pipe(concat('main.js'))
.pipe(gulp.dest('assets/js/build/'))
.pipe(uglify())
.pipe(gulp.dest('assets/js/'))
.pipe(browserSync.stream({stream: true}));
});
Now your scripts task will only run when the jshint task was successful. If any JavaScript file was defective jshint will output the error to the console while your server continues to run using the last good version of your JavaScript.
The simplest fix would be to use gulp-plumber to handle the error a little more gracefully:
var plumber = require("gulp-plumber");
gulp.task('scripts', () => {
return gulp.src('assets/js/src/*.js')
.pipe(plumber())
.pipe(jshint())
.pipe(jshint.reporter('jshint-stylish', {beep: true}))
.pipe(concat('main.js'))
.pipe(gulp.dest('assets/js/build/'))
.pipe(uglify())
.pipe(gulp.dest('assets/js/'))
.pipe(browserSync.stream({stream: true}));
});
Personally, I don't like that solution because it will prevent your minified file from being updated. Here's what I would recommend:
var jshintSuccess = function (file) {
return file.jshint.success;
}
gulp.task('scripts', () => {
return gulp.src('assets/js/src/*.js')
.pipe(sourcemaps.init())
.pipe(jshint())
.pipe(jshint.reporter('jshint-stylish', {
beep: true
}))
.pipe(gulpif(jshintSuccess, uglify()))
.pipe(concat('main.js'))
.pipe(sourcemaps.write('maps'))
.pipe(gulp.dest('assets/js/'))
.pipe(browserSync.stream({
stream: true
}));
});
First, notice that I'm not writing to multiple destinations. Instead, I'm using sourcemaps so that you don't need unminified code. Second, I'm using gulp-if to conditionally pipe your code through uglify based on the results of jshint. Code with errors will bypass uglify so that it still makes it into to your destination file.
Now, you can inspect and debug it with the developer tools.
Note: I recommend this for local development only. I wouldn't connect this to a continuous integration pipeline because you'll only want good code to make it into production. Either set up a different task for that or add another gulp-if condition to prevent broken code from building based on environment variables.

Controlling the order in which Gulp concats javascript files

I am having trouble controlling the order in which my javascript files are concatenated with Gulp. I've tried gulp-order but it doesn't seem to work. I just started using Gulp, so I am sure (hoping) this is an easy solution. I did notice some SO posts on renaming the files with numbers...I do not want to do this. Thank you.
gulp.task('scripts', function () {
gulp.src('starter_app/static/backoffice/js/vendor/*.js')
.pipe(order([
'excanvas.js',
'respond.js',
'js.cookie.min.js',
'bootstrap-hover-dropdown.min.js',
'jquery.slimscroll.min.js',
'jquery.blockui.min.js',
'jquery.uniform.min.js',
'bootstrap-switch.min.js',
'app.min.js',
'dashboard.min.js',
'layout.min.js',
'quick-sidebar.min.js'
]))
.pipe(concat('scripts.js'))
.pipe(gulp.dest('starter_app/static/backoffice/js'));
});
You can do:
gulp.task('scripts', function () {
gulp.src([
'excanvas.js',
'respond.js',
'js.cookie.min.js',
'bootstrap-hover-dropdown.min.js',
'jquery.slimscroll.min.js',
'jquery.blockui.min.js',
'jquery.uniform.min.js',
'bootstrap-switch.min.js',
'app.min.js',
'dashboard.min.js',
'layout.min.js',
'quick-sidebar.min.js'
], {
cwd: 'starter_app/static/backoffice/js/vendor'
})
.pipe(concat('scripts.js'))
.pipe(gulp.dest('starter_app/static/backoffice/js'));
});

Gulp-sass how to change dest output

I'm trying to set a shopify dev workflow, and i'm stuck in a problem. How can i change the dest() output in gulp-sass to use .liquid files in the assets folder?
gulp.task('sass', function() {
gulp.src('stylesheets/*.scss')
.pipe(sass().on('error', sass.logError))
.pipe(gulp.dest('./assets/'));
});
I want to get as output something like main.css.liquid, so i can use the .liquid methods.
Is that possible?
There's a good thread about it # Gulp. As said it seems that gulp-rename may be a great fit.
In your case, you can change your code to:
gulp.task('sass', function() {
gulp.src('stylesheets/*.scss')
.pipe(sass().on('error', sass.logError))
.pipe(gulp.rename('destinationpath/yourfile.liquid'));
.pipe(gulp.dest('./assets/'));
});