Change in LESS should trigger a full page reload - gruntjs

I have a grunt-watch task that triggers livereload, when it detects changes to files. However it does not trigger a page reload when I change .less files. On that occasion it only makes the page reload the app.less which updates the styling. This seems to be intended, but for my project it would be more practical to also have a full page reload on that occasion. Can I force grunt-watch to always perform a full page reload?
BR,
Daniel

You can use grunt-touch to trigger a change on your html file:
module.exports = function(grunt) {
grunt.initConfig({
less: {
development: {
files: {"index.css": "test.less"}
}
},
touch: {
options: {
force: true,
mtime: true
},
src: ['index.html'],
},
watch: {
less: {
files: ['*.less'],
tasks: ["less","touch"],
},
livereload: {
options: { livereload: true },
files: ['index.html'],
},
},
}
);
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-touch');
grunt.registerTask( 'default', ["less","watch"] );
};

Related

Grunt Watch LiveReload on site on server

I am developing a WordPress site on a server (not local). I want to refresh the page in my browser whenever I modify a sass file. I've got some grunt tasks listed, but right now I just want it to refresh on any sass modification. Right now, it catches whenever a file is modified, but it does not refresh the page.
Gruntfile:
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
watch: {
scripts: {
options: { livereload: true },
files: ['**/*.scss'],
//tasks: ['criticalcss:front', 'criticalcss:page', 'cssmin', 'postcss'],
}
},
postcss: {
options: {
processors: [
require('autoprefixer')({browsers: 'last 6 versions'}), // add vendor prefixes
//require('cssnano')() // minify the result
]
},
dist: {
src: 'style.css',
dest: 'style.css'
}
},
criticalcss: {
front : {
options: {
url: "https://grandeurflooring.ca/grand_dev/",
minify: true,
width: 1500,
height: 900,
outputfile: "critical_css/critical-front.css",
filename: "style.css",
buffer: 800*1024,
ignoreConsole: true
}
},
page : {
options: {
url: "https://grandeurflooring.ca/grand_dev/sample-page/",
minify: true,
width: 1500,
height: 900,
outputfile: "critical_css/critical-page.css",
filename: "style.css",
buffer: 800*1024,
ignoreConsole: true
}
}
},
cssmin: {
target: {
files: [{
expand: true,
cwd: 'critical_css',
src: ['*.css', '!*.min.css'],
dest: 'critical_css',
ext: '.min.css'
}]
}
}
});
// Load the plugin that provides the "critical" task.
grunt.loadNpmTasks('grunt-criticalcss');
// Load the plugin that provides the "cssmin" task.
grunt.loadNpmTasks('grunt-contrib-cssmin');
// Load the plugin that provides the "watch" task.
grunt.loadNpmTasks('grunt-contrib-watch');
// Load the plugin that provides the "PostCSS" task.
grunt.loadNpmTasks('grunt-postcss');
// Critical task.
grunt.registerTask('critical', ['criticalcss:front']);
};
In footer.php, before wp_footer(), I put the script:
<script src="http://localhost:35729/livereload.js"></script>
You can configure Grunt to watch the compiled css file in your dist directory, which would be updated every time the Sass is recompiled.
Here is my watch configuration which is achieving what you want:
watch: {
options: {
livereload: true,
},
html: {
files: ['index.html'],
},
js: {
files: ['js/**/*.js'],
tasks: ['jshint'],
},
sass: {
options: {
livereload: false
},
files: ['css/scss/**/*.scss'],
tasks: ['sass'],
},
css: {
files: ['dist/css/master.css'],
tasks: []
}
}
You might need to change spawn: false to spawn: true depending on your setup as well.
EDIT: Additionally, you can use the grunt-contrib-watch plugin which allows you to:
Run predefined tasks whenever watched file patterns are added, changed or deleted
This plugin contains numerous additional options for live-reloading, watching, etc. which you may find useful.

Get Grunt to upload files after watch is triggered

I am working on a site that uses SCSS. We have grunt watching those files to convert them to css but each time we make a change we have to tab over to the css file and upload. Maybe not a big deal but over time on different projects it adds up.
I would like the watch process to run ftpush once it see's a change but the only times I've got it to work it stays on ftpush which means we have to exit grunt then run it again. It would be helpful if after the upload os complete(or a specific time passes) it resumes the watch task.
module.exports = function (grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
sass: {
options: {
loadPath: ['bower_components/foundation/scss'],
sourceMap: true
},
dist: {
options: {
style: 'expanded'
},
files: {
'assets/css/app.css': 'assets/scss/app.scss'
}
}
},
ftpush: {
build: {
auth: {
host: 'OUR HOST',
port: 21,
authKey: 'key1'
},
src: '../vhc-master',
dest: '/var/www/html/vhc/dev/wp-content-themes/vhc-master'
}
},
watch: {
scripts: {
files: ['Gruntfile.js'],
tasks: ['ftpush'],
options: {
interrupt: true,
reload: true
}
},
sass: {
files: 'assets/scss/*.scss',
tasks: ['sass']
}
}
});
grunt.loadNpmTasks('grunt-sass');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-ftpush');
grunt.registerTask('build', ['sass']);
grunt.registerTask('deploy', ['ftpush']);
grunt.registerTask('default', ['build','watch']);
}

