I just running my gulp task recently, but when try running a task such as sass, it didn't affect anything to the file source. Actually the task is running on CLI, but nothing changes. I'm using templating style to my function, and if I change it to a normal writing path(src/../..), the task is running well. Can somebody explain this, please?
const sourceAssetsCss = 'src/assets/css';
const sourceAssetsScss = 'src/assets/scss';
***// Compile SCSS to CSS src developer***
function sassRun() {
var prefix = [autoprefixer({
overrideBrowserslist: ['last 3 version']
})];
return gulp
.src(sourceAssetsScss + '/*scss')
.pipe(sourcemaps.init())
.pipe(plumber())
.pipe(sass({
outputStyle: 'nested'
}).on('error', sass.logError))
.pipe(postcss(prefix))
.pipe(plumber.stop())
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest(`${sourceAssetsCss}`))
.pipe(notify('sass successfully compiled'));
}
Related
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
I'm tryng to create a new gulp task to run into my application and look for all '.fragment.sass' files.
I wrote:
gulp.task('sassFragments', () => {
return gulp
.src('./src/**/*.fragment.sass')
.pipe(debug())
.pipe(sassGlob())
.pipe(sass({ outputStyle: 'expanded' })).on('error', sass.logError)
.pipe(concat('fragments_style.css'))
.pipe(gulp.dest('./build/assets/css'))
.pipe(browserSync.reload({ stream: true }));
})
but no fragments_style.css is created in /build/assets/css folder.
I have another task which does similar using src('./src/**/*.sass') to generate a style.css file and works great!
I think there is a issue with .src method, that is not matching this '.fragment.sass' pattern.
Can anyone help me?
Gulp version: 3.9.1
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.
So, Autoprefixer has been bugging me to use the updated postcss version so I am trying to update my Gulp file.
The problem is all the examples do not integrate Sass as the first step; I use gulp-ruby-sass.
If I run my sass task on my sass directory (there are 2 scss files I need to process in there), this works and outputs 2 css files in the dest directory:
gulp.task('sass', function() {
return sass('./app/assets/sass')
.on('error', function(err) {
console.error('Error!', err.message);
})
.pipe(gulp.dest('./app/assets/css'))
.pipe(reload({
stream: true
}));
});
But my question is how to integrate the next part, to pass the CSS through autoprefixer and generate sourcemaps? If I run this next in a sequence, this blows up with object is not a function errors:
gulp.task('autoprefixer', function() {
return gulp.src('./app/assets/css/')
.pipe(sourcemaps.init())
.pipe(postcss([autoprefixer({
browsers: ['last 2 versions']
})]))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest('./app/assets/css'));
});
I was trying to run them as a sequence, but would rather integrate them:
gulp.task('styles', function() {
runSequence('sass', 'autoprefixer');
});
I just cannot put together the pipe that gets ruby-sass, autoprefixer, and sourcemaps to all work together.
UPDATE:
OK, even if I decide to keep the task separated (as suggested below by #patrick-kostjens), when I run the Autoprefixer task I get this error:
[08:56:38] Starting 'autoprefixer'...
events.js:72
throw er; // Unhandled 'error' event
^
TypeError: Cannot call method 'toString' of null
at new Input (/Users/stevelombardi/github/designsystem/node_modules/gulp-postcss/node_modules/postcss/lib/input.js:29:24)
at Object.parse [as default] (/Users/stevelombardi/github/designsystem/node_modules/gulp-postcss/node_modules/postcss/lib/parse.js:17:17)
at new LazyResult (/Users/stevelombardi/github/designsystem/node_modules/gulp-postcss/node_modules/postcss/lib/lazy-result.js:54:42)
at Processor.process (/Users/stevelombardi/github/designsystem/node_modules/gulp-postcss/node_modules/postcss/lib/processor.js:30:16)
at Transform.stream._transform (/Users/stevelombardi/github/designsystem/node_modules/gulp-postcss/index.js:44:8)
at Transform._read (_stream_transform.js:179:10)
at Transform._write (_stream_transform.js:167:12)
at doWrite (_stream_writable.js:223:10)
at writeOrBuffer (_stream_writable.js:213:5)
at Transform.Writable.write (_stream_writable.js:180:11)
at write (/Users/stevelombardi/github/designsystem/node_modules/gulp-sourcemaps/node_modules/through2/node_modules/readable-stream/lib/_stream_readable.js:623:24)
at flow (/Users/stevelombardi/github/designsystem/node_modules/gulp-sourcemaps/node_modules/through2/node_modules/readable-stream/lib/_stream_readable.js:632:7)
at DestroyableTransform.pipeOnReadable (/Users/stevelombardi/github/designsystem/node_modules/gulp-sourcemaps/node_modules/through2/node_modules/readable-stream/lib/_stream_readable.js:664:5)
at DestroyableTransform.EventEmitter.emit (events.js:92:17)
at emitReadable_ (/Users/stevelombardi/github/designsystem/node_modules/gulp-sourcemaps/node_modules/through2/node_modules/readable-stream/lib/_stream_readable.js:448:10)
at emitReadable (/Users/stevelombardi/github/designsystem/node_modules/gulp-sourcemaps/node_modules/through2/node_modules/readable-stream/lib/_stream_readable.js:444:5)
And I tried autoprefixer = autoprefixer-core as suggested.
Personally, I would make the sass task a dependency of autoprefixer by declaring the autoprefixer task as follows:
gulp.task('autoprefixer', ['sass'], function() {
// Your current autoprefixer code here.
});
You can then simply run the autoprefixer task.
If you really want to integrate them into one task (even though the tasks do two separate things) you can try something like this:
gulp.task('autoprefixer', function() {
return es.concat(
gulp.src('./app/assets/css/')
.pipe(sourcemaps.init())
.pipe(postcss([autoprefixer({
browsers: ['last 2 versions']
})]))
.pipe(sourcemaps.write('.'))
,
sass('./app/assets/sass')
.on('error', function(err) {
console.error('Error!', err.message);
}))
.pipe(gulp.dest('./app/assets/css'));
});
Do not forget to define es as require('event-stream').
How are you including the autoprefixer requirement? This doesn't work for me:
var autoprefixer = require('gulp-autoprefixer');
This does work:
var autoprefixer = require('autoprefixer-core');
Try importing autoprefixer instead. I couldn't get gulp-autoprefixer working either and autoprefixer-core is now deprecated.
npm install autoprefixer --save-dev
I'm new to using gulp and I think I have it setup correctly, but it does not seem to be doing what it should be doing.
My gulpfile.js has
gulp.task('compass', function() {
return gulp.src('sites/default/themes/lsl_theme/sass/**/*.scss')
.pipe(compass({
config_file: 'sites/default/themes/lsl_theme/config.rb',
css: 'css',
sass: 'scss'
}))
.pipe(gulp.dest('./sites/default/themes/lsl_theme/css'))
.pipe(notify({
message: 'Compass task complete.'
}))
.pipe(livereload());
});
with
gulp.task('scripts', function() {
return gulp.src([
'sites/default/themes/lsl_theme/js/**/*.js'
])
.pipe(plumber())
.pipe(concat('lsl.js'))
.pipe(gulp.dest('sites/default/themes/lsl_theme/js'))
// .pipe(stripDebug())
.pipe(uglify('lsl.js'))
.pipe(rename('lsl.min.js'))
.pipe(gulp.dest('sites/default/themes/lsl_theme/js'))
.pipe(sourcemaps.write())
.pipe(notify({
message: 'Scripts task complete.'
}))
.pipe(filesize())
.pipe(livereload());
});
and the watch function
gulp.task('watch', function() {
livereload.listen();
gulp.watch('./sites/default/themes/lsl_theme/js/**/*.js', ['scripts']);
gulp.watch('./sites/default/themes/lsl_theme/sass/**/*.scss', ['compass']);
});
when I run gulp, the result is
[16:14:36] Starting 'compass'...
[16:14:36] Starting 'scripts'...
[16:14:36] Starting 'watch'...
[16:14:37] Finished 'watch' after 89 ms
and no changes are registered.
for file structure, my gulpfile.js is in the root directory and the sass, css, and js are all in root/sites/default/themes/lsl_theme with the sass folder containing the folder 'components' full of partials.
My assumption is that you are on windows? Correct me if I'm wrong.
There is this problem that gulp-notify tends to break the gulp.watch functions. Try commenting out
// .pipe(notify({
// message: 'Scripts task complete.'
// }))
and see if the problem still exists.
If that does fix the issue, a solution from this thread may be helpful.
You can use the gulp-if
plugin in combination with
the os node module
to determine if you are on Windows, then exclude gulp-notify, like
so:
var _if = require('gulp-if');
//...
// From https://stackoverflow.com/questions/8683895/variable-to-detect-operating-system-in-node-scripts
var isWindows = /^win/.test(require('os').platform());
//...
// use like so:
.pipe(_if(!isWindows, notify('Coffeescript compile successful')))
It turns out that a large part of my issue was just simply being a rookie with Gulp. When I removed 'scripts' from my gulp watch it started working.
I then made the connection that it was watching the same directory that it was placing the new concatenated and minified js files in so it was putting the new file, checking that file, and looping over and over causing memory issues as well as not allowing 'compass' to run.
After creating a 'dest' folder to hold the new js everything started working just peachy.