Compile, Concatenate and Minify Sass files with Grunt - javascript

I'm building a sizable JS application using angularjs, and I'm using Grunt to process everything into a compact distribution. I can't figure out what to use to compile, concat and minify my .scss files into one single css file.
My project is organized by modules, so the .scss files are scattered, rather than grouped in a single directory.
I've looked at grunt-contrib-sass and grunt-contrib-compass, but they both seem to require you to individually specify files to compile. I'm looking for a solution that won't have to change when I add source files.
What Grunt plugin can I use to compile, concat and minify my sass files into a single css file?
I'm currently using concat and recess to concat and minify my plain css files:
concat: {
css: {
src: ['<%= src.css %>'],
dest: '<%= distdir %>/<%= pkg.name %>.css'
},
},
recess: {
min: {
files: {
'<%= distdir %>/<%= pkg.name %>.css': ['<%= distdir %>/<%= pkg.name %>.css']
},
options: {
compress: true
}
}
}

I think a documentation about patterns can help you.
http://gruntjs.com/configuring-tasks#globbing-patterns
sass: { // Task
dist: { // Target
options: { // Target options
style: 'expanded'
},
src: 'foo/{a,b}*.sass', // you can use some kind of regular expression
dest: 'foo/css/
}
}

Related

grunt sass and js autoloader

I've tried a few things but can't come to a good solution.
I'm using grunt to compile my sass and minify my javascript.
Is it possible to autoload every .sass file and every .js file in a specific directory?
I've tried stuff like this
sass: {
options: {
sourceMap: false
},
dist: {
src: 'src/sass/**/*.sass',
dest: 'dist/css/style.css'
}
}
but this will only load the very first sass file.
I'm not sure what concat even does but I tried it aswell and didn't find the solution I was looking for.
Basicly all files in the folder sass/ should be compiled to 1 big style.css file the same with javascript.
Sure I could manually import each file in a main.sass file or so, but I would love a autoload function so I don't get lazy and don't create new files because I would have to add them.
edit:
So with this
files: [{
expand: true,
cwd: "src/sass/",
src: ["**/*.sass"],
dest: "dest/css",
ext: ".css"
}]
I can actually do what I want. The problem is my mixins get loaded too late and it's thorwing an error because it doesn't find the mixin I wanted to include.
This is a format to generate a single output file from multiple source files:
concat: {
whatever: {
options: { separator: '\n' },
src: ['src/sass/**/*.sass'],
dest: 'build/tmp.sass' // make sure the temporary build/ dir exists!
}
}
It only works on tasks supporting combining multiple files; in this case the grunt-contrib-concat task.
It produces dist/css/sass.tmp, which you will need to process with the sass task:
sass: {
dist: {
files: [{
src: 'build/tmp.sass',
dest: 'dist/css/style.css'
}]
}
}
You would make sure they are run in sequence with something like this:
grunt.registerTask( 'default', ['concat', 'sass'] ); // add your uglify/cssmin here
However, I don't recommend this, because the order of the sass files is uncontrollable, and it won't make mixin's available, even if they are compiled to css first - which is pointless, because they loose their 'mixin' format. It's best to run sass on a single source file and import your other files in that source file.
Update
Regarding auto-loading of mixin files,
the SASS Reference does mention you can use custom importers (written in Ruby) that take care of #import; I'm not sure whether this is only for top-level importing of files, or also for #import mixin-name(foo) within rules, but I don't think so.
There is an alternative approach you could use, based on concat, assuming that you have one main sass file. You would need to add a single #import 'all-mixins' to it. This all-mixins.sass is a generated file:
concat: {
all_mixins: {
options: { separator: '\n' },
src: ['src/sass/mixins/*.sass'],
dest: 'build/all-mixins.sass'
}
}
And you would specify the sass option loadPath to add build/ to the path:
sass: {
dist: {
options: {
loadPath: 'build/'
},
files: [{
src: 'build/tmp.sass',
dest: 'dist/css/style.css'
}]
}
}
This is as close to auto-loading as it gets without extending sass itself.

Compiling SASS files using Grunt creates an unnecessary folder

