Grunt.js spawns a new node process when using the watch task - windows

Grunt.js is obviously spawning a new node.js process when using grunt's watch task:
http://www.youtube.com/watch?v=fgRlcFt9dkg
As soon as I save my document the default task is executed and (as you can see in the video) there suddenly is a new node.exe process.
This is my gruntfile:
module.exports = function(grunt) {
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.loadNpmTasks('grunt-contrib-compress');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-contrib-qunit');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-text-replace');
grunt.loadNpmTasks('grunt-yui-compressor');
// Project configuration.
grunt.initConfig({
// Metadata.
meta: {
version: '1.0',
},
banner: '/*! Copyright (c) <%= grunt.template.today("yyyy") %> */\n',
// Task configuration.
concat: {
options: {
banner: '<%= banner %>',
stripBanners: true
},
develop: {
src: ['js/app.main.js', 'js/app/*.js', 'js/app.debug.js', 'js/app.workarounds.js', 'js/app.init.js'],
dest: 'build/js/app.js'
},
production: {
src: ['js/app.main.js', 'js/app/*.js', 'js/app.workarounds.js', 'js/app.init.js'],
dest: 'build/js/app.js'
},
habla_css: {
src: ['build/habla.css'],
dest: 'build/habla.css'
},
wiwo_css: {
src: ['build/wiwo.css'],
dest: 'build/wiwo.css'
},
iefix: {
src: 'js/iefix/*',
dest: 'build/js/iefix.js'
},
libs: {
src: ['js/src/*'],
dest: 'build/js/libs.js'
}
},
clean: {
pre: [
'build'
],
post: 'dest'
},
copy: {
thirdparty: {
files: [
{
expand: true,
src: ['js/jquery.min.js'],
dest: 'build/',
}]
}
},
min: {
options: {
report: false,
banner: '<%= banner %>'
},
app: {
src: ['build/js/app.js'],
dest: 'build/js/app.min.js'
},
iefix: {
src: 'js/iefix.js',
dest: 'build/js/iefix.min.js'
},
libs: {
src: ['js/src/*'],
dest: 'build/js/libs.min.js'
},
},
cssmin: {
options: {
report: false,
banner: '<%= banner %>'
},
icons: {
src: ['build/icons.css'],
dest: 'build/icons.min.css'
},
habla: {
src: ['build/habla.css'],
dest: 'build/habla.min.css'
},
wiwo: {
src: ['build/wiwo.css'],
dest: 'build/wiwo.min.css'
}
},
less: {
icons: {
src: ['less/system/icons.less'],
dest: 'build/icons.css'
},
habla: {
src: ['less/habla.less'],
dest: 'build/habla.css'
},
wiwo: {
src: ['less/wiwo.less'],
dest: 'build/wiwo.css'
}
},
replace: {
production: {
src: 'build/js/app.js',
dest: 'build/js/app.js',
replacements: [{
from: /\s*App.debug.(log|group|groupEnd)\(.*\);/g,
to: ''
},
{
from: 'debug: true',
to: 'debug: false'
}]
},
date: {
src: 'build/js/app.js',
dest: 'build/js/app.js',
replacements: [{
from: '/*!%CURDATE%*/',
to: 'console.log("' + d.replace(/(T|Z)/gi,' ') + '");'
}]
}
},
qunit: {
files: ['tests/**/*.html']
},
watch: {
main: {
files: ['grunt.js', 'js/app.*.js', 'js/**/*', 'less/**/*', 'less/*'],
tasks: ['default'],
options: {
nospawn: true
}
}
}
});
grunt.registerTask('con', ['concat:habla_css', 'concat:wiwo_css', 'concat:iefix', 'concat:libs']);
grunt.registerTask('icons', ['less:icons cssmin:icons']);
grunt.registerTask('test', ['qunit']);
// Default task.
grunt.registerTask('default', ['less:habla', 'less:wiwo', 'concat:develop', 'con', 'replace:date', 'copy:thirdparty', 'clean:post', 'watch']);
grunt.registerTask('release', ['clean:pre', 'less', 'concat:production', 'con', 'replace:production', 'copy:thirdparty', 'min', 'cssmin', 'clean:post']);
};
So is it a grunt bug or a bug in my gruntfile? The grunt version I'm using is 0.4.1 (+ grunt-cli 0.1.9) on Windows 7 x64.

