Grunt with compass not compiling - gruntjs

Hi I'm new to grunt and I'm having a problem getting it up and running with compass.
This is my Gruntfile:
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
//Read the package.json (optional)
pkg: grunt.file.readJSON('package.json'),
// Metadata.
meta: {
sassPath: 'templates/sass/',
cssPath: 'public/css/',
},
// Task configuration.
compass: {
dist: {
files: {
'<%= meta.cssPath %>*.css': '<%= meta.sassPath %>**/*.scss'
}
}
},
});
// These plugins provide necessary tasks.
grunt.loadNpmTasks('grunt-contrib-compass');
// Default task.
grunt.registerTask('default', ['compass']);
}
But when I run grunt --verbose I get this:
...
Running "default" task
Running "compass" task
Running "compass:dist" (compass) task
Verifying property compass.dist exists in config...OK
Files: templates/sass/ie.scss, templates/sass/print.scss, templates/sass/screen.scss, templates/sass/style.scss -> public/css/*.css
Options: (none)
Nothing to compile. If you're trying to start a new project, you have left off the directory argument.
Run "compass -h" to get help.
Done, without errors.
So it looks like it sees the files, and even sees where to put them... what is going wrong?
EDIT: Just so people know the final answer... I thought I had tried this before without success, but this morning I ended up getting this to work:
compass: {
dist: {
expand: true,
cwd: '<%= meta.scssPath %>',
src: ['{,*/}*.scss'],
dest: '<%= meta.cssPath %>',
ext: '.css'
}
},
EDIT 2: Okay, for the life of me don't know why, but it only works when a config.rb was present... why would grunt use the compass config is another question...

I think the issue is your destination file. You have to specify an actual file, not *.css. Try tweaking your config slightly:
compass: {
dist: {
files: {
'<%= meta.cssPath %>compiled.css': '<%= meta.sassPath %>**/*.scss'
}
}
}

Related

No images being compressed using grunt-contrib-imagemin

I'm having trouble using grunt-contrib-imagemin, insofar as I can't get it to compress any images.
Here's my Gruntfile.js
module.exports = function(grunt) {
// 1. All configuration goes here
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
concat: {
dist: {
src: [
'css/{base,global,medium,large}.css', // All CSS in the CSS folder
],
dest: 'css/build/production.css',
}
},
cssmin: {
build: {
src: 'css/build/production.css',
dest: 'css/build/production.min.css'
}
},
imagemin: {
dynamic: {
files: [{
expand: true,
cwd: 'if3/images',
src: ['**/*.{png,jpg,gif}'],
dest: 'images/build'
}]
}
}
});
// 3. Where we tell Grunt we plan to use this plug-in.
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.loadNpmTasks('grunt-contrib-imagemin');
// 4. Where we tell Grunt what to do when we type "grunt" into the terminal.
grunt.registerTask('default', ['concat', 'cssmin', 'imagemin']);
}
When I run grunt from the command line, each of concat and cssmin run fine, whereas imagemin - although running without errors - returns the following message.
Running "imagemin:dynamic" (imagemin) task
Minified 0 images (saved 0 B)
For info, my folder structure is as follows.
if3\
css\
*.css
images\
*.png
*.jpg
js\
*.js
node_modules\
etc.
Gruntfile.js
package.json
*.html
The image folder currently contains 7 PNG and 2 JPG files, but I can't figure out why it's not doing anything with them.
Any help much appreciated.
Thanks
your src-properties in your concat and cssmin tasks do not contain if3. your imagemin config does. removing that should probably help...
imagemin: {
dynamic: {
files: [{
expand: true,
cwd: 'images',
src: ['**/*.{png,jpg,gif}'],
dest: 'images/build'
}]
}
}
you don't need use: dynamic {} or static {} and will works perfect.
see: Grunt imagemin running but not minifying

Grunt watch: Not triggering any task