So I have been trying to create my first compiled css files using grunt and sass, and i am having a problem that I cant figure it out.
Every time that I run the sass task, an unnecessary "sass" folder is created inside of my css folder:
This is how it looks:
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
watch:{
sass:{
files:['sass/*.scss'],
task:['sass']
}
},
sass: {
dist: {
files: [{
expand: true,
cwd: '',
src: ['sass/*.scss'],
dest: 'css/',
ext: '.css'
}]
}
}
});
grunt.loadNpmTasks('grunt-sass');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('default', ['sass']);
};
And this is how my folder looks after I run the task:
/SASS/somefile.scss
/CSS/SASS/somefile.css
The SASS folder it should not be there, the result i expect is:
/SASS/somefile.scss
/CSS/somefile.css
Thanks in advance!
The problem is due to your parameters for building the files object dynamically. You need to set the cwd parameter: "All src matches are relative to (but don't include) this path."
files: [{
expand: true,
cwd: 'sass/',
src: '*.scss',
dest: 'css/',
ext: '.css'
}]
Create a SASS folder under your CSS folder. Your somefile.scss file move into SASS folder then run.
like as :
CSS/
SASS/somefile.scss

Using Grunt to concat multiple js files but want them split?

I am new to grunt (literally installed it today and using it) and its great, but i cannot work out something.
I have an angularJs project and i would like to concat all my javascript files into 3 files overall.
So i would have
"base" - all the vendor javascript files for plugins etc
"app" - all the controllers etc used by all users
"admin" - all the controllers etc used but only ever accessed by administrators
Now i have install grunt and setup my task for concat, but how can i have multiple dest and src attributes?
Example of grunt file
grunt.initConfig({
// Metadata
pkg: grunt.file.readJSON('package.json'),
concat: {
options: {
stripBanners: true
},
dist: {
src: ['Scripts/jquery-*.js', '!Scripts/jquery-*.min.*', '!Scripts/jquery-*.intellisense.*', 'Scripts/bootstrap.js', 'Scripts/respond.js', 'js/**/*.js'],
dest: 'dist/app.js'
},
distCss: {
src: ['Content/bootstrap.css', 'Content/site.css'],
dest: 'dist/app.css'
}
},
});
Once i have figured this out, can i then have multiple ugilify attributes to ugilify each js file created?
you can set up seperate tasks to perform when ever you run grunt. each task will concatenate different sources.
from grunt-contrib-concat:
In this example, running grunt concat will build two separate files. One "basic" version, with the main file essentially just copied to dist/basic.js, and another "with_extras" concatenated version written to dist/with_extras.js.
grunt.initConfig({
concat: {
basic: {
src: ['src/main.js'],
dest: 'dist/basic.js',
},
extras: {
src: ['src/main.js', 'src/extras.js'],
dest: 'dist/with_extras.js',
},
},
});
after which you need to use grunt-contrib-uglify plugin to minify the output files from grunt-concat.

How do I tell Grunt to NOT minify or concatenate js files in a build task?

I've just scaffolded an Angular app using Yeoman. I've noticed that the build task does several things by default, including minifying and concatenating js files.
I'd like to have a simpler build task that didn't do any minifying or concatenation, and, instead, only did the following two things:
compile my .scss into .css
copy a working app into my distribution directory
Can anyone help me write a grunt task that will do (only) these two things?
Many thanks.
Ok, I've edited the default grunt file so that it does what I want.
My solution involved writing tasks called copy:devDist and compass:devDist, and then combining them into a devDist task.
//
// copy:devDist --> copies everything into the dist folder, except styles/
//
copy: {
[...]
devDist: {
files: [{
expand: true,
dot: true,
cwd: '<%= yeoman.app %>',
dest: '<%= yeoman.dist %>',
src: [
'**','!styles/**' // everything but styles/
]
}]
}
},
//
// compass:devDist --> compile the sass; put result in dist/styles/
//
compass: {
[...]
devDist: {
options: {
cssDir: '<%= yeoman.dist %>/styles'
}
}
},
//
// register a 'devDist' task that calls the two tasks above
//
grunt.registerTask('devDist', [
'clean:dist',
'copy:devDist',
'compass:devDist'
]);
Now running grunt devDist compiles my css and puts a fully functional app into my dist folder. Excellent. :)

Concat a single file to every file in a directory using grunt

Using Grunt, I want to concat one file to all of the files in a build directory. The purpose of doing so is to append (or potentially prepend) IE specific CSS files to a build CSS file.
To task this:
build/
file1.css
file2.css
file3.css
And create this:
build/
file1.css
file1.ie.css
file2.css
file2.ie.css
file3.css
file3.ie.css
I thought that the expand option might be what I was looking for but I can't figure out how to get it to do what I want.
Try the banner option in grunt-contrib-concat:
concat: {
dist: {
options: {
banner: '/* IE specific things here */',
},
expand: true,
cwd: 'build/',
ext: '.ie.css',
src: ['**/*.css'],
dest: 'build/',
},
},

Categories