Grunt not compiling Sass to CSS - gruntjs

I can't figure out what's wrong with my Gruntfile, but the way I understand it is that the sass task will compile abc.scss to abc-exp.css, then, cssmin will take abc-exp.css and generate abc.css. Finally, the watch task will run the css task, which includes sass and cssmin. However, the accurate CSS is only generated the first time I run my tasks, then, on any subsequent changes, nothing is generated.
My project structure is:
_themes/abc/css/abc-exp.css
_themes/abc/css/abc.css
_themes/abc/sass/abc.scss
_themes/abc/sass/partials
_themes/abc/sass/partials/_base.scss
_themes/abc/sass/partials/_variables.scss
_themes/abc/sass/partials/_mixins.scss
Gruntfile:
module.exports = function(grunt){
require("matchdep").filterDev("grunt-*").forEach(grunt.loadNpmTasks);
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
sass: {
build: {
files: {
'_themes/abc/css/abc-exp.css': '_themes/abc/sass/abc.scss'
}
}
},
// autoprefixer: {
// build: {
// src: '_themes/abc/css/abc-exp.css',
// dest: '_themes/abc/css/abc-exp.css'
// }
// },
cssmin: {
build: {
src: '_themes/abc/css/abc-exp.css',
dest: '_themes/abc/css/abc.css'
}
},
// cssbeautifier: {
// files: ['_themes/abc/css/abc-exp.css'],
// options: {
// indent: ' ',
// openbrace: 'end-of-line',
// autosemicolon: false
// }
// },
uglify: {
options: {
},
my_target: {
files: {
'_themes/abc/js/abc-min.js': ['_themes/abc/js/abc.js'],
'_themes/abc/js/abc-bottom-min.js': ['_themes/abc/js/abc-bottom.js']
}
}
},
watch: {
css: {
files: ['_themes/abc/sass/*.scss'],
tasks: ['css']
},
js: {
files: ['_themes/abc/js/abc.js', '_themes/abc/js/abc-bottom.js'],
tasks: ['js']
}
},
browserSync: {
dev: {
bsFiles: {
src: [
'_themes/abc/css/*.css',
'_themes/abc/img/*',
'_themes/abc/js/*.js',
'_themes/abc/**/*.html',
'_themes/abc/**/*.md'
]
},
options: {
watchTask: true,
proxy: 'wifi.dev:8888'
}
}
}
});
// grunt.registerTask('default', ['browserSync', 'watch']);
// grunt.registerTask('css', ['sass', 'autoprefixer', 'cssmin', 'cssbeautifier']);
// grunt.registerTask('buildcss', ['sass', 'autoprefixer', 'cssmin', 'cssbeautifier']);
// grunt.registerTask('js', ['uglify']);
// grunt.registerTask('buildjs', ['uglify']);
grunt.registerTask('default', ['browserSync', 'watch']);
grunt.registerTask('css', ['sass', 'cssmin']);
grunt.registerTask('js', ['uglify']);
};

I think you need to replaced build with dist like this:
sass: {
dist: {
files: {
'_themes/abc/css/abc-exp.css': '_themes/abc/sass/abc.scss'
}
}
},
In order to make the task observable by watch you need to change it from css to sass
watch: {
sass: {
files: ['_themes/abc/sass/**/*.{scss,sass}'],
tasks: ['sass']
},
...
},

Related

Grunt: cssmin not working

I am trying to minify CSS using Grunt cssmin plugin. Below is my code:
// Minify CSS
cssmin: {
build: {
options: {
banner: '/* Minified CSS */'
},
files: {
'htt/css/style.min.css' : ['wp/css/**/*.css']
}
}
},
when i run "grunt cssmin" it gives error of "Unexpected identifier".
You where missing a comma after the js object in the watch task, for future you can edit your answer to provide more information instead of posting it as an answer :)
// Watch Tasks
watch: {
js: {
files: ['wp/js/*.js'],
tasks: ['uglify:dev']
}, <------- Missing comma
css: {
files: ['wp/css/*.css'],
tasks: ['']
}
}
});
#mike
`module.exports = function (grunt) {
// Configure Tasks
grunt.initConfig ({
pkg: grunt.file.readJSON ('package.json'),
// Uglify JS
uglify: {
build: {
src: 'wp/js/*.js',
dest: 'htt/js/script.min.js'
},
dev: {
options: {
beautify: true,
mangel: false,
compress: false,
preserveComments: 'all'
},
src: 'wp/js/*.js',
dest: 'htt/js/script.min.js'
}
},
// Concatenating files
concat: {
build: {
src: ['wp/css/*.css'],
dest: 'htt/css/style.css'
}
},
// Minify CSS
cssmin: {
build: {
//options: {
// banner: '/* Minified CSS */'
//},
files: {
'htt/css/style.min.css' : ['wp/css/**/*.css']
}
}
},
// Watch Tasks
watch: {
js: {
files: ['wp/js/*.js'],
tasks: ['uglify:dev']
}
css: {
files: ['wp/css/*.css'],
tasks: ['']
}
}
});
// Load the Plugins
grunt.loadNpmTasks ('grunt-contrib-uglify');
grunt.loadNpmTasks ('grunt-contrib-watch');
grunt.loadNpmTasks ('grunt-contrib-concat');
grunt.loadNpmTasks ('grunt-contrib-cssmin');
// Register Tasks
grunt.registerTask ('default', ['uglify:dev']);
grunt.registerTask ('build', ['uglify:build', 'cssmin']);
};`
Above is the whole gruntfile.js file

