grunt watch executes tasks multiple times - javascript

I've the following Grunfile.js File:
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
sass: {
dist: {
options: {
style: 'compressed'
},
files: {
'css/build/style.css': 'css/style.scss'
}
}
},
watch: {
stylesheets: {
files: ['css/*.scss'],
tasks: ['newer:sass']
}
}
});
// Load the plugin that compiles sass
grunt.loadNpmTasks('grunt-contrib-sass');
// watch for, and run grunt if files change
grunt.loadNpmTasks('grunt-contrib-watch');
// Plugin for Grunt tasks to run with newer files only.
grunt.loadNpmTasks('grunt-newer');
// Grunt Tasks:
grunt.registerTask('default', ['newer:sass']);
};
After running grunt watch and saving my scss File, the console output is the following:
Running "watch" task
Waiting...
>> File "css\style.scss" changed.
Running "newer:sass" (newer) task
Running "newer:sass:dist" (newer) task
Running "sass:dist" (sass) task
File css/build/style.css created.
Running "newer-postrun:sass:dist:1:D:\xampp\htdocs\grunt-test\node_modules\grunt-newer\.cache" (newer-postrun) task
Done, without errors.
The problem is, the .scss file is compiled every time. Even if there was no change.
I don't understand why grunt is running 3 tasks (newer:sass, newer:sass:dist, sass:dist), instead of only running the task defined under watch (newer:sass).
Hope someone has an idea to fix this. :)

I'm not positive this is the problem, but try specifying that you don't want to run all of sass, just sass:dist. So try: grunt.registerTask('default', ['newer:sass:dist']);

Related

How to use ng-annotate directions

how exactly do you run ng-annotate from the command line? Im trying to minify angular, angular_routes and my own script.js into one file. Ive tried grunt uglify:app1 but it gives the injection error. My own code works when minified by itself but not when combined with the angular scripts.here is the grunt file
grunt.initConfig({
ngAnnotate: {
options: {
singleQuotes: true,
},
app1: {
files: {
'min.js': ['angular.js','angular_routes.js','script.js'],
},
},
},
});
grunt.loadNpmTasks('grunt-ng-annotate');
I dont know what the command is to run it.
Add this to your grunt file:
grunt.registerTask('default', ['ngAnnotate']);
And then just run grunt in the console

Grunt switch task between dev and prod

I have a grunt file I am trying to see if I can split so I can call something like grunt build:dev or grunt build:prod.
Right now the task looks like this -
grunt.registerTask('build', "Building all needed files.", [
'clean:build',
'check-code',
'clean:dist',
'dist:prepare',
'copy',
'cssmin',
'injector',
'webpack:prod',
'create-status-page'
]);
And I am wondering if there is a way to split this task like you can with configs with a key of dev and prod, where the task list for prod it slight different than dev. Sort of similiar to how you might do it with tha configs like
return {
dev: {
...
},
prod: {
...
}
}
Is something like this possible? To be clear, I am asking if I can get away with registering both these in a single task.
You may be able to use a multitask.
grunt.initConfig({
build: {
dev: ['task1', 'task2', 'task3'],
prod: ['taskA', 'taskB', 'taskC']
}
});
grunt.registerMultiTask('build', 'Building...', function() {
grunt.task.run(this.data);
});
Then you can do grunt build:dev or grunt build:prod
Note: If you just do grunt build, it will iterate through all of the properties, so it would run both dev tasks and prod tasks.

Grunt watch task binding in Visual Studio 2015

