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
Related
I've started to learn this just now. I installed the grunt.
If I get grunt watch it is automatic but only in case one file.
How could I make it wath all scss file in my theme, and make the css in different folders.
I don't really undestand how could it working in big.
This is my gruntfile.js now:
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
connect: {
uses_defaults: {}
},
sass: {
dev: {
options: { sourceMap: true },
files: { 'sites/all/themes/uj/css/uj.styles.css' : 'sites/all/themes/uj/sass/uj.styles.scss' }
}
},
watch: {
css: {
files: 'sites/all/themes/uj/**/*.scss',
tasks: [ 'sass:dev' ],
options: { livereload: true }
}
}
});
// Load Grunt plugins
// grunt.loadNpmTasks('');
// Default task(s).
grunt.registerTask('default', []);
// Load Grunt plugins
grunt.loadNpmTasks('grunt-contrib-connect');
grunt.loadNpmTasks('grunt-sass');
grunt.loadNpmTasks('grunt-contrib-watch');
};
Per the official documentation on file globbing, to watch for changes for files of a certain file type in the directory path and its subdirectories, you'll want:
files: ['js/**/*.js']
or:
files: ['css/**/*.*']
I'm trying to build a Grunt task that minifys my JS files and return a single minified JS file.
This is my gruntfile.js file:
module.exports = function (grunt) {
// Project configuration.
grunt.initConfig({
minified: {
files: {
src: [
'js/*.js',
],
dest: 'js/min/'
},
options: {
allinone: true
}
},
});
grunt.loadNpmTasks('grunt-minified');
};
When I run the task it does work, but it also returns an error.
> cmd.exe /c grunt -b "C:\Users\alucardu\documents\visual studio 2015\Projects\JS-demo\JS-demo" --gruntfile "C:\Users\alucardu\documents\visual studio 2015\Projects\JS-demo\JS-demo\Gruntfile.js" minified
Running "minified:files" (minified) task
Warning: Cannot read property 'yellow' of undefined Use --force to continue.
Process terminated with code 3.
Aborted due to warnings.
I've done a search action in my entire solution for 'yellow' but it doesn't return any results. Also when I empty both my JS files that are being minified it still returns the error.
Does anyone know why it's returning this error?
By removing the
options: {
allinone: true
}
The warning no longer showed up, but it also doesn't concat the files together. So I've added another task called concat. So now my gruntfile looks like this:
module.exports = function (grunt) {
// Project configuration.
grunt.initConfig({
watch: {
scripts: {
files: ['js/*.js'],
tasks: ['concat', 'minified', 'uglify'],
},
},
concat: {
dist: {
src: ['js/*.js'],
dest: 'js/min/concat.js'
},
},
minified: {
files: {
src: ['js/min/concat.js'],
dest: 'js/min/minified.js'
},
},
uglify: {
my_target: {
files: {
'js/min/uglify.js': ['js/min/minified.jsconcat.js']
}
}
},
});
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-minified');
grunt.loadNpmTasks('grunt-contrib-uglify');
};
And it seems to be working fine.
For some reason running grunt from the terminal doesn't work. When I run grunt dev and open http://localhost:8000/ it works, but when I just use grunt it says This site can’t be reached. localhost refused to connect.
Any ideas what I am missing?
'use strict';
var path = require('path');
var lrSnippet = require('grunt-contrib-livereload/lib/utils').livereloadSnippet;
var folderMount = function folderMount(connect, point) {
return connect.static(path.resolve(point));
};
module.exports = function (grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
clean: {
build: {
src: [".sass-cache"]
}
}, // end clean
sass: {
dist: {
options: {
style: 'expanded',
noCache: true
},
files: {
'app/production/css/style.css': 'app/scss/style.scss'
}
}
}, // end sass
cssmin: {
target: {
files: [{
expand: true,
cwd: 'app/production/css',
src: ['*.css', '!*.min.css'],
dest: 'app/production/css',
ext: '.min.css'
}]
}
}, //end cssmin
connect: {
server: {
options: {
port: 8000
}
}
}, // end connect
uglify: {
options: {
mangle: false
},
my_target: {
files: {
'app/production/js/app.min.js': ['app/js/module.js', 'app/js/config.js', 'app/js/factory.js', 'app/js/filter.js', 'app/js/PotatoAppController.js']
}
}
}, // end js minify
watch: { // this is a watcher, to run this in terminal write: grunt watch
options: {
dateFormat: function(time) {
grunt.log.writeln('The watch finished in ' + time + 'ms at' + (new Date()).toString());
grunt.log.writeln('Waiting for new changes ...');
},
livereload: true
},
css: {
files: 'app/scss/style.scss',
tasks: ['sass', 'cssmin']
},
jsmin: {
files: 'app/js/*.js',
tasks: ['uglify']
},
html: {
files: ['app/views/**/*.html'],
options: {
livereload: true
}
}
} // end watch
});
grunt.loadNpmTasks('grunt-contrib-watch'); // Load the plugin that provides the "watch" task.
grunt.loadNpmTasks('grunt-contrib-cssmin'); // Load the plugin that provides the "cssmin" task.
grunt.loadNpmTasks('grunt-contrib-sass'); // Load the plugin that provides the "sass" task.
grunt.loadNpmTasks('grunt-contrib-uglify'); // Load the plugin that provides the "uglify" task.
grunt.loadNpmTasks('grunt-contrib-livereload'); // Load the plugin that provides the "livereload" task.
grunt.loadNpmTasks('grunt-contrib-connect'); // Load the plugin that provides the "connect" task.
grunt.loadNpmTasks('grunt-contrib-clean'); // Load the plugin that provides the "clean" task.
grunt.registerTask('default', ['watch']); // this is the default command, use in terminal 'grunt'
grunt.registerTask('dev', ['connect', 'sass', 'cssmin', 'uglify', 'clean', 'watch']); // use 'grunt dev' for development
};
Once you execute 'grunt', 'default' command will be executed.
In your case, only 'watch' task is executed.
grunt.registerTask('default', ['watch']);
If you want to reach 'localhost', you need to run 'connect' module.
'watch' task is just watching file changes. not launch web-server.
'connect' is for launching web-server.
Thanks.
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']);
};
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