Bootstrap-Sass using Grunt

I have installed bootstrap using sass, however my scss files are not compiling to the css folder.
I was able to install the bootstrap, using bower.
This is my gruntfile.js
/*jslint node: true */
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
sass: {
options: {
loadPath: ['./bower_components/bootstrap-sass/assets/stylesheets']
},
dist: {
options: {
outputStyle: 'expanded',
sourceMap: false
},
files: {
'css/bootstrap.css' : 'stylesheets/_bootstrap.scss',
}
}
}, // sass
compass: {
dev: {
options: {
config: 'config.rb'
}
} // dev
}, //compass
watch: {
options: {
livereload: true,
dateFormat: function(time) {
grunt.log.writeln('The watch finished in ' + time + 'ms at ' + (new Date()).toString());
grunt.log.writeln('Waiting for more changes...');
} //date format function
}, //options
scripts: {
files: ['*.js']
}, // scripts
//Live Reload of SASS
sass: {
files: ['stylesheets/*.scss', 'stylesheets/bootstrap/*.scss'],
tasks: ['sass']
}, //sass
css: {
files: ['stylesheets/*.scss', 'stylesheets/bootstrap/*.scss'],
tasks: ['compass']
},
html: {
files: ['*.html']
}
}, //watch
postcss: {
options: {
processors: [
require('autoprefixer-core')({
browsers: 'last 2 versions'
})
]
}
}, //post css
jshint: {
options: {
reporter: require('jshint-stylish')
},
target: ['*.js', 'js/*.js']
} //jshint
});
grunt.loadNpmTasks('grunt-sass');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-compass');
grunt.loadNpmTasks('grunt-postcss');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.registerTask('build', ['sass']);
grunt.registerTask('default', ['build', 'watch', 'compass', 'jshint']);
}
I would like to know, what step I am missing, because I have followed the directory paths correctly. My config.rb file, I have changed the sass directory to stylesheets.
When I run, sudo grunt, no errors are found but the stylesheet is not compiling.
In SCSS, files starting with _ (underscore) are typically ignored. See: http://sass-lang.com/documentation/file.SASS_REFERENCE.html#partials
This also applies to grunt-sass.

FoundationPress: want to add task to Gruntfile.js

