can you please take a look at the following Gruntfile to see if you can determine why it isn't running cssnano and autoprefixer?
Grunt is currently watching my project and with each save grunt-sass compiles fine but neither grunt-cssnano or autoprefixer are doing their thing and no errors are reported.
Done, without errors.
Completed in 1.906s at Wed Nov 25 2015 13:12:18 GMT+0000 (GMT Standard Time) - Waiting...
File "sass\styles.scss" changed.
Running "sass:dist" (sass) task
I figure I've done something wrong with grunt-contrib-watch setup (specifically the css part) but that's just a guess.
My project folder looks like so
dist
css
styles.css
node_modules (includes all relevant packages)
sass
styles.css
Gruntfile.js
package.json
And my Gruntfile is as follows
module.exports = function (grunt) {
grunt.initConfig({
sass: {
options: {
sourceMap: false
},
dist: {
files: {
'dist/css/styles.css': 'sass/styles.scss'
}
}
},
postcss: {
options: {
map: {
inline: false,
annotation: 'dist/css/maps/'
},
processors: [
require('autoprefixer')({
browsers: 'last 2 versions'
}),
require('cssnano')()
]
},
dist: {
src: 'dist/css/styles.css'
}
},
watch: {
sass: {
files: 'sass/*.scss',
tasks: ['sass']
},
css: {
files: 'dist/css/styles.css',
tasks: ['cssnano', 'autoprefixer']
}
},
});
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-sass');
grunt.loadNpmTasks('grunt-postcss');
grunt.loadNpmTasks('grunt-cssnano');
grunt.registerTask('default', ['watch', 'sass', 'postcss:dist', 'cssnano', 'autoprefixer']);
};
registering a task like you do :
grunt.registerTask('default', ['watch', 'sass', 'postcss:dist', 'cssnano']);
will execute the tasks one by one. So in your case, only the watch task will be executed because it "never ends" till you finish it. So the sass, postcss:dist, cssnano wont be reached.
So in your case it will execute the watch task only, which will watch the *.scss files to execute the sass task and watch the style.css to execute the cssnano and autoprefixer task.
But these 2 last tasks aren't defined in your config, so it won't do anything.
To solve your problem, remove the tasks from your default registered task because they aren't used :
grunt.registerTask('default', ['watch']);
And add a config for each missing task. for example:
cssnano: {
options: {
sourcemap: true
},
dist: {
files: {
'dist/css/styles.min.css': 'dist/css/styles.css'
}
}
},
//and same for autoprefixer
With a lot more trial and error it looks like I have a solution. The below file now runs Sass, cssnano, autoprefix and watch. Sass, cssnano and autoprefix packets (and I assume any others that are added in future) will do their thing in grunt.initConfig while and at the bottom of the file registerTask takes care of watch.
More work is need to figure out how to create other registerTasks but that's for another day.
Thanks to Mian who set me on the right track.
module.exports = function (grunt) {
grunt.initConfig({
sass: {
options: {
sourceMap: false
},
dist: {
files: {
'dist/css/styles.css': 'sass/styles.scss'
}
}
},
postcss: {
options: {
map: {
inline: false,
annotation: 'dist/css/maps/'
},
processors: [
require('autoprefixer')({
browsers: 'last 2 versions'
}),
require('cssnano')()
]
},
dist: {
src: 'dist/css/styles.css'
}
},
watch: {
sass: {
files: 'sass/*.scss',
tasks: ['sass', 'postcss']
},
},
});
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-sass');
grunt.loadNpmTasks('grunt-postcss');
grunt.loadNpmTasks('grunt-cssnano');
grunt.registerTask('default', ['watch']);
};
Related
I am using grunt-contrib-watch and this sublime package sublime-grunt.
I am using the sublime-grunt package to start a watch session and livereload with the Chrome extension. Everything works great however once a 'watch' session is started what is the command to stop/kill/cancel a watch. I tried using a command in the sublime-grunt package called 'Grunt Kill Running Processes' and it tells me something has been canceled but if I change my style.scss file and save it, it compiles and updates are made to my html page, so 'watch' is still in effect. Right now I have to close down Sublime Text to kill the 'watch' session.
I am trying to use a variable for a path to my theme root directory but when I try to concat the variable with a string I received this error. What type of syntax should I use, do I need to create a variable in the package.json file?
Code
var theme_path = 'wp-content/themes/twentyfifteen/';
// Sass plugin
sass: {
dist: {
files: {
theme_path + 'style.css': theme_path + 'sass/style.scss',
}
}
},
// Error
Loading "Gruntfile.js" tasks...ERROR
>> SyntaxError: C:\wamp\www\grunt\Gruntfile.js:31
>> theme_path + 'style.css': 'wp-content/th
emes/twentyfifteen/sass/style.scs
>> ^
>> Unexpected token +
Warning: Task "default" not found. Use --force to continue.
Here is my Gruntfile.js:
module.exports = function(grunt) {
// Theme Directory Path
var theme_path = 'wp-content/themes/twentyfifteen/';
// Configure main project settings
grunt.initConfig({
// Basic settings and info about our plugins
pkg: grunt.file.readJSON('package.json'),
// Watch Plugin
watch: {
sass: {
files: 'wp-content/themes/twentyfifteen/sass/*.scss',
tasks: ['sass','postcss','uglify'],
options: {
livereload: true,
},
},
},
// Sass plugin
sass: {
dist: {
files: {
'wp-content/themes/twentyfifteen/style.css': 'wp-content/themes/twentyfifteen/sass/style.scss',
}
}
},
// Postcss plugin
postcss: {
options: {
map: true, // inline sourcemaps
// or
map: {
inline: false, // save all sourcemaps as separate files...
},
processors: [
require('pixrem')(), // add fallbacks for rem units
require('autoprefixer')({browsers: 'last 2 versions'}), // add vendor prefixes
require('cssnano')() // minify the result
]
},
dist: {
src: 'wp-content/themes/twentyfifteen/style.css'
}
},
// Minify JS Uglify
uglify: {
dist: {
files: {
'wp-content/themes/twentyfifteen/js/functions.min.js': ['wp-content/themes/twentyfifteen/js/functions.js']
}
}
}
});
// Load the plugin
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.loadNpmTasks('grunt-postcss');
grunt.loadNpmTasks('grunt-contrib-uglify');
// Run plugin
grunt.registerTask('default', ['watch'] );
}
I think that tasks options can't have variable assigned, i don't have any source at the moment but i can suggest another way to do it:
you can use task params:
watch: {
sass: {
files: '<%= grunt.task.current.args[0] %>/sass/*.scss',
tasks: ['sass:<%= grunt.task.current.args[0] %>','postcss','uglify'],
options: {
livereload: true,
},
},
},
sass: {
dist: {
files: {
'<%= grunt.task.current.args[0] %>/style.css': '<%= grunt.task.current.args[0] %>/sass/style.scss',
}
}
},
and than
grunt.registerTask('default', ['watch:'+theme_path] );
This is a problem that i have already meet to make dynamic watch tasks
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']);
}
I'm still rather new to Grunt so maybe someone with more experience can help me with this. For some reason anytime I run grunt watch the uglify task is getting executed multiple times so my scripts.min.js file is getting compiled multiple times.
This is what my Gruntfile.js currently looks like:
'use strict';
module.exports = function(grunt) {
// Show elapsed time
require('time-grunt')(grunt);
// Comment out any unused components
var jsFiles = [
//'assets/vendor/bootstrap-sass-official/assets/javascripts/bootstrap/affix.js',
//'assets/vendor/bootstrap-sass-official/assets/javascripts/bootstrap/alert.js',
//'assets/vendor/bootstrap-sass-official/assets/javascripts/bootstrap/button.js',
//'assets/vendor/bootstrap-sass-official/assets/javascripts/bootstrap/carousel.js',
'assets/vendor/bootstrap-sass-official/assets/javascripts/bootstrap/collapse.js',
//'assets/vendor/bootstrap-sass-official/assets/javascripts/bootstrap/dropdown.js',
//'assets/vendor/bootstrap-sass-official/assets/javascripts/bootstrap/modal.js',
//'assets/vendor/bootstrap-sass-official/assets/javascripts/bootstrap/popover.js',
//'assets/vendor/bootstrap-sass-official/assets/javascripts/bootstrap/scrollspy.js',
//'assets/vendor/bootstrap-sass-official/assets/javascripts/bootstrap/tab.js',
//'assets/vendor/bootstrap-sass-official/assets/javascripts/bootstrap/tooltip.js',
'assets/vendor/bootstrap-sass-official/assets/javascripts/bootstrap/transition.js',
'assets/js/*.js'
];
// Configure tasks.
grunt.initConfig({
sass: {
dist: {
options: {
style: 'compressed'
},
files: {
'assets/css/main.min.css': 'assets/sass/app.scss',
'assets/css/custom-login.min.css': 'assets/sass/_login.scss',
'assets/css/magnific.min.css': 'assets/sass/plugins/magnific/magnific.scss'
}
}
},
uglify: {
dist: {
files: {
'assets/js/scripts.min.js': [ jsFiles ]
}
}
},
watch: {
sass: {
files: [ 'assets/sass/*.scss' ],
tasks: [ 'sass' ]
},
js: {
files: [ jsFiles ],
tasks: [ 'uglify' ]
}
}
});
// Load tasks.
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-sass');
// Register tasks.
grunt.registerTask('default', [
'watch',
'sass',
'uglify'
]);
};
Anyone have any ideas why the uglify task is executing multiple times?
The problem is that you have all the js files to inspect and minify. The main problem is:
'assets/js/*.js'
You are compressing all the js files, but also you are watching then, so when you uglify all the js files, they changed, and for that reason the watch task executes and minify again....and that's the infinite loop.
You should change your gruntfile, for example removing scripts.min.js of the assets folder, or removimg assets/js/*.js and adding manually all your js files. I recommend apply the second one.
'use strict';
module.exports = function(grunt) {
// Show elapsed time
require('time-grunt')(grunt);
// Comment out any unused components
var jsFiles = [
//'assets/vendor/bootstrap-sass-official/assets/javascripts/bootstrap/affix.js',
//'assets/vendor/bootstrap-sass-official/assets/javascripts/bootstrap/alert.js',
//'assets/vendor/bootstrap-sass-official/assets/javascripts/bootstrap/button.js',
//'assets/vendor/bootstrap-sass-official/assets/javascripts/bootstrap/carousel.js',
'assets/vendor/bootstrap-sass-official/assets/javascripts/bootstrap/collapse.js',
//'assets/vendor/bootstrap-sass-official/assets/javascripts/bootstrap/dropdown.js',
//'assets/vendor/bootstrap-sass-official/assets/javascripts/bootstrap/modal.js',
//'assets/vendor/bootstrap-sass-official/assets/javascripts/bootstrap/popover.js',
//'assets/vendor/bootstrap-sass-official/assets/javascripts/bootstrap/scrollspy.js',
//'assets/vendor/bootstrap-sass-official/assets/javascripts/bootstrap/tab.js',
//'assets/vendor/bootstrap-sass-official/assets/javascripts/bootstrap/tooltip.js',
'assets/vendor/bootstrap-sass-official/assets/javascripts/bootstrap/transition.js'
];
// Configure tasks.
grunt.initConfig({
sass: {
dist: {
options: {
style: 'compressed'
},
files: {
'assets/css/main.min.css': 'assets/sass/app.scss',
'assets/css/custom-login.min.css': 'assets/sass/_login.scss',
'assets/css/magnific.min.css': 'assets/sass/plugins/magnific/magnific.scss'
}
}
},
uglify: {
dist: {
files: {
'assets/js/scripts.min.js': [ jsFiles ]
}
}
},
watch: {
sass: {
files: [ 'assets/sass/*.scss' ],
tasks: [ 'sass' ]
},
js: {
files: [ jsFiles ],
tasks: [ 'uglify' ]
}
}
});
// Load tasks.
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-sass');
// Register tasks.
grunt.registerTask('default', [
'watch',
'sass',
'uglify'
]);
};
Regards.
I'm trying to get grunt-browser-sync to inject any css changes into an open browser when a file is updated/changed. But for some reason, I can seem to get it to work and grunt is not giving me any errors to let me know it's not working.
I'm currently using MAMP since it's a Wordpress based project.
Here's my Gruntfile.js:
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
uglify: {
build: {
src: '_/js/libs/*.js', //input
dest: '_/js/functions.min.js' //output
}
},
sass: {
dist: {
options: {
loadPath: require('node-bourbon').includePaths,
loadPath: require('node-neat').includePaths,
style: 'compressed'
},
files: {
'style.css': 'scss/style.scss'
}
}
},
autoprefixer: {
dist: {
files: {
'style.css': 'style.css'
}
}
},
browserSync: {
dev: {
bsFiles: {
src : 'style.css'
},
options: {
watchTask: true
}
}
},
watch: {
options: {
livereload: true
},
js: {
files: ["_/js/libs/*.js"],
tasks: ["ugilify"],
},
sass: {
files: ["scss/*.scss"],
tasks: ["sass", "autoprefixer", "browserSync"],
},
php: {
files: ['*.php']
},
}
});
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-autoprefixer');
grunt.loadNpmTasks('grunt-browser-sync');
// Default task(s).
grunt.registerTask('default', ['uglify', 'sass', 'browserSync', 'watch', 'autoprefixer']);
};
and here's the output when I save/update a file:
Running "watch" task
Waiting...
>> File "scss/global.scss" changed.
Running "sass:dist" (sass) task
File style.css created.
Running "autoprefixer:dist" (autoprefixer) task
File style.css created.
Running "browserSync:dev" (browserSync) task
Done, without errors.
Completed in 1.478s at Wed May 07 2014 18:47:40 GMT-0500 (CDT) - Waiting...
But then I have to physically refresh the browser to see the changes.
I'm not sure if I am missing something within the grunt file or what.
The only version of grunt-browser-sync that works for me with this code is 1.9.1. So, un-install your current version and
npm install grunt-browser-sync#1.9.1 --save-dev
I encountered the same issue and have opened an issue here
Github grunt-browser-sync repo with issues 58
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