You should not have 'watch' as the final task in your default task sequence. Your watch configuration invokes default, which then spawns another watch task each time. This line is the problem:
grunt.registerTask('default', ['less:habla', 'less:wiwo', 'concat:develop', 'con', 'replace:date', 'copy:thirdparty', 'clean:post', 'watch']);
It should be this instead:
grunt.registerTask('default', ['less:habla', 'less:wiwo', 'concat:develop', 'con', 'replace:date', 'copy:thirdparty', 'clean:post']);
You should simply run grunt:watch in order to watch the files.
And if you want to run the default task sequence without doing watch, then you can simply run grunt

That's it. Thank you!
I optimized it a little bit so I can still run grunt (without to specify the watch parameter):
watch: {
main: {
files: ['grunt.js', 'js/app.*.js', 'js/**/*', 'less/**/*', 'less/*'],
tasks: ['develop']
}
}
grunt.registerTask('develop', ['less:habla', 'less:wiwo', 'concat:develop', 'con', 'replace:date', 'copy:thirdparty', 'clean:post']);
grunt.registerTask('release', ['clean:pre', 'less', 'concat:production', 'con', 'replace:production', 'copy:thirdparty', 'min', 'cssmin', 'clean:post']);
grunt.registerTask('default', ['develop', 'watch']);
Works fine! Thanks!

Related

Grunt-contrib-sass for dev and prod?

How set up different tasks of grunt-contrid-sass for dev and prod?
I need different css-files - with and without sourcemaps.
I tried:
sass: {
dev: {
options: {
sourcemap: 'inline',
},
},
prod: {
options: {
sourcemap: 'none',
},
},
files: {
expand: true,
cwd: 'static/compass/sass/pages/redesign/',
src: ['**/*.scss'],
dest: 'static/compass/css/pages/redesign/',
ext: '.css'
},
},
But in this case sass:dev task doesn't compile any files.
When I try:
sass: {
dev: {
options: {
sourcemap: 'inline',
},
files: {
expand: true,
cwd: 'static/compass/sass/pages/redesign/',
src: ['**/*.scss'],
dest: 'static/compass/css/pages/redesign/',
ext: '.css'
},
},
prod: {
options: {
sourcemap: 'none',
},
files: {
expand: true,
cwd: 'static/compass/sass/pages/redesign/',
src: ['**/*.scss'],
dest: 'static/compass/css/pages/redesign/',
ext: '.css'
},
},
}
I get a warning with suggestion to use "--force". But even with using "--force" I get no compiled files.
Is there any way to do it?
Your second example is close to what it should be. However the value of each files property should be an Array which contains an Object as shown in this example in the docs.
For instance, it should be:
files: [{
//...
}]
and NOT:
files: {
//...
}
Change your saas task to the following instead:
sass: {
dev: {
options: {
sourcemap: 'inline'
},
files: [{ // <-- change this
expand: true,
cwd: 'static/compass/sass/pages/redesign/',
src: ['**/*.scss'],
dest: 'static/compass/css/pages/redesign/',
ext: '.css'
}] // <-- change this
},
prod: {
options: {
sourcemap: 'none'
},
files: [{ // <-- change this
expand: true,
cwd: 'static/compass/sass/pages/redesign/',
src: ['**/*.scss'],
dest: 'static/compass/css/pages/redesign/',
ext: '.css'
}] // <-- change this
}
}
EDIT
Note: You should also consider changing your dest path in either the dev or prod targets (or both) because currently they are the same path, i.e. if you run both sass:prod and sass:dev the output from one task will overwritten by the other.

Sass is not compiling with patternlab node