Grunt concat no errors but doesn't works

Hi Grunt concat doesn't shows errors, but it doesn't concentrate my styles.css file. Here is a screenshot of it:
link: http://i.imgur.com/gHlbROe.png
And here is a screenshot of my css file, which still isn't being concatenated(also you can see my folder structure here below):
link: http://i.imgur.com/UlGWQv1.png
And here is my gruntfile.js (Maybe I should have a different separator in concat_css.):
module.exports = function(grunt) {
grunt.initConfig({
less: {
development: {
options: {
compress: true,
yuicompress: true,
optimization: 2,
css: ['concat']
},
files: {
"css/styles.css": "css/styles.less" // destination file and source file
}
}
},
concat_css: {
options: {
// Task-specific options go here.
separator: '}'
},
all: {
src: ["css/styles.css"],
dest: "css/styles.css"
},
},
watch: {
styles: {
files: ['css/styles.less'], // which files to watch
tasks: ['less', 'concat_css'],
options: {
nospawn: true
}
}
}
});
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-concat-css');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('default', ['less', 'watch', 'concat_css']);
};
I'm pretty sure the task is called concat, not concat_css. You're config will need to match that name (that is, you should not be using concat_css at all). Aside from that, why would you make the separator the closing brace (})? If you ever have more than one file that will almost certainly cause a syntax error in the concatenated CSS file. I would leave out that option unless you have a specific need for it.
concat: { // <-- change this to match the name of the task: "concat"
all: {
src: ["css/styles.css"],
dest: "css/styles.css"
},
},

Grunt SCSS - Not reloading

I am trying to achieve a smooth workflow.
my problem:
My JS modifications are shown and minified and the live reload works fine. When I make changes to my SCSS files they do not run under the run command:
grunt
or the grunt plugin:
grunt watch
It only works when I invoke:
grunt sass
This was the output from the 'grunt sass' console window:
Macintosh:grunt-test Neil$ grunt sass
Running "sass:dist" (sass) task
File "css/global.css" created.
Done, without errors.
Notes:
When I run 'grunt watch' on a sass file I have noticed that grunt runs the minification on the javascript for no reason. Surely this be invoked when that file or one of its dependencies is effected?
Gruntfile.js Contents:
module.exports = function(grunt) {
// 1. All configuration goes here
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
watch: {
options: {
files: ['css/*.css'],
livereload: true
},
css: {
files: ['css/*.scss'],
tasks: ['sass'],
options: {
spawn: false,
}
},
scripts: {
files: ['js/*.js', 'scss/*.scss'],
tasks: ['concat', 'uglify'],
options: {
spawn: false,
}
}
},
sass: {
dist: {
options: {
style: 'compressed'
},
expand: true,
cwd: 'scss/',
src: ['*.scss'],
dest: 'css/',
ext: '.css'
}
},
concat: {
// 2. Configuration for concatinating files goes here.
dist: {
src: [
'js/libs/*.js', // All JS in the libs folder
'js/global.js' // This specific file
],
dest: 'js/build/production.js',
}
},
uglify: {
build: {
src: 'js/build/production.js',
dest: 'js/build/production.min.js'
}
},
imagemin: {
dynamic: {
files: [{
expand: true,
cwd: 'images-lossy/',
src: ['**/*.{png,jpg,gif}'],
dest: 'images/'
}]
},
png: {
options: {
optimizationLevel: 7
}
},
jpg: {
options: {
progressive: true
}
}
}
});
// 3. Where we tell Grunt we plan to use this plug-in.
// CONCATENATION PLUGIN
grunt.loadNpmTasks('grunt-contrib-concat');
// MINIFY PLUGIN
grunt.loadNpmTasks('grunt-contrib-uglify');
// IMG CRUSH PLUGIN
grunt.loadNpmTasks('grunt-contrib-imagemin');
// GRUNT WATCH PLUGIN
grunt.loadNpmTasks('grunt-contrib-watch');
// SASS LIBARY PLUGIN
grunt.loadNpmTasks('grunt-contrib-sass');
// 4. Where we tell Grunt what to do when we type "grunt" into the terminal.
grunt.registerTask('default', ['sass','concat', 'uglify', 'imagemin', 'watch']);
};
I hope the above information helps. I have previously used Codekit, and it a really great app. I want to move to grunt but maybe my configuration file is incorrect I am close.
Any help would be greatly appreciated.
Neil
It looks like both of your issues occur within the watch configuration.
First, the reason the SASS task isn't working during watch is due to the files entry pointing to the wrong location. Your current files entry points to the "css" folder, but it should point to the "scss" folder, according to what you've specified in the actual "sass" task. In other words, your entry should be: files: ['scss/*.scss'].
css: {
files: ['scss/*.scss'],
tasks: ['sass'],
options: {
spawn: false,
}
}
Second, the JavaScript minification occurs during the watch whenever a SASS file changes because you have it listed here:
scripts: {
files: ['js/*.js', 'scss/*.scss'], // <-- scss is covered here
tasks: ['concat', 'uglify'],
options: {
spawn: false,
}
}
Change it to files: ['js/*.js'], instead to have the watch task kick in for JavaScript files only.
Once you address those issues, if things are slightly working you might want to expand the patterns so that it covers all files in the subdirectories for your JavaScript, CSS, SASS, etc. For example, js/*.js includes all .js files under the js folder, while js/**/*.js covers the js folder and its subfolders. You can read more under the GruntJS "globbing patterns" documentation.
EDIT: here's how the updated watch should look like...
watch: {
options: {
livereload: true
},
// css is really for Sass
css: {
files: ['scss/*.scss'],
tasks: ['sass'],
options: {
spawn: false,
}
},
// scripts will detect js changes
scripts: {
files: ['js/**/*.js'],
tasks: ['jshint', 'concat', 'uglify'],
options: {
spawn: false,
}
}
},
As mentioned, your individual tasks might need to use the ** pattern similar to what I've done with the "scripts" entry above: js/**/*.js