Problem: I have a problem to configure binding for grunt watch task to always run in Visual Studio 2015.
My goal: I want to watch files for changes and once the change occurs I want to run some task and then resume watch task to look for further changes.
What I have tried so far:
I have set binding for watch task on 'ProjectOpened', but it only
does work then until I build my project. Once I build/rebuild my project the
watch task stops handling the changes of tracked files.
I have tried binding my watch task to 'AfterBuild' and 'BeforeBuild', but having
that set, the build operation hangs forever in Visual Studio (it just never ends).
Here's my gruntfile.js:
/// <binding AfterBuild='default' ProjectOpened='watch' />
module.exports = function (grunt) {
grunt.loadNpmTasks('grunt-bower-task');
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.initConfig({
bower: {
install: {
options: {
targetDir: 'wwwroot/vendor',
layout: 'byComponent',
install: true,
cleanTargetDir: true,
}
}
},
less: {
development: {
files: { 'wwwroot/navbar.css': 'LessStyleSheets/navbar.less' }
}
},
watch: {
options: {
interrupt: true
},
files: ['LessStyleSheets/navbar.less'],
tasks: ['less']
}
});
grunt.registerTask('default', ['bower:install', 'less']);
};
Any help will be appreciated.
Apparently, the problem solved itself... After restarting Visual Studio the problem disappeard and the build process no longer hangs after running grunt watch task.

Grunt watch for tasks instead for files?

I`m new to Grunt and I saw a few tutorials about watch plugin. The example:
watch:{
sass:{
files: 'sass/*.scss',
tasks: ['sass','cssmin']
}
}
My question is why do I need to watch about another plungin like "sass" instead of watching the actual file(s) 'sass/*.scss'?
I don`t understand, it is not logical to watch a plugin/task, rather than a file.
Why I can`t call like this:
watch:{
files: 'sass/*.scss',
tasks: ['sass','cssmin']
}
?
And what if I want to also watch about my js file? Do I need to put it also in the files of the sass tasks? It does not make sense to have js files into sass task...
You're by no means watching a plugin. Suppose you have another plugin less, which you want to work on a different set of files. How will you do it?
watch {
sass: ...
less: ...
uglify: ...
}
Even if you put js files with sass (ignoring that it is horrible practice), when grunt calls sass on that file, nothing will happen.
As an example
module.exports = function (grunt) {
grunt.initConfig({
jshint: {
// ...
},
uglify: {
// ...
},
sass: {
// ...
},
foo: {
// ...
},
watch: {
javascript: {
files: 'javascripts/*/**.js',
tasks: ['jshint', 'uglify']
},
sass: {
files: 'sass/*/**.scss',
tasks: ['sass', 'foo']
}
}
});
// ...
};
There are different watchers for js, like uglify.
It's not that you're "watching" that plugin, it's that you're watching a set of files and running tasks when the files changes. the tasks specification is where you specify what tasks you need. So in this case you would run the sass and cssmin tasks.
The watch plugin watches files matching the pattern specified by files section. Whenever any of the matching files are changed, the tasks mentioned in tasks is executed.
For example, let us consider the watch task in your question
watch:{
sass:{
files: 'sass/*.scss',
tasks: ['sass','cssmin']
}
}
Here, sass is just a name given to the operation. It can be anything; but since the operation compiles Saas files, the operation is named saas.
Whenever any scss file in sass directory is changed, the operation saas is triggered, executing the saas and cssmin tasks, which should be defined earlier.
References:
Getting Started - Grunt: The JavaScript Task Runner

Write Grunt task to console

This is relevant to any Grunt task which has a source file and a destination (output file).
When I run grunt in my command line, I don't want Grunt to write anything to file, I just want to view (return) the output to my console, be it Bash, CMD or any CLI.
Lets take uglify for example.
module.exports = function(grunt) {
grunt.initConfig({
uglify: {
options: {
mangle: true,
sourceMap: true,
},
build: {
src: 'js/foo.js',
dest: 'js/foo.min.js' <-- Don't need this.
}
}
});
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.registerTask('default', ['uglify']);
};
Instead of Done, without errors, when successful, I want to view the uglifed code in the console.
For context, I need this for a command line application which won't need anything written to disk. I just need to use the output on the fly (I'm trying to avoid writing to file and re-reading from the CLI).
You could write directly to /dev/stdout ( not on windows tough ):
build: {
src: 'js/foo.js',
dest: '/dev/stdout'
}

Categories

Resources