I am trying to set up the Node version of patternlab but I am unable to get Sass to compile.
Here is the gruntfile.js.
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
clean: {
options: { force: true },
files: ['./public/patterns']
},
concat: {
options: {
stripBanners: true,
banner: '/* \n * <%= pkg.name %> - v<%= pkg.version %> - <%= grunt.template.today("yyyy") %> \n * \n * <%= pkg.author %>, and the web community.\n * Licensed under the <%= pkg.license %> license. \n * \n * Many thanks to Brad Frost and Dave Olsen for inspiration, encouragement, and advice. \n *\n */\n\n',
},
patternlab: {
src: './builder/patternlab.js',
dest: './builder/patternlab.js'
},
object_factory: {
src: './builder/object_factory.js',
dest: './builder/object_factory.js'
},
lineage: {
src: './builder/lineage_hunter.js',
dest: './builder/lineage_hunter.js'
},
media_hunter: {
src: './builder/media_hunter.js',
dest: './builder/media_hunter.js'
},
patternlab_grunt: {
src: './builder/patternlab_grunt.js',
dest: './builder/patternlab_grunt.js'
},
pattern_exporter: {
src: './builder/pattern_exporter.js',
dest: './builder/pattern_exporter.js'
}
},
copy: {
main: {
files: [
{ expand: true, cwd: './source/js/', src: '*', dest: './public/js/'},
{ expand: true, cwd: './source/css/', src: '*.css', dest: './public/css/' },
{ expand: true, cwd: './source/images/', src: ['*.png', '*.jpg', '*.gif', '*.jpeg'], dest: './public/images/' },
{ expand: true, cwd: './source/images/sample/', src: ['*.png', '*.jpg', '*.gif', '*.jpeg'], dest: './public/images/sample/'},
{ expand: true, cwd: './source/fonts/', src: '*', dest: './public/fonts/'},
{ expand: true, cwd: './source/_data/', src: 'annotations.js', dest: './public/data/' }
]
}
},
jshint: {
options: {
"curly": true,
"eqnull": true,
"eqeqeq": true,
"undef": true,
"forin": true,
//"unused": true,
"node": true
},
patternlab: ['Gruntfile.js', './builder/lib/patternlab.js']
},
watch: {
scss: {
options: {
livereload: true
},
files: ['source/css/**/*.scss', 'public/styleguide/css/*.scss'],
tasks: ['default']
},
all: {
options: {
livereload: true
},
files: [
'source/_patterns/**/*.mustache',
'source/_patterns/**/*.json',
'source/_data/*.json'
],
tasks: ['default']
}
},
sass: {
build: {
options: {
style: 'expanded',
precision: 8
},
files: {
'./source/css/style.css': './source/css/style.scss',
'./public/styleguide/css/static.css': './public/styleguide/css/static.scss',
'./public/styleguide/css/styleguide.css': './public/styleguide/css/styleguide.scss',
'./public/styleguide/css/styleguide-specific.css': './public/styleguide/css/styleguide-specific.scss'
}
}
},
nodeunit: {
all: ['test/*_tests.js']
},
connect: {
app:{
options: {
port: 9001,
base: './public',
hostname: 'localhost',
open: true,
livereload: 35729
}
}
}
});
// load all grunt tasks
require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);
//load the patternlab task
grunt.task.loadTasks('./builder/');
//if you choose to use scss, or any preprocessor, you can add it here
grunt.registerTask('default', ['clean', 'concat', 'patternlab', /*'sass',*/ 'copy']);
//travis CI task
grunt.registerTask('travis', ['clean', 'concat', 'patternlab', /*'sass',*/ 'copy', 'nodeunit']);
grunt.registerTask('serve', ['clean', 'concat', 'patternlab', /*'sass',*/ 'copy', 'connect', 'watch']);
};
The only modification I did to the gruntfile.js was uncomment the scss watch section. The .mustache templates compile correctly and auto-reloads in the browser. But when I make a change to a scss file in the source and save, my style change isn't reflected.
maintainer of Pattern Lab Node here.
You need to uncomment the sass tasks from the registered grunt tasks at the bottom of your gruntfile.
So for example:
grunt.registerTask('serve', ['clean', 'concat', 'patternlab', /*'sass',*/ 'copy', 'connect', 'watch']);
becomes
grunt.registerTask('serve', ['clean', 'concat', 'patternlab', 'sass', 'copy', 'connect', 'watch']);
Pattern Lab Node ships with a "stenciled" implementation of scss files and tasks, as a demonstration of how to incorporate into your project for novice users. This has become a little more clear with newer versions of the README which you can find here: https://github.com/pattern-lab/patternlab-node/blob/master/README.md

