Gulp hangs after executing tasks - javascript

I'm figuring out how gulp is working; it looks like the gulp tasks are being executed, but then it hangs.
Environment:
node version v14.17.0.
gulp:
CLI version: 2.3.0 Local version: 4.0.2
const babel = require("gulp-babel");
task("js",()=>{
return src("src/*.js").pipe(babel()).pipe(dest("dist/js"));
})
task("moveHTML",()=>{
return src("src/*.html").pipe(dest("dist"));
});
task("watch",()=>{
watch("src/*.js",series("js"));
});
task("default",series('moveHTML','js','watch'));
There is no error here, but the execution is hanging. below is the node terminal message:
[10:30:29] Starting 'default'...
[10:30:29] Starting 'moveHTML'...
[10:30:29] Finished 'moveHTML' after 85 ms
[10:30:29] Starting 'js'...
[10:30:32] Finished 'js' after 3.22 s
[10:30:32] Starting 'watch'...

The process persists because you are calling gulp.watch which returns an instance of chokidar and by default keeps the node process running.
If you want to stop the node process use the persistent option and set it to false.
watch("src/*.js", { persistent: false }, series("js"));
However, the gulp docs suggest not to do this.

Related

Gulp-Watch on Windows 7 Issue - Node.js, NPM and Gulp installed successfully

I am super new to using Node.js, NPM and all these modern tools for better productivity and workflow.
So here are the details:
Node version - v8.10.0
Gulp CLI version - 2.0.1
Gulp Local version - 3.9.1
NPM version - 5.6.0
Windows 7
Node.js installed in D:/ProgramFiles
I've tried using gulp and it does work wonderfully with this script
var gulp = require('gulp'),
watch = require('gulp-watch');
gulp.task('default',function(){
console.log('Gulp task created');
});
gulp.task('html' , function() {
console.log('Something useful here');
});
gulp.task('watch', function() {
watch('/app/index.html', function() {
gulp.start('html');
});
});
So typing gulp does respond with the default task message. Typing gulp html does respond too with a console message. However, when i type gulp watch, it does work with following output.
Starting 'watch'...
Finished 'watch' after 7.99 ms
But whenever i make changes and save the index file, the cmd doesn't update. I've tried using Git Bash and other terminals. I've even installed previous node versions and tried solving this issue using those but no luck so far.
I tried editing the dependencies to an older version but that doesn't work too.
If anyone of you can help, I'll be thankful.
Updated with callback method to end process for a graceful exit and not use CTRL-C.
gulp.task('watch',function(){
gulp.watch('./data/index.html', function(){
gulp.start(['someOtherGulpTask']);
});
});
gulp.task('someOtherGulpTask', function () {
gulp.src('./test/sometest.js')
.pipe(gulpmocha(),setTimeout(function() {
cb();
}, 5000))
});
function cb(){
process.exit(1);
}
Original answer below
The order of execution of gulp tasks are -
the default task gets executed and then the subsequent ones unless the task
to be executed is specifically mentioned in the cmdline call to gulp as you
have mentioned - "gulp watch".
you can specify the order in the beginning of the gulpfile like
gulp.task('default', ['watch']);
or, you can start a task explicitly like so,
gulp.task('default',function(done){
console.log('Gulp task created');
gulp.start('watch');
done();
});
done is the callback that allows your waiting task to complete which is missing in your gulp file. Below is the complete gulp file that you can use to execute the watch task as you require.
var gulp = require('gulp'),
watch = require('gulp-watch');
gulp.task('default',function(done){
console.log('Gulp task created');
gulp.start('watch');
done();
});
gulp.task('html' , function() {
console.log('Something useful here');
});
gulp.task('watch', function() {
watch('./data/index.html', function() {
console.log('Some changes done');
});
});
gulp.task('watch', function () {
gulp.watch('./data/index.html', ['html']);
});
Avoid gulp.start, it is not documented or recommended.

Gulp task does not finish even when the process terminates with code 0