Grunt - lint only modified files using grunt-newer

I'm running a Grunt task that uses Concurrent to run both Nodemon and Watch/Livereload. On default load, I lint and launch Concurrent. I would also like to set up a Watch to lint individual files on change. Currently, all files are linted when any one file is changed.
I have examined a similar question on StackOverflow and decided to go with grunt-newer as a potential solution. In my implementation below, however, the 'newer' prefix doesn't seem to do anything. How can I fix this so that only changed files are linted?
module.exports = function(grunt) {
//load all dependencies
require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
concurrent: {
dev: {
options: {
logConcurrentOutput: true
},
tasks: ['watch', 'nodemon']
}
},
jshint: {
files: ['Gruntfile.js', 'client/src/*.js', 'server/**/*.js'],
options: {
'-W030': true,
'-W083': true,
globals: {
console: true,
module: true,
document: true
}
}
},
watch: {
all: {
files: ['<%= jshint.files %>'],
tasks: ['newer:jshint']
},
frontend: {
files: ['client/**/*.{css,js,html}'],
options: {
livereload: true
}
}
},
nodemon: {
dev: {
options: {
file: 'server/server.js',
watchedFolders: ['server']
}
}
}
});
grunt.registerTask('test', ['jshint']);
grunt.registerTask('default', ['jshint', 'concurrent']);
};
I was having the same problem and finally figured it out. The solution is hidden deep in the documentation and very misleading with the spawn option in the code sample: https://github.com/gruntjs/grunt-contrib-watch#compiling-files-as-needed
Your config file should remain the same as you have it in your question, but you need to add a listener to the watch event. I recommend the 'robust' option they provide (modified for you specific task config). Place this code just above the call to grunt.initConfig and after you require calls.
var changedFiles = Object.create(null);
var onChange = grunt.util._.debounce(function() {
// Modified to point to jshint.files as per the task example in the question.
grunt.config('jshint.files', Object.keys(changedFiles));
changedFiles = Object.create(null);
}, 200);
grunt.event.on('watch', function(action, filepath) {
changedFiles[filepath] = action;
onChange();
});
Add the nospawn option to the all watch task. This is what is misleading in in the documentation. It mentions it should be disabled if you want dynamically modify your config but basically prevents it from working with newer unless it's set to true:
watch: {
all: {
files: ['<%= jshint.files %>'],
tasks: ['newer:jshint'],
options: {
nospawn: true,
}
},
...
NOTE: If you modify your grunt file while it's running then it will lint all files, not sure why it does this but then it gets stuck and will just keep linting everything for all changes you make. I just took out the 'gruntfile.js' from the list of files that should be linted to avoid it.

Resources