I'm just getting started with Grunt and would like to run grunt-contrib-watch [GitHub page] to lint my JavaScript every time a file is modified (with grunt-contrib-jshint [GitHub page]) and run grunt-nodemon [GitHub page] too, concurrently using grunt-concurrent [GitHub page].
As I understand (which I evidently don't) my Gruntfile should:
Run concurrent by default
concurrent runs watch
watch runs jshint every time a file is modified
Gruntfile.js
module.exports = function (grunt) {
grunt.initConfig({
concurrent: {
dev: [
'watch'
],
options: {
logConcurrentOutput: true
}
},
jshint: {
server: [
'**/*.js',
'!node_modules/**/*.js'
],
options: {
node: true
}
},
watch: {
all: [
'**/*/.js',
'!node_modules/**/*.js'
],
tasks: [
'jshint'
]
}
});
grunt.loadNpmTasks('grunt-concurrent');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('default', [
'concurrent:dev'/*,
'jshint',
'watch'*/
]);
};
grunt.loadNpmTasks('grunt-concurrent');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('default', [
'concurrent:dev'
]);
};
N.B. I've not added grunt-nodemon into the mix yet.
It looks like concurrent is running watch but when I modify a file it appears jshint isn't running. I certainly don't get any output in the Terminal (I thought logConcurrentOutput: true does this).
Here is the output I get in the Terminal:
Running "concurrent:dev" (concurrent) task
Running "watch" task
Waiting...
Done, without errors.
I would also like to run jshint when I first run the default task (as well as when I modify files).
Can anyone shed some light on where I am going wrong?
Thanks!
The watch task exits if there are no files found to 'watch'; as per this issue.
To easily tell watch to watch the same files as the jshint task I used Grunt's templating engine to reference the same Array of files as the jshint task.
I then added jshint to the list of concurrent tasks to run so it would be ran initially and as I modify files (with watch).
Here is my working Gruntfile:
module.exports = function (grunt) {
grunt.initConfig({
concurrent: {
dev: [
'jshint',
'watch'
],
options: {
logConcurrentOutput: true
}
},
jshint: {
server: [
'**/*.js',
'!node_modules/**/*.js'
],
options: {
node: true
}
},
watch: {
files: '<%= jshint.server %>',
tasks: [
'jshint'
]
}
});
grunt.loadNpmTasks('grunt-concurrent');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('default', [
'concurrent'
]);
};
If you are running an Express server then you can use grunt-express-server. The documentation has a good guide on using this with JSHINT, and LiveReload + Watch/Regarde.
grunt.initConfig({
jshint: {
all: ['Gruntfile.js', 'public/javascripts/*.js', 'test/**/*.js']
},
watch: {
express: {
files: ['**/*.js', '**/*.ejs'],
tasks: ['jshint', 'express:dev'],
options: {
spawn: false
}
}
},
express: {
dev: {
options: {
script: './app.js'
}
}
}
});
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-express-server');
grunt.loadNpmTasks('grunt-contrib-watch');
// Default task(s).
grunt.registerTask('server', [ 'express:dev', 'watch' ]);
});
Jonathon you need to check that your globbing pattern actually matches any files. As the link to the issue suggests you can try the nonull option. I would also suggest to run grunt with the flag --debug so you can see more of what's happening under the hood.
This is a working Gruntfile which launches a node server, watches for changes and livereloads. It uses the grunt-express plugin.
Related
I am looking to run a node command through my gruntfile. I just need to run:
node index.js
as the first task before any other tasks. I tried searching around but haven't found the answer. I believe it might be something simple but I am not sure how. Do I need to load in nmp tasks?
This is how my Gruntfile looks like:
"use strict";
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
jshint: {
all: [
'Gruntfile.js'
],
options: {
jshintrc: '.jshintrc',
},
},
// Before generating any new files, remove any previously-created files.
clean: {
tests: ['dist/*']
},
// Configuration to be run (and then tested).
mustache_render: {
json_data: {
files: [
{
data: 'jsons/offer.json',
template: 'offers.mustache',
dest: 'dist/offers.html'
},
{
data: 'jsons/profile.json',
template: 'profile.mustache',
dest: 'dist/profile.html'
}
]
}
}
});
// These plugins provide necessary tasks.
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-mustache-render');
// Whenever the "test" task is run, first clean the "tmp" dir, then run this
// plugin's task(s), then test the result.
grunt.registerTask('default', ['clean', 'jshint', 'mustache_render']);
};
I want to run "node index.js" before the 'clean' task.
The standard way of doing this is to use the grunt-run task.
Do:
npm install grunt-run --save-dev
And in your grunt file:
grunt.loadNpmTasks('grunt-run');
And then some config (from the documentation):
grunt.initConfig({
run: {
options: {
// Task-specific options go here.
},
your_target: {
cmd: 'node',
args: [
'index.js'
]
}
}
})
Then you change the task registration to be this:
grunt.registerTask('default', ['run', 'clean', 'jshint', 'mustache_render']);
I keep running into this problem everytime I try to use the live reload option of grunt watch.
No matter which port I use, I keep getting the "Fatal error: Port xxxx is already in use by another process."
I listed all ports in use, and choosing a random number that doesn't appear in the list doesn't help: it substitues xxxx with whatever port was last used in the gruntfile.
My gruntfile itself:
module.exports = function (grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
watch: {
options: {
livereload: true
},
js: {
files: ['.dev/**/*.js'],
tasks: ['concat', 'uglify', 'watch'],
},
scss: {
files: ['./dev/scss/*.scss'],
tasks: ['sass', 'concat', 'watch'],
options: {
reload: true,
livereload: false,
}
},
html: {
files: ['./dev/**/*.html', 'watch'],
tasks: ['copy', 'watch'],
},
grunt: {
files: ['Gruntfile.js'],
tasks: ['watch'],
},
},
concat: {
js: {
src: ['dev/js/script1.js', 'dev/js/script2.js'],
dest: 'dev/js/script.js',
},
css: {
src: ['./dev/css/nav.css', './dev/css/anim.css', './dev/css/style.css'],
dest: './dist/css/style.css',
},
},
uglify: {
build: {
src: 'dev/js/script.js',
dest: 'dist/js/script.min.js'
}
},
sass: { // Task
dev: { // Target
files: { // Dictionary of files
'./dev/css/style.css': './dev/scss/style.scss', // 'destination': 'source'
},
tasks: ['copy'],
}
},
copy: {
main: {
expand: true,
cwd: './dev/html',
src: '*.html',
dest: './dist/html/'
},
},
});
// Load the plugin that provides the "uglify" task.
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.loadNpmTasks('grunt-contrib-sass');
// Default task(s).
grunt.registerTask('default', ['concat', 'uglify', 'sass', 'copy', 'watch']);
};
I'm still new to npm, grunt etc, and have had this issue using Yeoman as well.
Is there some application that might automatically listen to every port (I'm using Webstorm)?
However, when I close it down and use sublime and a terminal, it keeps on saying every random port is already in use
Looks like you're recursively calling watch..
Take this portion of your gruntfile for example:
watch: { // hey grunt, you now know of a task called 'watch'
....
html: {
files: ['./dev/**/*.html', 'watch'], // here are the files to watch
tasks: ['copy', 'watch'], // and oh, hey, when you run watch, make
// sure to run watch again, recursively, forever
}
I think you can see where this is going. Your port is in use because your watch task is already running when it tries to run again. You don't need to register 'watch' as a task on each subsection of watch. Hope that helps :)
I want to use browserfy to transform es6 files to es5. But everytime the watch-task is executed I get the error:
Warning: Task "browserfy" not found. Use --force to continue.
I automate the task with the following gruntfile (simplified):
grunt.initConfig({
browserfy: {
dist: {
options: {
transform: [
["babelify", {
loose: "all"
}]
]
},
files: {
"dist/module.js": ["lib/main.js"]
}
}
},
watch: {
lib_test: {
files: '<%= jshint.lib_test.src %>',
tasks: ['jshint:lib_test', 'browserfy'/*, 'qunit'*/]
}
}});
grunt.loadNpmTasks("grunt-browserify");
grunt.loadNpmTasks('grunt-contrib-watch');
I also used the command
npm install grunt-browserify --save-dev
Solved the problem. I had a typo. It is "browserify.
When I am using grunt command it is showing me following error:
$ grunt
Loading "Gruntfile.js" tasks...ERROR
>> Error: Cannot find module 'load-grunt-tasks'
Warning: Task "default" not found. Use --force to continue.
Aborted due to warnings.
Execution Time (2015-02-07 18:05:42 UTC)
loading tasks 339ms ███████████████████████████████████████████████ 99%
Total 344ms
I already tried - npm install, npm update commands. It would be great if someone can help me with this. Thanks!
Addding Content of Gruntfile.js
'use strict';
var paths = {
js: ['*.js', 'test/**/*.js', '!test/coverage/**', '!bower_components/**', 'packages/**/*.js', '!packages/**/node_modules/**', '!packages/contrib/**/*.js', '!packages/contrib/**/node_modules/**'],
html: ['packages/**/public/**/views/**', 'packages/**/server/views/**'],
css: ['!bower_components/**', 'packages/**/public/**/css/*.css', '!packages/contrib/**/public/**/css/*.css']
};
module.exports = function(grunt) {
if (process.env.NODE_ENV !== 'production') {
require('time-grunt')(grunt);
}
// Project Configuration
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
assets: grunt.file.readJSON('config/assets.json'),
clean: ['bower_components/build'],
watch: {
js: {
files: paths.js,
tasks: ['jshint'],
options: {
livereload: true
}
},
html: {
files: paths.html,
options: {
livereload: true,
interval: 500
}
},
css: {
files: paths.css,
tasks: ['csslint'],
options: {
livereload: true
}
}
},
jshint: {
all: {
src: paths.js,
options: {
jshintrc: true
}
}
},
uglify: {
core: {
options: {
mangle: false
},
files: '<%= assets.core.js %>'
}
},
csslint: {
options: {
csslintrc: '.csslintrc'
},
src: paths.css
},
cssmin: {
core: {
files: '<%= assets.core.css %>'
}
},
nodemon: {
dev: {
script: 'server.js',
options: {
args: [],
ignore: ['node_modules/**'],
ext: 'js,html',
nodeArgs: ['--debug'],
delayTime: 1,
cwd: __dirname
}
}
},
concurrent: {
tasks: ['nodemon', 'watch'],
options: {
logConcurrentOutput: true
}
},
mochaTest: {
options: {
reporter: 'spec',
require: [
'server.js',
function() {
require('meanio/lib/core_modules/module/util').preload(__dirname + '/packages/**/server', 'model');
}
]
},
src: ['packages/**/server/tests/**/*.js']
},
env: {
test: {
NODE_ENV: 'test'
}
},
karma: {
unit: {
configFile: 'karma.conf.js'
}
}
});
//Load NPM tasks
require('load-grunt-tasks')(grunt);
/**
* Default Task
*/
grunt.hook.push('clean', -9999);
grunt.hook.push('concurrent', 9999);
if (process.env.NODE_ENV === 'production') {
grunt.hook.push('cssmin', 100);
grunt.hook.push('uglify', 200);
} else {
grunt.hook.push('jshint', -200);
grunt.hook.push('csslint', 100);
}
//Default task.
grunt.registerTask('default', ['hook']);
//Test task.
grunt.registerTask('test', ['env:test', 'mochaTest', 'karma:unit']);
// For Heroku users only.
// Docs: https://github.com/linnovate/mean/wiki/Deploying-on-Heroku
grunt.registerTask('heroku:production', ['cssmin', 'uglify']);
};
Try running:
$ npm install
After that, if you run it and the error still persists or if there's another one, then you probably have not installed ruby, compass or both :)
I had the same issue, the problem for me was in my package.json where I didn't actually install the NPM package needed and it was not automatically installed as previously thought. Try doing
npm install --save-dev load-grunt-tasks
If that doesn't work can you provide the package.json file as well so we can get a little more information.
I was having the same issue you were having, it seems as though the gruntfile is missing a required initialization step.
By changing this:
require('load-grunt-tasks')(grunt);
/**
* Default Task
*/
grunt.hook.push('clean', -9999);
to this:
require('load-grunt-tasks')(grunt);
grunt.loadNpmTasks('grunt-hook');
/**
* Default Task
*/
grunt.hook.push('clean', -9999);
Adding the grunt.loadNpmTasks call, I'm able to get past that issue. The problem is, now I'm getting
Task "clean" not found. Use --force to continue.
Looking at the rest of the grunt file, i don't see a register task for clean. If I go to the mean.io docs, it looks like the build is failing. Perhaps this is part of why? I think I asked mean-cli for gulp version, that's probably why. I'll delete and take it from the top :)
I think the problem is related to where the npm dependencies are declared and the way Heroku handles them.
In few words, check if the npm packages are as dev dependencies and move them to the dependencies block, as suggested here: https://stackoverflow.com/a/20687098/532912.
This is my Gruntfile. I run concurrently nodemon to run my application and watch to watch for changes in my coffeescript.
Coffeescript takes the src files and turns them into JS files (Currently 3, main.coffee, Person.coffee and Car.coffee)
I want my Nodemon to restart everytime once of those file changes, to run it with the latest saved changes.
Here is the problem: When just 1 coffee file is modified, running coffee will recompile all the coffee files, which in turn generate 3 JS files, which in turn makes nodemon restart 3 times. This is not desirable since im working in an application that uses net requests, and I don't want it to spin out of control.
Would it be possible to make nodemon restart just 1 time?
I thought of concatenating all the JS files, but that messes the modularity of my JS files.
I also thought of "watching" the files 1 by 1, but that can get cumbersome if I reach 50 files.
How can I solve this problem?
module.exports = function(grunt) {
"use strict";
grunt.initConfig({
pkg: grunt.file.readJSON( 'package.json' ),
coffee: {
dist: {
join: true,
expand: true,
flatten: true,
cwd: 'src/dist',
src: ['*.coffee'],
dest: 'dist',
ext: '.js'
},
},
watch: {
dist: {
files: ['src/dist/**/*.coffee'],
tasks: 'coffee'
},
},
concurrent: {
dev: {
tasks: ['nodemon', 'watch'],
options: {
logConcurrentOutput: true
}
}
},
nodemon: {
dev: {
script: 'dist/main.js',
},
options:{
watch: "dist/**/*.js"
}
}
});
grunt.loadNpmTasks('grunt-concurrent');
grunt.loadNpmTasks('grunt-contrib-coffee');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-nodemon');
grunt.registerTask("default", ["coffee", "concurrent"]);
};
You probably need to use the delayTime option. The problem is, it doesn't actually wait for all files to finish, it simply waits some amount of time before restarting, thus preventing multiple restarts.
nodemon: {
dev: {
script: 'dist/main.js',
},
options:{
watch: "dist/**/*.js",
delayTime: 2000
}
}
You can use grunt-newer. Then in the watch task you can specify that you want to compile only files that changed.
watch: {
dist: {
files: ['src/dist/**/*.coffee'],
tasks: 'newer:coffee'
},
}