I have added a gulp task to remove directories in the given paths. The paths are read from an array.
My gulp task runs properly and does the required job. The Task Runner explorer give the message of starting the task as well as the process terminating successfully with code 0. The problem is that it doesn't state that the task has finished. Due to this, my other tasks that are dependent on this task, cannot execute during build process automation.
const rmr = require('rmr');
// array containing the list of all paths of the folders to be deleted
const removeFoldersArr = [
{
Path: "wwww/scripts"
},
{
Path: "www/styles"
}
];
// Gulp Task to remove all files in a folder
gulp.task('cleanFolders', function () {
return removeFoldersArr.map(function (folder) {
rmr.sync(folder.Path);
});
});
Inside Task Runner Explorer, the task starts but doesn't finish, though it terminates with code 0, as shown below:
cmd.exe /c gulp -b "D:\My Projects\Solution1" --color --gulpfile "D:\My Projects\Solution1\Gulpfile.js" cleanFolders
[18:04:23] Using gulpfile D:\My Projects\Solution1\Gulpfile.js
[18:04:23] Starting 'cleanFolders'...
Process terminated with code 0.
The correct way is to return a promise.
Given an iterable (array or string), or a promise of an iterable, promise.all iterates over all the values in the iterable into an array and returns a promise that is fulfilled when all the item(s) in the array is(are) fulfilled.
Following is the code snippet of the solution:
gulp.task('cleanFolders', function () {
return Promise.all([
removeFoldersArr.map(function (folder) {
rmr.sync(folder.Path);
})
]);
});
Now, the process first finishes and then gets terminated.
Following is the output as shown in Task Runner Explorer:
cmd.exe /c gulp -b "D:\My Projects\Solution1" --color --gulpfile "D:\My Projects\Solution1\Gulpfile.js" cleanFolders
[12:25:01] Using gulpfile D:\My Projects\Solution1\Gulpfile.js
[12:45:01] Starting 'cleanFolders'...
[12:45:01] Finished 'cleanFolders' after 3.18 ms
Process terminated with code 0.
After having this issue on VS2017, we looked to see that the issue we were having was related to version numbers 15.8.X, in which they shipped a new version of Node.js, version 10.6, and that basically broke gulp. It was terminating the process early with a code 0, but few if any of the processes were even allowed to finish.
Rearranging the web package management list to put $(PATH) before $(VSInstalledExternalTools) and having LTS version of Node on your path is what fixed it for us.
See: https://developercommunity.visualstudio.com/content/problem/311553/task-runner-cant-load-gruntfilejs.html

Why is this gulp task not being run consecutively?

