Grunt concurrent task outputting nothing - node.js

I want my Grunt based setup to run both "test" (i.e. the unit tests) and "server" (i.e. the web server) at the same time, so that I can just do grunt testAndServer to run both (and update both when any file is changed) in the same terminal.
Code (much of it is based on the yo angular scaffold):
// in initConfig:
concurrent: {
testAndWebServer: [
'karma',
'watch'
]
},
and later
grunt.registerTask('testAndServer', function (target) {
if (target === 'dist') {
return grunt.task.run(['build', 'open', 'connect:dist:keepalive']);
}
grunt.task.run([
'clean:server',
'concurrent:server',
'autoprefixer',
'compass',
'connect:livereload',
'open',
'concurrent:testAndWebServer'
]);
});
This actually works, but I don't get any output in the terminal (PowerShell) window. I would like the karma task to show the results of the tests. How can I acheive that?
I am running Node.js v0.10.20 on Windows 7, on a quadcore machine.

I just realized that I missed the logConcurrentOutput option.
This makes it work:
testAndWebServer: {
tasks: ['watch', 'karma'],
options: { logConcurrentOutput: true }
},

Related

How to execute npm script using grunt-run?

I have a npm task in my package.json file as follows to execute jest testing:
"scripts": {
"test-jest": "jest",
"jest-coverage": "jest --coverage"
},
"jest": {
"testEnvironment": "jsdom"
},
I want to execute this task npm run test-jest using grunt. I installed grunt-run for the same and added the run task, but how do I invoke this npm task there?
run: {
options: {
// Task-specific options go here.
},
your_target: {
cmd: 'node'
}
}
Configure your Gruntfile.js similar to the example shown in the docs.
Set the value for the cmd to npm.
Set run and test-jest in the args Array.
Gruntfile.js
module.exports = function (grunt) {
grunt.loadNpmTasks('grunt-run');
grunt.initConfig({
run: {
options: {
// ...
},
npm_test_jest: {
cmd: 'npm',
args: [
'run',
'test-jest',
'--silent'
]
}
}
});
grunt.registerTask('default', [ 'run:npm_test_jest' ]);
};
Running
Running $ grunt via your CLI using the configuration shown above will invoke the npm run test-jest command.
Note: Adding --silent (or it's shorthand equivalent -s) to the args Array simply helps avoids the additional npm log to the console.
EDIT:
Cross Platform
Using the grunt-run solution shown above failed on Windows OS when running via cmd.exe. The following error was thrown:
Error: spawn npm ENOENT Warning: non-zero exit code -4058 Use --force to continue.
For a cross-platform solution consider installing and utlizing grunt-shell to invoke the npm run test-jest instead.
npm i -D grunt-shell
Gruntfile.js
module.exports = function (grunt) {
require('load-grunt-tasks')(grunt); // <-- uses `load-grunt-tasks`
grunt.initConfig({
shell: {
npm_test_jest: {
command: 'npm run test-jest --silent',
}
}
});
grunt.registerTask('default', [ 'shell:npm_test_jest' ]);
};
Notes
grunt-shell requires load-grunt-tasks for loading the Task instead of the typical grunt.loadNpmTasks(...), so you'll need to install that too:
npm i -D load-grunt-tasks
For older version of Windows I had to install an older version of grunt-shell, namely version 1.3.0, so I recommend installing an earlier version.
npm i -D grunt-shell#1.3.0
EDIT 2
grunt-run does seem to work on Windows if you use the exec key instead of the cmd and args keys...
For cross platform purposes... I found it necessary to specify the command as a single string using the exec key as per the documentation that reads:
If you would like to specify your command as a single string, useful
for specifying multiple commands in one task, use the exec: key
Gruntfile.js
module.exports = function (grunt) {
grunt.loadNpmTasks('grunt-run');
grunt.initConfig({
run: {
options: {
// ...
},
npm_test_jest: {
exec: 'npm run test-jest --silent' // <-- use the exec key.
}
}
});
grunt.registerTask('default', [ 'run:npm_test_jest' ]);
};

How to prevent grunt-nodemon from restarting all apps

I'm running node on Windows 10. I have three node apps and I want to be able to start them all up with one handy grunt command. Furthermore, I want node to automatically restart if I modify any of the apps.
I'm using a combination of grunt-nodemon and grunt-concurrent for this. The node processes all start up fine.
The problem is that if I modify the code related to any of them they all restart, which takes a long time. How can I make it so that nodemon only restarts the app whose code I actually modified?
var loadGruntTasks = require('load-grunt-tasks')
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
concurrent: {
runAll: {
tasks: ['nodemon:app1', 'nodemon:app2', 'nodemon:app3'],
options: {
logConcurrentOutput: true
}
}
},
nodemon: {
app1: {
script: './app1/app.js'
},
app2: {
script: './app2/app.js'
},
app3: {
script: './app3/app.js'
}
}
})
loadGruntTasks(grunt)
grunt.registerTask('default', ['concurrent:runAll'])
}
Update
If I use grunt-watch instead of grunt-nodemon, only the app whose code I modified will restart. The problem is that grunt-watch only knows to run node app.js which gives an error because the app is already running. Is there a way to make grunt-watch kill the node process and restart it?
I think the answer could be fairly simple. Nodemon has an ignore option. For each of your three applications nodemon grunt configurations you can configurate them to ignore the directories of the other applications. That way they only kick off their restart when their own files are changed and not those of other projects. Let me know how that goes. :) Specifics about setting up the ignore section of config can be found in both nodemons documentation and grunt-nodemons documentation.
Patrick Motard's answer made me think about what directory nodemon was running in and how it was observing the files for changes. It appears that since I started grunt inside the parent directory of all the node apps that each nodemon process was looking for changes in all of those directories. So I set the working directory of the nodemon processes to the corresponding directory for each app using the options.cwd setting. That seemed to fix it. Here is the working solution:
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
concurrent: {
runAll: {
tasks: ['nodemon:app1', 'nodemon:app2', 'nodemon:app3'],
options: {
logConcurrentOutput: true
}
}
},
nodemon: {
app1: {
script: 'app.js',
options: {
cwd: './app1'
}
},
app2: {
script: 'app.js',
options: {
cwd: './app2'
}
},
app3: {
script: 'app.js',
options: {
cwd: './app3'
}
}
}
})
loadGruntTasks(grunt)
grunt.registerTask('default', ['concurrent:runAll'])
}