Yeoman - Gruntfile.js generates source map at build but deletes it after any changes

I installed Yeoman with angular generator, and it created Gruntfile.js. The problem is that after launching the webserver in the terminal with:
grunt serve
Yeoman generates main.css with in the end the reference of the source map
/*# sourceMappingURL=main.css.map */
But after changing any scss the watch routine regenerates it without the reference of the source map in the end.
You can see my Gruntfile.js attached below:
// Generated on 2015-06-16 using generator-angular 0.11.1
'use strict';
// # Globbing
// for performance reasons we're only matching one level down:
// 'test/spec/{,*/}*.js'
// use this if you want to recursively match all subfolders:
// 'test/spec/**/*.js'
module.exports = function (grunt) {
// Load grunt tasks automatically
require('load-grunt-tasks')(grunt);
// Time how long tasks take. Can help when optimizing build times
require('time-grunt')(grunt);
// Configurable paths for the application
var appConfig = {
app: require('./bower.json').appPath || 'app',
dist: 'dist'
};
// Define the configuration for all the tasks
grunt.initConfig({
// Project settings
yeoman: appConfig,
// Watches files for changes and runs tasks based on the changed files
watch: {
bower: {
files: ['bower.json'],
tasks: ['wiredep']
},
js: {
files: ['<%= yeoman.app %>/scripts/{,*/}*.js'],
tasks: ['newer:jshint:all'],
options: {
livereload: '<%= connect.options.livereload %>'
}
},
jsTest: {
files: ['test/spec/{,*/}*.js'],
tasks: ['newer:jshint:test', 'karma']
},
sass: {
files: ['<%= yeoman.app %>/styles/{,*/}*.{scss,sass}'],
tasks: ['sass:server', 'autoprefixer']
},
gruntfile: {
files: ['Gruntfile.js']
},
livereload: {
options: {
livereload: '<%= connect.options.livereload %>'
},
files: [
'<%= yeoman.app %>/{,*/}*.html',
'.tmp/styles/{,*/}*.css',
'<%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
]
}
},
// The actual grunt server settings
connect: {
options: {
port: 9000,
// Change this to '0.0.0.0' to access the server from outside.
hostname: 'localhost',
livereload: 35729
},
livereload: {
options: {
open: true,
middleware: function (connect) {
return [
connect.static('.tmp'),
connect().use(
'/bower_components',
connect.static('./bower_components')
),
connect().use(
'/app/styles',
connect.static('./app/styles')
),
connect.static(appConfig.app)
];
}
}
},
test: {
options: {
port: 9001,
middleware: function (connect) {
return [
connect.static('.tmp'),
connect.static('test'),
connect().use(
'/bower_components',
connect.static('./bower_components')
),
connect.static(appConfig.app)
];
}
}
},
dist: {
options: {
open: true,
base: '<%= yeoman.dist %>'
}
}
},
// Make sure code styles are up to par and there are no obvious mistakes
jshint: {
options: {
jshintrc: '.jshintrc',
reporter: require('jshint-stylish')
},
all: {
src: [
'Gruntfile.js',
'<%= yeoman.app %>/scripts/{,*/}*.js'
]
},
test: {
options: {
jshintrc: 'test/.jshintrc'
},
src: ['test/spec/{,*/}*.js']
}
},
// Empties folders to start fresh
clean: {
dist: {
files: [{
dot: true,
src: [
'.tmp',
'<%= yeoman.dist %>/{,*/}*',
'!<%= yeoman.dist %>/.git{,*/}*'
]
}]
},
server: '.tmp'
},
// Add vendor prefixed styles
autoprefixer: {
options: {
browsers: ['last 1 version']
},
server: {
options: {
map: true,
},
files: [{
expand: true,
cwd: '.tmp/styles/',
src: '{,*/}*.css',
dest: '.tmp/styles/'
}]
},
dist: {
files: [{
expand: true,
cwd: '.tmp/styles/',
src: '{,*/}*.css',
dest: '.tmp/styles/'
}]
}
},
// Automatically inject Bower components into the app
wiredep: {
app: {
src: ['<%= yeoman.app %>/index.html'],
ignorePath: /\.\.\//
},
test: {
devDependencies: true,
src: '<%= karma.unit.configFile %>',
ignorePath: /\.\.\//,
fileTypes:{
js: {
block: /(([\s\t]*)\/{2}\s*?bower:\s*?(\S*))(\n|\r|.)*?(\/{2}\s*endbower)/gi,
detect: {
js: /'(.*\.js)'/gi
},
replace: {
js: '\'{{filePath}}\','
}
}
}
},
sass: {
src: ['<%= yeoman.app %>/styles/{,*/}*.{scss,sass}'],
ignorePath: /(\.\.\/){1,2}bower_components\//
}
},
// Compiles Sass to CSS
sass: {
options: {
includePaths: [
'bower_components'
],
sourceMap: true,
},
dist: {
files: [{
expand: true,
cwd: '<%= yeoman.app %>/styles',
src: ['*.scss'],
dest: '.tmp/styles',
ext: '.css'
}]
},
server: {
files: [{
expand: true,
cwd: '<%= yeoman.app %>/styles',
src: ['*.scss'],
dest: '.tmp/styles',
ext: '.css'
}]
}
},
// Renames files for browser caching purposes
filerev: {
dist: {
src: [
'<%= yeoman.dist %>/scripts/{,*/}*.js',
'<%= yeoman.dist %>/styles/{,*/}*.css',
'<%= yeoman.dist %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}',
'<%= yeoman.dist %>/styles/fonts/*'
]
}
},
// Reads HTML for usemin blocks to enable smart builds that automatically
// concat, minify and revision files. Creates configurations in memory so
// additional tasks can operate on them
useminPrepare: {
html: '<%= yeoman.app %>/index.html',
options: {
dest: '<%= yeoman.dist %>',
flow: {
html: {
steps: {
js: ['concat', 'uglifyjs'],
css: ['cssmin']
},
post: {}
}
}
}
},
// Performs rewrites based on filerev and the useminPrepare configuration
usemin: {
html: ['<%= yeoman.dist %>/{,*/}*.html'],
css: ['<%= yeoman.dist %>/styles/{,*/}*.css'],
options: {
assetsDirs: [
'<%= yeoman.dist %>',
'<%= yeoman.dist %>/images',
'<%= yeoman.dist %>/styles'
]
}
},
// The following *-min tasks will produce minified files in the dist folder
// By default, your `index.html`'s <!-- Usemin block --> will take care of
// minification. These next options are pre-configured if you do not wish
// to use the Usemin blocks.
// cssmin: {
// dist: {
// files: {
// '<%= yeoman.dist %>/styles/main.css': [
// '.tmp/styles/{,*/}*.css'
// ]
// }
// }
// },
// uglify: {
// dist: {
// files: {
// '<%= yeoman.dist %>/scripts/scripts.js': [
// '<%= yeoman.dist %>/scripts/scripts.js'
// ]
// }
// }
// },
// concat: {
// dist: {}
// },
imagemin: {
dist: {
files: [{
expand: true,
cwd: '<%= yeoman.app %>/images',
src: '{,*/}*.{png,jpg,jpeg,gif}',
dest: '<%= yeoman.dist %>/images'
}]
}
},
svgmin: {
dist: {
files: [{
expand: true,
cwd: '<%= yeoman.app %>/images',
src: '{,*/}*.svg',
dest: '<%= yeoman.dist %>/images'
}]
}
},
htmlmin: {
dist: {
options: {
collapseWhitespace: true,
conservativeCollapse: true,
collapseBooleanAttributes: true,
removeCommentsFromCDATA: true,
removeOptionalTags: true
},
files: [{
expand: true,
cwd: '<%= yeoman.dist %>',
src: ['*.html', 'views/{,*/}*.html'],
dest: '<%= yeoman.dist %>'
}]
}
},
// ng-annotate tries to make the code safe for minification automatically
// by using the Angular long form for dependency injection.
ngAnnotate: {
dist: {
files: [{
expand: true,
cwd: '.tmp/concat/scripts',
src: '*.js',
dest: '.tmp/concat/scripts'
}]
}
},
// Replace Google CDN references
cdnify: {
dist: {
html: ['<%= yeoman.dist %>/*.html']
}
},
// Copies remaining files to places other tasks can use
copy: {
dist: {
files: [{
expand: true,
dot: true,
cwd: '<%= yeoman.app %>',
dest: '<%= yeoman.dist %>',
src: [
'*.{ico,png,txt}',
'.htaccess',
'*.html',
'views/{,*/}*.html',
'images/{,*/}*.{webp}',
'styles/fonts/{,*/}*.*'
]
}, {
expand: true,
cwd: '.tmp/images',
dest: '<%= yeoman.dist %>/images',
src: ['generated/*']
}, {
expand: true,
cwd: '.',
src: 'bower_components/bootstrap-sass-official/assets/fonts/bootstrap/*',
dest: '<%= yeoman.dist %>'
}]
},
styles: {
expand: true,
cwd: '<%= yeoman.app %>/styles',
dest: '.tmp/styles/',
src: '{,*/}*.css'
}
},
// Run some tasks in parallel to speed up the build process
concurrent: {
server: [
'sass:server',
'copy:styles'
],
test: [
'copy:styles'
],
dist: [
'sass',
'copy:styles',
'imagemin',
'svgmin'
]
},
// Test settings
karma: {
unit: {
configFile: 'test/karma.conf.js',
singleRun: true
}
}
});
grunt.registerTask('serve', 'Compile then start a connect web server', function (target) {
if (target === 'dist') {
return grunt.task.run(['build', 'connect:dist:keepalive']);
}
grunt.task.run([
'clean:server',
'wiredep',
'concurrent:server',
'autoprefixer:server',
'connect:livereload',
'watch'
]);
});
grunt.registerTask('server', 'DEPRECATED TASK. Use the "serve" task instead', function (target) {
grunt.log.warn('The `server` task has been deprecated. Use `grunt serve` to start a server.');
grunt.task.run(['serve:' + target]);
});
grunt.registerTask('test', [
'clean:server',
'wiredep',
'concurrent:test',
'autoprefixer',
'connect:test',
'karma'
]);
grunt.registerTask('build', [
'clean:dist',
'wiredep',
'useminPrepare',
'concurrent:dist',
'autoprefixer',
'concat',
'ngAnnotate',
'copy:dist',
'cdnify',
'cssmin',
'uglify',
'filerev',
'usemin',
'htmlmin'
]);
grunt.registerTask('default', [
'newer:jshint',
'test',
'build',
'sass'
]);
};
Issue is with the watch task for sass
sass: {
files: ['<%= yeoman.app %>/styles/{,*/}*.{scss,sass}'],
tasks: ['sass:server', 'autoprefixer']
}
Change this to
sass: {
files: ['<%= yeoman.app %>/styles/{,*/}*.{scss,sass}'],
tasks: ['sass:server', 'autoprefixer:server']
}
Currently as the whole autoprefixer task runs on change of SASS file , both its subtasks also run , autoprefixer:server and autoprefixer:dist
The autoprefixer:server task updates and preserves the sourceMap whereas autoprefixer:dist task doesn't , which causes its reference to be removed from generated CSS file