I have three gulp tasks: watch, build, test. I'd like to have my watch running and when a file is saved, it is built and then tested (duh).
What is happening is that despite being set up to run build as a dependency of test, I need to save the file twice in order for the latest build to be the one that is tested.
I can reproduce this by starting the watch, making a change to somewhere in the client JS code (like adding a console log) and then watching the resulting output. The first save will not have any console output. Just saving the file again (no changes made) will cause the test to be re-run and the console output to display.
I have also noticed cases where the first build+test cycle will be the correct build (i.e. will have the console log statement), but after that, it takes two saves to make sure the latest code is the one being tested.
Spec files are immune to this because they are not built and instead used directly (sorta, they're transpiled first).
So, am I going crazy here? These should be run consecutively, right?
The log would suggest that's the case:
[12:05:54] Starting 'build:client:js'...
[12:05:54] Finished 'build:client:js' after 13 ms
[12:05:54] Starting 'test:client'...
19 09 2016 12:05:54.808:INFO [karma]: Karma v1.3.0 server started at http://localhost:9876/
19 09 2016 12:05:54.808:INFO [launcher]: Launching browser PhantomJS with unlimited concurrency
19 09 2016 12:05:54.841:INFO [launcher]: Starting browser PhantomJS
19 09 2016 12:05:55.381:INFO [PhantomJS 2.1.1 (Mac OS X 0.0.0)]: Connected on socket /#Zklau3qmk75NKg2HAAAB with id 61545463
LOG: 'test'
.
PhantomJS 2.1.1 (Mac OS X 0.0.0): Executed 1 of 1 SUCCESS (0.002 secs / 0.029 secs)
[12:05:55] Finished 'test:client' after 775 ms
Build:
Basic build for AngularJS App, nothing too strange here.
gulp.task('build:client:js', () => {
gulp.src('app/sections/client/**/!(*.spec|*.e2e).js')
.pipe(sourceMaps.init())
.pipe(eslint())
.pipe(eslint.formatEach())
.pipe(babel({presets: ['es2015']}))
.pipe(ngAnnotate())
.pipe(concat('client.js'))
.pipe(uglify())
.pipe(sourceMaps.write())
.pipe(gulp.dest(paths.build))
});
Test:
This is set up so that, ideally, build runs and completes first.
gulp.task('test:client', ['build:client:js'], (done) => {
const src = {};
src['client'] = 'app/sections/client';
const config = getTestConfig(src);
new karmaServer(config, done).start();
});
Watch:
This should only need to run test because build is a dependency of test.
gulp.task('watch:client:js', () => {
gulp.watch('app/sections/client/**/*.js', ['test:client']);
});
Also, to be totally transparent, most of my watch>build>test gulp tasks are being generated dynamically based off a paths file. It basically returns JSON that is then used by functions to create the gulp tasks. The output below is the result of that generation, but I'm not sure that physically writing each task out like this would make any difference.
You can experiment with or see more here.
In the task 'build:client:js', you should return the stream so that gulp knows when the task actually ends.
gulp.task('build:client:js', () => {
return gulp.src('app/sections/client/**/!(*.spec|*.e2e).js')
.pipe(sourceMaps.init())
.pipe(eslint())
.pipe(eslint.formatEach())
.pipe(babel({presets: ['es2015']}))
.pipe(ngAnnotate())
.pipe(concat('client.js'))
.pipe(uglify())
.pipe(sourceMaps.write())
.pipe(gulp.dest(paths.build))
});

gulp.watch() not running associated task

I have the following code in my gulpfile.js:
gulp.task('test-watch', function () {
console.log('running test-watch...');
return gulp.src('./views/layout.tmpl')
.pipe(rename('layout.html'))
.pipe(gulp.dest('./views/'));
});
gulp.task('watch', function () {
var watcher = gulp.watch('./views/layout.tmpl', ['test-watch']);
watcher.on('change', function (event) {
console.log('File ' + event.path + ' was ' + event.type + ', running tasks...');
});
});
It results in the following output (the last line occurs after I edit/save "layout.tmpl"):
[15:53:12] Using gulpfile C:\project1\gulpfile.js
[15:53:12] Starting 'watch'...
[15:53:12] Finished 'watch' after 6.72 ms
File C:\project1\views\layout.tmpl was changed, running tasks...
The file "layout.html" (which is supposed to be a copy of "layout.tmpl") does not get created. Note that in the above output while the "console.log" within the "watcher.on" invocation is shown in output, the "console.log" within the "test-watch" task is not shown. If I run the test-watch task directly, the file does get created.
Here is the output if I run the test-watch task directly:
[15:53:56] Using gulpfile C:\project1\gulpfile.js
[15:53:56] Starting 'test-watch'...
running test-watch...
[15:53:56] Finished 'test-watch' after 12 ms
Note that the "console.log" within the "test-watch" task is shown.
This is on a Windows 7 machine, running gulp tasks from cmd.exe.
Support for passing in watch tasks to the gulp.watch API as an array requires gulp version 3.5 at minimum. The gulp.watch API accepts an array of tasks only in gulp version 3.5 and up.
My local gulp was version 3.4.
I updated gulp to latest 3.8 version and my watch task worked correctly.

grunt server can't be connected <gruntjs>

module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
server: {
port: 8888,
base: '.'
}
});
};
C:\Program Files\nodejs\test\grunt>
C:\Program Files\nodejs\test\grunt>grunt server
Running "server" task
Starting static web server on port 8888.
Done, without errors.
but can't connected by input [http://127.0.0.1:8888][1] in browsers ! jiong~
How about to fix this problem in windows or unix ?
In grunt 0.4 combined with grunt-contrib-connect you can run a long running server by using the keepalive argument: grunt connect:target:keepalive or define it as an option in your config:
grunt.initConfig({
connect: {
target:{
options: {
port: 9001,
keepalive: true
}
}
}
});
Don't use grunt to serve your project. Grunt is a build tool. Instead, use npm lifecycle scripts.
server.js
var express = require("express"),
app = express();
app.use('/', express.static(__dirname));
app.listen(8888);
package.json
{
"name": "my-project",
"scripts": {
"start": "node server.js"
},
"dependencies": {
"express": "3"
}
}
Now you can run npm start and life will be great. Grunt is a build tool, not a server. npm is a package lifecycle manager, not a build tool. Express is a server library. Use each in its right place.
Follow up (2013-08-15)
The exception to this rule is when you're needing to serve your project to other testing tools in your build stack. The grunt-contrib-connect plugin is designed specifically with this use case in mind, and has a keepalive configuration setting that will leave grunt open while serving your static files. This is usually used in conjunction with a watch task that runs a test suite when either the tests or the code changes.
The server task only runs as long as it is needed, but you can keep it from quitting. From a comment by widget on another question: In your grunt.js file define a task named run that runs the tasks server and watch.
grunt.registerTask("run", "server watch");
The watch task runs indefinitely, so it prevents the server task from ending. Just make sure you also have a config for the watch task. Here it is all together in your grunt.js file:
module.exports = function (grunt) {
// …
grunt.initConfig({
// …
watch: {
files: "<config:lint.files>",
tasks: "lint qunit",
},
// …
});
grunt.registerTask("run", "server watch");
};
From the command line just type:
$ grunt run
The server will stay up and running.
Alternatively, as #NateBarr points out, from the command line you can run:
$ grunt server watch
By default Grunt starts up the server just for testing (or any other task asked..) and as soon as it's done it exits....
But fortunately I found a solution which by adding this to your grunt.js file will let you (optionally) halt the server from exiting.
grunt.registerTask('wait', 'Wait for a set amount of time.', function(delay) {
var d = delay ? delay + ' second' + (delay === '1' ? '' : 's') : 'forever';
grunt.log.write('Waiting ' + d + '...');
// Make this task asynchronous. Grunt will not continue processing
// subsequent tasks until done() is called.
var done = this.async();
// If a delay was specified, call done() after that many seconds.
if (delay) { setTimeout(done, delay * 1000); }
});
Then in your command line call it: grunt server wait then you should be able to see it in the browser..
Make sure you add it inside module.exports = function(grunt){...}

Categories