I am trying to create a gulp task that updates all the assets in my project by executing a shell script. The problem is that it executes as expected and then just hangs.
'use-strict';
var gulp = require('gulp'),
gutil = require('gulp-util');
exec = require('child_process').exec;
var foreach = require('gulp-foreach');
gulp.task('update-assets', function () {
exec('./update_assets.sh', {cwd: 'assets'}, function(err, stdout, stderr) {
console.log(stdout);
console.log(stderr);
cb(err);
});
});
gulp.task('default', ['update-assets'], function() {
gulp.start('update-assets');
});
This is because of the nature of exec(). What exec() does it allows the command you give it to "take over" the current process. What you can do is instead try something like child_process.spawn . If it is a daemon process.
Take a good look at the Child_Process documentation. I think that this should help you get a good start.
Other options that may be helpful include modifying the script to throw exit codes for Gulp to recognize, or using timeouts to know when a gulp task has terminated.
UPDATE: Alternatively, you could use this, which is what I found worked for me when running a web server.
shell.exec('./update_assets.sh', {async:true} );
Related
I'm using gulp to minify CSS and JS files.
When I run the gulp command gulp build:website1:desktop from a terminal, it finishes successfully but it does not return to the shell prompt, I have to run Ctrl+C to return to the command prompt
Here is a what I'm using
gulp.task('build:website1:desktop', function () {
runSequence(
'website1:desktop:scripts',
'website1:desktop:css');
})
Any ideas How to exit and return to the command prompt without typing Ctrl+C every time?
Thank you in advance.
First thing is to make sure that your scripts and css tasks return a stream or a promise, so that runSequence knows when these tasks are finished. For most gulp tasks, using the return statement with gulp.src(…) will do just that:
gulp.task('website1:desktop:scripts', function() {
return gulp.src(…)
.pipe(doSomething())
.pipe(gulp.dest(…));
});
Next thing is to provide a callback for runSequence:
gulp.task('build:website1:desktop', function (callback) {
runSequence(
'website1:desktop:scripts',
'website1:desktop:css',
callback);
});
This should do the trick.
Using gulp and the new Microsoft bash shell, I am trying to set up a gulp watch to compile my scss into css, in a way that the watch doesn't stop when there is an error compiling it.
I've set up a gulp task called sass to do this, and I can run it fine from the command line with gulp sass, but when I try to run my gulp watch command with gulp watch I get an EPERM error which I've been unable to fix in a way to get my gulp.watch working. Here is the error messages output to the command line, below.
I've tried changing permissions on my node_modules folder, as well using sudo to do, but I still get this error. Help would be greatly appreciated.
var gulp = require('gulp');
var sass = require('gulp-sass');
var plumber = require('gulp-plumber');
var notify = require('gulp-notify');
gulp.task('watch', ['sass'], function() {
gulp.watch('app/scss/**/*.scss', ['sass']);
})
gulp.task('sass', function() {
return gulp.src('app/scss/**/*.scss')
.pipe(customPlumber('Error Running Sass'))
.pipe(sass())
.pipe(gulp.dest('app/css'))
})
function customPlumber(errTitle){
return plumber({
//use notify plugin to report error as windows toaster message
errorHandler:notify.onError({
//Customizing error title
title:errTitle || "Error running Gulp",
message: "Error: <%= error.message %>",
})
});
}
WSL doesn't support FS notify syscalls in Slow/Preview/Production rings. In the Fast ring, it supports tracking changes made inside WSL. Devs promise support for tracking changes made in Windows will be added soon enough.
Related links:
GitHub issue
UserVoice ticket
I'm new to Gulp and I found a Gulpfile.js example I wanted to use to livereload my express app's server whenever a change takes place in either my app.js file or ./public directory. Here is the Gulpfile.js code:
var gulp = require('gulp'),
spawn = require('child_process').spawn,
node;
/**
* $ gulp server
* description: Launch the server. If there's a server already running, kill it.
*/
gulp.task('server', function() {
if (node) node.kill()
node = spawn('node', ['app.js'], {stdio: 'inherit'})
node.on('close', function (code) {
if (code === 8) {
gulp.log('Error detected, waiting for changes...');
}
});
})
/**
* $ gulp default
* description: Start the development environment
*/
gulp.task('default', function() {
gulp.run('server')
gulp.watch(['./app.js', './public/'], function() {
gulp.run('server')
})
})
// clean up if an error goes unhandled.
process.on('exit', function() {
if (node) node.kill()
})
In my terminal window I keep getting the following warning:
gulp.run() has been deprecated. Use task dependencies or gulp.watch task triggering instead.
Gulp is working and it is livereloading the web application like I want it to but I'd like to fix this issue to future proof my development process, as well as get rid of this annoying warning message.
Thanks for the help!
One option would be to simply replace all occurrences of gulp.run() with gulp.start():
gulp.task('default', function() {
gulp.start('server');
gulp.watch(['./app.js', './public/'], function() {
gulp.start('server');
});
});
However calling a task explicitly using gulp.start() is not the idiomatic way of doing things in gulp (although sometimes it's necessary).
The warning message you receive already hints at the idiomatic way of solving this:
Use task dependencies or gulp.watch task triggering
Task dependencies allow you to run a task before another task. That means you can get rid of the first gulp.run().
Task triggering in gulp.watch() allows you to run a task when a file changes. That means you can get rid of the second gulp.run().
Therefore your default task ends up looking like this:
gulp.task('default', ['server'], function() {
gulp.watch(['./app.js', './public/'], ['server']);
});
I'm trying to execute something using gulp-shell. My gulfile.js contains the following content:
var gulp = require('gulp'),
shell = require('gulp-shell');
gulp.task('test', function() {
shell(['echo test']);
});
Then I run it calling gulp test. This is the output I get:
Using gulpfile ~/gulpfile.js
Starting 'test'...
Finished 'test' after 2.62 ms
There's no output for my echo call.
I'm using an Ubuntu 14 VM that I connected to, using Putty.
Anyone got an idea what's wrong?
That's because it's not the good way to use gulp-shell.
Try this, as seen in the gulp-shell README.
var gulp = require('gulp'),
shell = require('gulp-shell');
gulp.task('test', shell.task([
'echo test'
]));
For the record, if you want to pipe gulp-shell, per specified in the doc:
gulp.task('myGulpTask', [], function() {
return gulp.src('gulpfile.js', {read: false})
.pipe(shell('echo "This works too"'));
});
Short of it: started using Gulp recently (convert from Grunt), and am trying to use both Gulp's default watch task (not gulp-watch from npm) for SASS/JS/HTML and gulp-nodemon (from npm) to restart an Express server upon changes. When running just gulp watch, it works fine; and when running gulp server (for nodemon) that works fine. However, using both together (shown below in the configuration of the default task), the watch stuff isn't working. The task is running, and on the CLI gulp shows 'Starting' and 'Finished' for the watch tasks, but the files don't update.
Relevant task configurations:
Concat javascript:
gulp.task('js:app', function(){
return gulp.src([
pathSource('js/application/modules/**/*.js'),
pathSource('js/application/_main.js')
])
.pipe(concat('application.js'))
.pipe(gulp.dest('./build/assets/js')).on('error', utils.log);
});
Nodemon, restart on changes to express app:
gulp.task('express', function(){
return nodemon({script:'server.js', ext:'js', cwd: __dirname + '/express', legacyWatch: true})
.on('restart', function(){
//gulp.run('watch'); // doesn't work :(
});
});
Watch javascript changes, and run js:app for concat'ing.
gulp.task('watch', function(){
gulp.watch(pathSource('js/application/**/*.js'), ['js:app']);
});
Default task, to initialize gulp watch and nodemon simultaneously:
gulp.task('default', ['watch', 'express']);
If anyone has any ideas, thanks in advance!
gulp.run calls have been deprecated, so I'd try a different approach. Since you're already using gulp, may I suggest giving gulp-nodemon a try?
As per gulp-nodemon documentation, you can pass it an array of tasks to execute:
UPDATE: Here's the full gulpfile.js file, together with a working sample on github.
'use strict';
// Main dependencies and plugins
var gulp = require('gulp');
var jshint = require('gulp-jshint');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var rename = require('gulp-rename');
var nodemon = require('gulp-nodemon');
var assets = 'assets/js/**/*.js';
var publicDir = 'public/javascripts';
// Lint Task
gulp.task('lint', function () {
return gulp.src(assets)
.pipe(jshint())
.pipe(jshint.reporter('jshint-stylish'));
});
// Concatenate and minify all JS files
gulp.task('scripts', function () {
return gulp.src(assets)
.pipe(concat('global.js'))
.pipe(gulp.dest(publicDir))
.pipe(rename('global.min.js'))
.pipe(uglify())
.pipe(gulp.dest(publicDir));
});
// Watch Files For Changes
gulp.task('watch', function () {
gulp.watch(assets, ['lint', 'scripts']);
});
gulp.task('demon', function () {
nodemon({
script: 'server.js',
ext: 'js',
env: {
'NODE_ENV': 'development'
}
})
.on('start', ['watch'])
.on('change', ['watch'])
.on('restart', function () {
console.log('restarted!');
});
});
// Default Task
gulp.task('default', ['demon']);
This way, you spawn the watch task upon nodemon's start and ensure that the watch task is again triggered whenever nodemon restarts your app.
EDIT: seems you should be calling the on-change event from gulp-nodemon, which will handle compile tasks before the restart event triggers.
EDIT: It seems nodemon's on('change', callback) is removed from their API
FWIW, it seems that using the cwd parameter on gulp-nodemon's configuration actually sets the entire gulp cwd to that directory. This means future tasks will be executed in the wrong directory.
I had this problem when running gulp watch tasks on my frontend server at the same time as nodemon tasks on my backend server (in the same gulpfile), there was a race condition wherein if the nodemon command was executed first, the frontend stuff would actually build into (Home)/backend/frontend instead of (Home)/frontend, and everything would go pearshaped from there.
I found that using watch and script params on gulp-nodemon worked around this (although it still looks like nodemon is watching my entire project for changes rather than the built backend directory).