I'm using the excellent FoundationPress and want to add a task to my watch to create a single .css file out of a single .scss file. In my case, this is for CKEditor - because it needs a separate .css file for custom formatting the input area.
However, I get this output whenever I edit my .scss file:
>> File "ckeditor/nb-ckeditor.scss" changed.
Warning: Task "sassckeditor" not found. Use --force to continue.
Aborted due to warnings.
Here's my the content of Gruntfile.js (see ADD 1 and ADD 2 for what I added to the original content):
module.exports = function(grunt) {
require('time-grunt')(grunt);
grunt.initConfig(
{
pkg: grunt.file.readJSON('package.json'),
sass: {
options: {
sourceMap: true
},
dist: {
options: {
outputStyle: 'compressed'
},
files: {
'css/foundation.css': 'scss/foundation.scss'
}
}
},
/* ADD 1 BEGIN */
sassckeditor: {
options: {
sourceMap: true
},
dist: {
options: {
outputStyle: 'compressed'
},
files: {
'ckeditor/nb-ckeditor-fromsass.css': 'ckeditor/nb-ckeditor.scss'
}
}
},
/* ADD 1 END */
copy: {
scripts: {
expand: true,
cwd: 'bower_components/foundation/js/vendor/',
src: '**',
flatten: 'true',
dest: 'js/vendor/'
},
iconfonts: {
expand: true,
cwd: 'bower_components/fontawesome/',
src: ['**', '!**/less/**', '!**/css/**', '!bower.json'],
dest: 'assets/fontawesome/'
},
},
'string-replace': {
fontawesome: {
files: {
'assets/fontawesome/scss/_variables.scss': 'assets/fontawesome/scss/_variables.scss'
},
options: {
replacements: [
{
pattern: '../fonts',
replacement: '../assets/fontawesome/fonts'
}
]
}
},
},
concat: {
options: {
separator: ';',
},
dist: {
src: [
'bower_components/foundation/js/foundation/foundation.js',
'js/custom/*.js'
],
dest: 'js/foundation.js',
},
},
uglify: {
dist: {
files: {
'js/foundation.js': ['js/foundation.js']
},
options: {
preserveComments: false
}
}
},
watch: {
grunt: { files: ['Gruntfile.js'] },
sass: {
files: 'scss/**/*.scss',
tasks: ['sass'],
options: {
livereload:true,
}
},
/* ADD 2 BEGIN */
sassckeditor: {
files: 'ckeditor/*.scss',
tasks: ['sassckeditor'],
options: {
livereload:true,
}
},
/* ADD 2 END */
js: {
files: 'js/custom/**/*.js',
tasks: ['concat', 'uglify'],
options: {
livereload:true,
}
},
all: {
files: '**/*.php',
options: {
livereload:true,
}
}
}
});
grunt.loadNpmTasks('grunt-sass');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-string-replace');
grunt.registerTask('build', ['copy', 'string-replace:fontawesome', 'sass', 'concat', 'uglify']);
grunt.registerTask('default', ['watch', 'sassckeditor']);
};
What am I doing wrong? Thanks in advance!
From reading your code it looks like the error is coming from trying to run a task by the name of 'sassckeditor' rather than sending the .scss through the 'sass' task. Here's an example of what your code should look like:
/* ADD 2 BEGIN */
sassckeditor: {
files: 'ckeditor/*.scss',
tasks: ['sass'],
options: {
livereload:true,
}
},
/* ADD 2 END */
This will keep your .scss file for the CKEditor separate from the rest of your Sass files, but will still run it thorough the proper 'sass' task that actually compiles the .scss files.
Okay, got this working by simply adding an entry for "files" in my "dist" task:
sass: {
options: {
sourceMap: true
},
dist: {
options: {
outputStyle: 'compressed'
},
files: {
'css/foundation.css': 'scss/foundation.scss',
'css/nb-ckeditor.css': 'scss/nb-ckeditor.scss' // <-- THIS
}
}
},

Grunt: Why is concat and uglify not working when the watch task sees a file change?

Grunt doesn't concat and uglify my javascript files when these files are changed and changes are watched for.
If I run grunt concat the js files are concatenated as expected.
If I then run grunt uglify the files are uglified as expected.
However when I simply run grunt the watch task starts and I change a javascript file I get this:
$ grunt
Running "watch" task
Waiting...
>> File "src/js/test.js" changed.
Running "uglify:my_target" (uglify) task
>> Destination dest/js/app.min.js not written because src files were empty.
>> No files created.
Why does it work when I run individual commands but not when changes to the files are being watched for?
Here's my grunt file:
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
concat: {
options: {
separator: ';',
},
dist: {
src: ['src/**/*.js'],
dest: 'dest/js/app.js',
},
},
uglify: {
my_target: {
files: {
'dest/js/app.min.js': ['<%= concat.dist.dest %>']
}
}
},
compass: { // Task
dist: { // Target
options: { // Target options
sassDir: 'scss',
cssDir: 'css',
environment: 'production'
}
},
dev: { // Another target
options: {
sassDir: 'scss',
cssDir: 'css'
}
}
},
watch: {
css: {
files: '**/*.scss',
tasks: ['compass']
},
js: {
files: 'src/js/*.js', tasks: [ 'uglify' ]
},
}
});
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-compass');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.registerTask('default',['watch', 'compass', 'concat', 'uglify']);
};
I fixed this by changing the watch section. I also changed my_target to build.
My whole grunt file looks like this
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
concat: {
options: {
separator: "\n\n\n",
},
dist: {
src: ['src/**/*.js'],
dest: 'dest/js/app.js',
},
},
uglify: {
build: {
files: {
'dest/js/app.min.js': ['<%= concat.dist.dest %>']
}
}
},
compass: { // Task
dist: { // Target
options: { // Target options
sassDir: 'scss',
cssDir: 'css',
environment: 'production'
}
},
dev: { // Another target
options: {
sassDir: 'scss',
cssDir: 'css'
}
}
},
watch: {
css: {
files: '**/*.scss',
tasks: ['compass']
},
scripts: {
files: ['<%= concat.dist.dest %>'],
tasks: ['concat', 'uglify:build'],
options: {
atBegin: true,
}
}
}
});
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-compass');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.registerTask('default',['watch', 'compass', 'concat', 'uglify']);
};

Grunt Watch - Verifiying property