I am trying to automate my workflow with the help of Grunt. I have everything set up, but the watch task is not working - I can start it, but it doesn't detect changes. The problem really must be in the watch task, as I can trigger the sass task by hand and it compiles correctly without problems.
My Gruntfile looks like this:
module.exports = function (grunt) {
require('load-grunt-tasks')(grunt);
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
sass: {
dist: {
options: {
'style': 'compressed'
},
expand: true,
cwd: './sass/',
src: 'style.scss',
dest: './css/',
ext: '.css'
},
dev: {
options: {
'style': 'expanded',
},
expand: true,
cwd: './sass/',
src: 'style.scss',
dest: './css/',
ext: '.css'
}
},
watch: {
sass: {
files: ['<%= sass.dev.src %>'],
tasks: ['default']
}
}
});
grunt.registerTask('default', ['sass:dev']);
};
The structure in the project directory looks like this:
Gruntfile.js
index.html
package.json
css
> style.css (created by sass task)
node_modules
> all required modules
sass
> style.scss
To me everything looks good, but as it is not working something must be wrong. My guess it that the paths following the 'expand' option are off, although I already tried other structures that didn't work either.
Because sass.dev.src equals src: 'style.scss'. The watch task configured with files: ['<%= sass.dev.src %>'] will try and watch ./style.scss and not ./sass/style.scss.
The watch task has a cwd option (options:{cwd:'./sass'}) but probably easier to just set it to watch files: ['sass/*.scss'] instead.

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 - doesn't give any output