Grunt: How do I run seperate processes for CSS (sass, concat, minify) and JS (concat, minify)

I'm looking at the grunt watch documentation but I can see how to run a separate process for my javascript files. Below is what I have for CSS:
GruntFile.js
module.exports = function(grunt) {
grunt.initConfig({
// running `grunt sass` will compile once
sass: {
dist: {
options: {
style: 'expanded'
},
files: {
'./public/css/sass_styles.css': './src/sass/sass_styles.scss' // 'destination': 'source'
}
}
},
// bring in additonal files that are not part of the sass styles set
concat: {
dist: {
src: [
'public/css/datepicker.css',
'public/css/jquery.tagsinput.css',
'public/css/sass_styles.css',
'application/themes/japantravel/style.css'
],
dest: 'public/css/all.css',
},
},
// running `grunt cssmin` will minify code to *.min.css file(s)
cssmin: {
minify: {
expand: true,
cwd: "public/css/",
src: ["all.css", "!*.min.css"],
dest: "public/css/",
ext: ".min.css"
}
},
// running `grunt watch` will watch for changes
watch: {
files: ["./src/sass/*.scss", "./src/sass/partials/*.scss"],
tasks: ["sass", "concat", "cssmin"]
}
});
// load tasks
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks("grunt-contrib-cssmin");
grunt.loadNpmTasks("grunt-contrib-watch");
};
As you can see I have tasks for CSS ["sass", "concat", "cssmin"], but I want to do separate tasks for separate files (js) - concat and minify - and listen for changes (watch). Can someone point me in the correct direction, I'm not really sure what I should be searching for. Is this something that watch can handle, or is there another plugin? I'm a little new to grunt so still trying to figure out how to use it. Thanks
You can use 'grunt-concurrent' for that, you can define multiple tasks with it. In combination with watch sets you will have the proper solution. https://github.com/sindresorhus/grunt-concurrent
# to install:
npm install grunt-concurrent --save-dev
And this will be your adjusted function then.
Remember, you still have to set some uglify and jshint properties! But I believe that's not the issue here.
module.exports = function(grunt) {
grunt.initConfig({
/* .. */
// running `grunt watch` will watch for changes
watch: {
// Use 'sets' like this, just make up a name for it:
watchCss: {
files: ["./src/sass/*.scss", "./src/sass/partials/*.scss"], // Directory to look for changes
tasks: ["concurrent:taskCss"] // Tasks you want to run when CSS changes
},
watchJs: {
files: ["./src/js/**/*.js"], // Directory to look for changes
tasks: ["concurrent:taskJs"] // Tasks you want to run when JS changes
}
},
concurrent: {
taskCss: ["sass", "concat", "cssmin"], // define the CSS tasks here
taskJs: ["jshint", "concat", "uglify"] // define the JS tasks here
},
});
// load tasks
grunt.loadNpmTasks("grunt-contrib-sass");
grunt.loadNpmTasks("grunt-contrib-concat");
grunt.loadNpmTasks("grunt-contrib-cssmin");
grunt.loadNpmTasks("grunt-contrib-watch");
grunt.loadNpmTasks('grunt-contrib-jshint'); // Added
grunt.loadNpmTasks('grunt-contrib-uglify'); // Added
grunt.loadNpmTasks("grunt-concurrent"); // Added
// register tasks (note: you can execute sets from concurrent)
grunt.registerTask('default', ["concurrent:taskCss", "concurrent:taskJs"]);
grunt.registerTask('css', ["concurrent:taskCss"]);
grunt.registerTask('js', ["concurrent:taskJs"]);
};
To watch for changes:
grunt watch
# if a css file is changed, only the css tasks are performed
You can also execute a task from the prompt directly, for example:
grunt js
# This will only execute the registered task 'js'
# In this case that task points to 'concurrent:taskJs' wich will run jshint, concat and uglify
To install uglify and jshint:
https://github.com/gruntjs/grunt-contrib-uglify
https://github.com/gruntjs/grunt-contrib-jshint
npm install grunt-contrib-uglify --save-dev
npm install grunt-contrib-jshint --save-dev