I'm attempting to seperate my grunt file so I can process two separate chunks of code, everything seems to work apart from the watch task.
I get the following error which loops out until it exceeds the call stack
Waiting...Verifying property watch.app.files exists in config...ERROR
>> Unable to process task.
Warning: Required config property "watch.app.files" missing.
It seems it doesn't like my watch task being split into two. I've look around and it doesn't seem to be an issue for other people.
My gruntfile looks like this:
module.exports = function(grunt) {
// 1. All configuration goes here
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
concat: {
app: {
src: [
'themes/site_themes/app/scripts/build/libs/!(html5shiv|respond).js',
'themes/site_themes/app/scripts/build/modules/*.js'
],
dest: 'themes/site_themes/app/scripts/production/app.min.js'
},
marketing: {
src: [
'themes/site_themes/marketing/scripts/build/libs/!(html5shiv|respond).js',
'themes/site_themes/marketing/scripts/build/modules/*.js'
],
dest: 'themes/site_themes/marketing/scripts/production/app.min.js'
}
},
uglify: {
app: {
files: {
'themes/site_themes/app/scripts/production/app.min.js': ['themes/site_themes/app/scripts/production/app.min.js'],
'themes/site_themes/app/scripts/production/html5shiv.min.js': ['themes/site_themes/app/scripts/build/libs/html5shiv.js'],
'themes/site_themes/app/scripts/production/respond.min.js': ['themes/site_themes/app/scripts/build/libs/respond.js'],
}
},
marketing: {
files: {
'themes/site_themes/marketing/scripts/production/app.min.js': ['themes/site_themes/marketing/scripts/production/app.min.js'],
'themes/site_themes/marketing/scripts/production/html5shiv.min.js': ['themes/site_themes/marketing/scripts/build/libs/html5shiv.js'],
'themes/site_themes/marketing/scripts/production/respond.min.js': ['themes/site_themes/marketing/scripts/build/libs/respond.js'],
}
}
},
jshint: {
app: {
all: ['themes/site_themes/app/scripts/build/modules/!(analytics).js', 'themes/site_themes/app/scripts/build/app.js'],
},
marketing: {
all: ['themes/site_themes/marketing/scripts/build/modules/!(analytics).js', 'themes/site_themes/marketing/scripts/build/app.js'],
}
},
sass: {
app: {
options: {
style: 'compressed'
},
files: {
'themes/site_themes/app/styles/production/style.min.css':'themes/site_themes/app/styles/build/style.scss'
}
},
marketing: {
options: {
style: 'compressed'
},
files: {
'themes/site_themes/marketing/styles/production/style.min.css':'themes/site_themes/marketing/styles/build/style.scss'
}
}
},
autoprefixer: {
options: {
browsers: ['last 2 versions', 'ie >= 8']
},
app: {
no_dest: {
src: 'themes/site_themes/app/styles/production/style.min.css',
}
},
marketing: {
no_dest: {
src: 'themes/site_themes/marketing/styles/production/style.min.css',
}
}
},
watch: {
app: {
jshint: {
files: ['themes/site_themes/app/scripts/build/modules/!(analytics).js', 'themes/site_themes/app/scripts/build/app.js'],
tasks: 'jshint:app'
},
scripts: {
files: ['themes/site_themes/app/scripts/build/*/*.js'],
tasks: ['concat:app', 'uglify:app'],
options: {
spawn: false,
},
},
css: {
files: ['themes/site_themes/app/styles/build/*.scss', 'themes/site_themes/app/styles/build/inuit/*/*.scss', 'themes/site_themes/app/styles/build/theme/*/*.scss'],
tasks: ['sass:app', 'autoprefixer:app'],
options: {
livereload: true,
spawn: false,
}
}
},
marketing: {
jshint: {
files: ['themes/site_themes/marketing/scripts/build/modules/!(analytics).js', 'themes/site_themes/marketing/scripts/build/app.js'],
tasks: 'jshint:marketing'
},
scripts: {
files: ['themes/site_themes/marketing/scripts/build/*/*.js'],
tasks: ['concat:marketing', 'uglify:marketing'],
options: {
spawn: false,
},
},
css: {
files: ['themes/site_themes/marketing/styles/build/*.scss', 'themes/site_themes/marketing/styles/build/inuit/*/*.scss', 'themes/site_themes/marketing/styles/build/theme/*/*.scss'],
tasks: ['sass:marketing', 'autoprefixer:marketing'],
options: {
livereload: true,
spawn: false,
}
}
}
}
});
// 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-sass');
grunt.loadNpmTasks('grunt-autoprefixer');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-watch');
// 4. Where we tell Grunt what to do when we type "grunt" into the terminal.
grunt.registerTask('default', ['concat:app', 'uglify:app', 'jshint:app', 'sass:app', 'autoprefixer:app', 'watch:app']);
grunt.registerTask('marketing', ['concat:marketing', 'uglify:marketing', 'jshint:marketing', 'sass:marketing', 'autoprefixer:marketing', 'watch:marketing']);
};
Just found this. Looks like nested targets aren't supported by watch.
I'll try find another way to to this and post if I do.

Resources