I have installed grunt-cli,grunt(local),grunt-init. Below is the simple grunt file to minify javascript files in source folder.
module.exports = function (grunt) {
grunt.initConfig({
min: {
dev: {
src: 'calculator/*.js',
dest: 'calculator.min.js'
}
}
});
};
when I run grunt, it does nothing, nor it gives any message out. nor does grunt --help or grunt --version..none of them seem to say anything. but if I dont' have grunt.js file it does complain about the grunt file not existing and help gives the details..
What you need to do is add a task that then calls min. To get it to run by just using grunt you must call this task default.
If you call it anything else (e.g. development, you must run grunt development)
You also need to make sure you have the necessary dependencies installed with npm. So min you probably want to minify JS with the gruntjs uglify module.
From the docs:
Install this plugin with this command:
npm install
grunt-contrib-uglify --save-dev
Once the plugin has been installed,
it may be enabled inside your Gruntfile with this line of JavaScript:
grunt.loadNpmTasks('grunt-contrib-uglify');
For example, here are some snippets from one of my Gruntfile.js
module.exports = function (grunt) {
// load all grunt tasks
require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);
// configurable paths
var yeomanConfig = {
app: 'resources',
dist: 'dist'
};
grunt.initConfig({
yeoman: yeomanConfig,
uglify: {
dist: {
files: {
'<%= yeoman.dist %>/js/scripts.js': [
'<%= yeoman.app %>/js/lib/*.js'
],
'<%= yeoman.dist %>/js/output.js': [
'<%= yeoman.app %>/js/*.js'
],
}
}
},
});
grunt.registerTask('default', [
// 'jshint',
// 'test',
'uglify'
]);
The above sets up an uglify task and then the grunt.registerTask('default'.. part calls uglify when I run grunt.
The above was generated and used as part of the yeoman workflow.

Using constants in gruntjs

I am trying to write my first Grunt task to copy some files from my common libs folder, which is out of my project directory.
Project Folder : /home/user/projects/bottle
Common Libs directory : /home/user/projects/common
Files' source are inside Common Libs directory at : lib/general/static/js/
Files' destination inside project folder : lib
I have a properties.json file with Common Libs directory path as shown below
{
"common_libs" : `/home/user/projects/common`
}
Now what I already tried is :
module.exports = function(grunt) {
var properties = grunt.file.readJSON('properties.json'),
paths = {
common_libs : properties.common_libs,
common_libs_js : this.common_libs + "lib/general/static/js/"
};
grunt.initConfig({
copy: {
main: {
files: [
{
expand: true,
flatten : true,
src: [
paths.common_libs_js + "/*"
],
dest: 'lib/',
filter: 'isFile'
}
]
}
}
});
grunt.loadNpmTasks('grunt-contrib-copy');
};
I am running grunt as follows
grunt copy
With this no files are copied to the destination.
Help me in this.
Also I want to know
How can I use Ant's property tag type constants in GruntJS? Because I am getting the base folder from properties.json and I need to copy many files from different folders under the base folder.
Can we have these type of constants per task?
Thanks in advance.
There are a few issues with your code. First:
common_libs_js : this.common_libs + "lib/general/static/js/"
Unfortunately this.common_libs is undefined (this doesn't point to where you think it does), so common_libs_js ends up being 'undefinedlib/general/static/js/', which doesn't work.
The second problem is that on that same line you are concatenating paths, but the first path (from the properties file) doesn't seem to end with a slash, and would become '/home/user/projects/commonlib/general/static/js/' if it wasn't for the previous issue.
Third, you'd get a whole bunch of folders inside your dest path. When the expand option is used, Grunt uses the paths as given in the src property to create the folder structure. If you want /home/user/projects/common/lib/general/static/js/foo.js to be copied to lib/foo.js, you should set the cwd option to paths.common_libs_js and the src to '*.js' (or '**/*.js' for a match on any level).
People usually embed configuration properties inside Grunt's config, and then use template strings to access them. A very common way to write your task would be something like this (with a few changes, adjust as needed):
module.exports = function(grunt) {
grunt.initConfig({
properties: grunt.file.readJSON('properties.json'),
copy: {
main: {
expand: true,
cwd: '<%= properties.common_libs %>/lib/general/static/js',
src: '**/*.js',
dest: 'lib'
}
}
});
grunt.loadNpmTasks('grunt-contrib-copy');
};
Alternatively, if you want your files to end up in 'lib/general/static/js/' in the destination path too:
module.exports = function(grunt) {
grunt.initConfig({
properties: grunt.file.readJSON('properties.json'),
copy: {
main: {
expand: true,
cwd: '<%= properties.common_libs %>',
src: 'lib/general/static/js/**/*.js',
dest: '.' // because src includes 'lib'
}
}
});
grunt.loadNpmTasks('grunt-contrib-copy');
};
If you're not sure how Grunt sees your files, run it with grunt -v and it will tell you.
You might also want to consider git submodules for a non-Grunt solution.
For task-specific constants: you could use the task's (or target's) options hash for that, and access it with template strings:
module.exports = function(grunt) {
grunt.initConfig({
properties: grunt.file.readJSON('properties.json'),
copy: {
options: {
foo: 'lib'
},
main: {
options: {
bar: '**/*.js'
},
expand: true,
cwd: '<%= properties.common_libs %>/<%= copy.options.foo %>/general/static/js',
src: '<%= copy.options.main.bar %>',
dest: 'lib'
}
}
});
grunt.loadNpmTasks('grunt-contrib-copy');
};
This is rarely done for anything other than actual options, though. Conflicts with real options can occur. You could also use the target namespace directly, setting the property directly inside main. But again, there are a few property names that may conflict.
If you want to override properties (e.g. for a release build), you can do this:
module.exports = function(grunt) {
grunt.registerTask('release', function() {
grunt.config.set('properties.common_libs', '/usr/lib/shared');
});
grunt.initConfig({
properties: grunt.file.readJSON('properties.json'),
copy: {
main: {
expand: true,
cwd: '<%= properties.common_libs %>/lib/general/static/js',
src: '**/*.js',
dest: 'lib'
}
}
});
grunt.loadNpmTasks('grunt-contrib-copy');
};
Then you'd call your task with grunt release copy.
EDIT
Based on your updated question, it doesn't seem like the properties.json file is of much use to you. Why not just specify the properties in your Gruntfile?
module.exports = function(grunt) {
grunt.initConfig({
properties: {
base_dir: '../common',
base_js_dir: '<%= properties.base_dir %>/lib/general/static/js',
base_css_dir: '<%= properties.base_dir %>/lib/general/static/css'
},
copy: {
main: {
expand: true,
cwd: '<%= properties.base_js_dir %>',
src: '**/*.js',
dest: 'lib'
}
}
});
grunt.loadNpmTasks('grunt-contrib-copy');
};
You can also use the file together with this, if you want. Or even put these properties (with the template strings) inside the properties.json file. In the end it's just a matter of making Grunt see an object with template strings. It's up to you to provide that somehow.

Resources