How can I run a Node.js app using grunt-contrib-watch?

For example, I have a project folder "myProject" with the following files:
/myProject/app.js
/myProject/foo.json
Is there a way to setup grunt-contrib-watch to run app.js any time foo.json is modified?
Something like:
shell: {
runapptask: {
command: [
'node /myPorject/app.js'
]
}
},
watch: {
runapp: {
files: ['/myproject/foo.json'],
tasks: ['shell:runapptask']
}
}

grunt throw "Recursive process.nextTick detected"

I'm running Lion 10.9.2 with nodejs v0.10.26
I want to setup an automated compilation on sass files and a live reload with grunt, nothing complicated but...
When running grunt watch I get the following error
(node) warning: Recursive process.nextTick detected. This will break in the next version of node. Please use setImmediate for recursive deferral.
util.js:35
var str = String(f).replace(formatRegExp, function(x) {
^
RangeError: Maximum call stack size exceeded
here is the Gruntfile.js
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
sass: {
dist: {
files: {
'assets/css/styles.css': 'assets/sass/styles.scss'
}
}
},
watch: {
all: {
files: 'index.html', // Change this if you are not watching index.html
options: {
livereload: true // Set livereload to trigger a reload upon change
}
},
css: {
files: [ 'assets/sass/**/*.scss' ],
tasks: [ 'sass' ],
options: {
spawn: false
}
},
options: {
livereload: true // Set livereload to trigger a reload upon change
}
}
});
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.registerTask('watch', [ 'watch']);
grunt.registerTask('default', [ 'sass', 'watch' ]);
};
and here is the package.json
{
"name": "application",
"version": "0.0.1",
"private": true,
"devDependencies": {
"grunt": "~0.4.2",
"grunt-contrib-watch": "~0.5.3",
"grunt-contrib-sass": "~0.7.3"
}
}
I finally figured out a similar problem I was having with SASS. I was using
grunt.registerTask('sass', [ 'sass']);
The trick was that Grunt doesn't seem to like the repetition in names. When I switch to
grunt.registerTask('styles', [ 'sass']);
Everything worked as it should.
Just had this problem. Resolved it by removing grunt.registerTask('watch', [ 'watch']);
I just fixed a similar error "Recursive process.nextTick detected" causing by command: grunt server
The solution? Use sudo grunt serve instead
you could try this one, it fixed the issue for me, working with Yeoman 1.3.3 and Ubuntu 14.04 Grunt watch error - Waiting...Fatal error: watch ENOSPC
I was getting error in even trying to install grunt. Running npm dedupe solved my problem as answered here: Grunt watch error - Waiting...Fatal error: watch ENOSPC
Alternative solution: check your watch for an empty file argument.
Here's an excerpt of my gruntfile
watch: {
all: {
options:{
livereload: true
},
files: ['src/scss/*.scss', 'src/foo.html',, 'src/bar.html'],
tasks: ['default']
}
}
In my case, I could recreate the original poster's error on demand with the empty argument above.

Resources