Grunt not executing sass command

My watch command executes all my tasks except for sass. When I execute grunt sass, I receive the following message error:
Warning:
You need to have ruby and sass installed and in your path for this task to work.
I don't know why this message is showed because I can generate my .css file from the .scss through the Ruby console (sass --watch styles/scss/general.scss:styles/css/general.css), so I have both Ruby and sass installed.
My Gruntfile.js is the following:
module.exports = function(grunt) {
// 1. All configuration goes here
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
concat: {
dist: {
src: [
'js/libs/*.js', // All JS in the libs folder
],
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/',
src: ['**/*.{png,jpg,gif}'],
dest: 'images/optimized/'
}]
}
},
sass: {
dist: {
options: {
style: 'compressed'
},
files: {
'styles/css/general.css': 'styles/scss/general.scss'
}
}
},
watch: {
scripts: {
files: ['**/*.{png,jpg,gif}', 'js/libs/*.js'],
tasks: ['imagemin', 'concat', 'uglify'],
options: {
spawn: false,
}
},
sass: {
files: ['css/*.scss'],
tasks: ['sass']
}
}
});
// 3. Where we tell Grunt we plan to use this plug-in.
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-imagemin');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.loadNpmTasks('grunt-contrib-compass');
// 4. Where we tell Grunt what to do when we type "grunt" into the terminal.
grunt.registerTask('default', ['concat', 'uglify', 'imagemin', 'watch', 'sass']);
};
My OS is Windows7. Any idea?
Try
var config = {
app: 'app',
dist: 'dist'
};
grunt.initConfig({
sass: {
dist: {
options: {
style: 'compressed'
},
files: [{
cwd: 'styles/scss/',
src: '*.scss',
dest: 'styles/css/',
ext: '.css'
}],
},
watch: {
sass: {
files: ['styles/scss/{,*/}*.scss'],
tasks: ['sass'],
options: {
livereload: true
}
}
}
};
and would be better to place all the grunt.loadNpmTasks at the top before the grunt.initConfig

grunt contrib-sass sourcemap enable

I can't get a lot of contrib-sass features to work in grunt. I dived into grunt a day ago and I found it really good.
Link to contrib-sass repo which says sourcemaps should be working:
https://github.com/gruntjs/grunt-contrib-sass/commit/e85ee70ccb8839867172b57ca1378293291f8037
note: I have sass bleeding edge, and this feature works fine if I use: sass --watch --scss --sourcemap --no-cache with google chrome canary sourcemaps and Sass stylesheet debugging
here is my Gruntfile.js:
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd hh:mm:ss") %> */\n',
concat: {
options: {
separator: '\n// New file\n',
banner: '<%= banner %>'
},
develop: {
files: [
{ src: ['js/develop/plugins.js', 'js/develop/main.js'], dest: 'js/concDev.js' }
]
},
vendor: {
files: [
{ src: ['js/vendor/*.js', '!js/vendor/jquery-1.9.1.min.js', '!js/vendor/modernizr-2.6.2.min.js'], dest: 'js/concVend.js' }
]
}
},
uglify: {
options: {
banner: '<%= banner %>'
},
develop: {
files: [
{ src: ['<%= concat.develop.files[0].dest %>'], dest: 'js/concDev.min.js' }
]
},
vendor: {
files: [
{ src: ['<%= concat.vendor.files[0].dest %>'], dest: 'js/concVend.min.js' }
]
}
},
removelogging: {
dist: {
files: [
{ src: ['js/concDev.min.js'], dest: 'js/concDev.min.js' },
{ src: ['js/concVend.min.js'], dest: 'js/concVend.min.js' },
{ src: ['js/concDev.js'], dest: 'js/concDev.js' },
{ src: ['js/concVend.js'], dest: 'js/concVend.js' }
]
}
},
jshint: {
files: ['gruntfile.js', 'js/develop/*.js'],
options: {
globals: {
jQuery: true,
console: true,
module: true,
document: true
}
}
},
cssmin: {
compress: {
options: {
banner: '<%= banner %>'
},
files: [
{ src: ['css/main.css'], dest: 'css/main.min.css' }
]
}
},
imagemin: {
dynamic_mappings: {
files: [
{
expand: true,
cwd: 'img/',
src: ['**/*.png', '**/*.jpg'],
dest: 'img/',
ext: '.png'
}
]
}
},
sass: {
compressed: {
files: {
'css/main.css': 'css/develop/main.scss'
},
options: {
outputStyle: 'compressed'
}
},
nested: {
files: {
'css/main.css': 'css/develop/main.scss'
},
options: {
sourcemap: true,
outputStyle: 'nested'
}
}
},
rsync: {
deploy: {
src: "./",
dest: '<%= connection.dest %>', // i.e. "var/www"
host: '<%= connection.host %>', // i.e. "user#server.com"
recursive: true,
syncDest: false,
exclude: ["/node_modules", ".*"]
}
},
watch: {
options: {
livereload: true
},
html: {
files: '*.html'
},
js: {
files: ['js/develop/plugins.js', 'js/develop/main.js'],
tasks: ['jshint', 'concat:develop']
},
css: {
files: 'css/develop/main.scss',
tasks: ['sass:nested']
}
}
});
// Load Plugins
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.loadNpmTasks('grunt-contrib-imagemin');
grunt.loadNpmTasks("grunt-remove-logging");
grunt.loadNpmTasks('grunt-sass');
grunt.loadNpmTasks('grunt-rsync');
// Task Lists
grunt.registerTask('default', ['jshint', 'concat', 'uglify', 'imagemin', 'sass:nested']);
grunt.registerTask('server', ['watch']);
grunt.registerTask('deploy', ['sass:compressed', 'rsync' ]);
};
Btw, as I said im totally new with grunt, if you find other bad practise in my code please let me know. Also great plugin names for ftront-end work always welcome, I saw there are many, only faminilar with a few contrib ones yet.
Note: Somewhy, a lot of sass options doen't work, for example: noCache, lineNumbers, debugInfo, outputStyle:'compact','expanded' (compressed, nested works oO)
~ ae
As of today (07/10/2013):
If you install pre version of sass
gem install sass --pre
and grunt-contrib-sass package, your config file will allow to generate sourcemaps.
If you use compass try using compass: true option in sass task config block or loadPath
I was able to get this to work using the following:
* one note: the map file doesn't get tracked anywhere so I didn't realize it was rewriting it until I deleted a version of the map and then I noticed that it was writing the file.
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
sass: {
dist: {
options: {
style: 'expanded',
debugInfo: true,
sourcemap: true
},
files: {
'styles/styles.css' : 'styles/sass/styles.scss'
}
},
},
watch: {
css: {
files: '**/*.scss',
tasks: ['sass'],
sourceComments: 'normal'
}
}
});
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('default',['watch']);
}
Just to provide this as an actual answer, sourcemaps aren't available in sass stable yet. They're being worked on in an alpha release. The original question referenced a commit message that noted the code was being future-proofed.
As of 6/24/2013, sourcemaps aren't available in grunt-contrib-sass or grunt-contrib-compass.
It's easy right now, SASS version 3.4.5 works with source maps very well and has some more options to set it up:
$ sass -h
Usage: sass [options] [INPUT] [OUTPUT]
Description:
Converts SCSS or Sass files to CSS.
[...]
Input and Output:
--scss Use the CSS-superset SCSS syntax.
--sourcemap=TYPE How to link generated output to the source files.
auto (default): relative paths where possible,
file URIs elsewhere
file: always absolute file URIs
inline: include the source text in the sourcemap
none: no sourcemaps
[...]
So you can configure your Gruntfile.js e.g. like this:
[...]
sass : {
dist : {
files : {
'example.css' : 'example.scss'
},
options: {
sourcemap: 'auto'
}
}
}
[...]
Now if you run grunt sass task source maps are generated automatically.

Resources