I have made a grunt task to run compass as follows:
module.exports = {
dev: {
options: {
sassDir: ['**/*.scss'],
cssDir: 'stylesheets',
noLineComments: false,
outputStyle: 'compressed'
}
}
}
My watch task is as follows:
module.exports = {
jade: {
files: 'app/views/**/*.jade',
tasks: ['jade']
},
src: {
files: '**/*.scss',
tasks: ['compass:dev']
},
options: {
livereload: true,
},
}
However I get Compass can't find any Sass files to compile.
My folder structure is as follows:
scss/
stylesheets/
Gruntfile.js
grunt/
aliases.yaml
compass.js
watch.js
You can create a file called config.rb in the same leval as gruntfile.js**
Reference
then you can tell where the compass will look for the sass files:
css_dir = 'assets/stylesheets' #where find the css
sass_dir = 'assets/sass' #where find sass files
images_dir = 'assets/images' #where find the images (if you want to use then in css as well)
You don't need to change the code.
Related
(Beginner post)
I used Grunt for this tree :
Gruntfile.js :
module.exports = function(grunt) {
grunt.initConfig({
sass: {
dist: {
options: {
style: 'expanded'
},
files: {
'css/style.css': 'Component/**/*.scss',
}
}
},
watch: {
css: {
files: 'Component/**/*.scss',
tasks: ['sass']
},
},
});
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('default',['watch']);
}
It runs without any errors, but it don't take any file. The style.css still empty.
When I replace this line :
files: {
'css/style.css': 'Component/**/*.scss',
}
with :
files: {
'css/style.css': 'Component/header/header.scss',
}
Its takes the .css file in header/ correctly.
I don't have any error with either of these two syntaxes.
Any idea ?
You need to use the grunt files pattern to get all the files recursively in the sources folder:
module.exports = function(grunt) {
grunt.initConfig({
sass: {
dist: {
options: {
style: 'expanded'
},
files: [{
expand: true,
cwd: 'Component/',
src: ['**/*.scss'],
dest: 'css/',
ext: '.css'
}]
}
},
watch: {
css: {
files: ['Component/**/*.scss'],
tasks: ['sass']
},
},
});
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('default',['watch']);
}
To use Grunt file patterns you need to specify an object with options instead of the default setting in the form of 'destination': 'source'. The file pattern object has the following options:
{
// source directory
cwd: String,
// creates the subdirectories or flatten the content to the destination directory
flatten: Boolean,
// remove anything and after the file extension and replace with the ext String
ext: String,
// destination folder
dest: String,
// source file pattern using minimatch to match files
src: String|Array
}
More about Grunt file patterns and minimatch file matching patterns.
Edit to achieve the desired result (have all the components compiled in to a single file), you will need to do the following:
Change the filenames of all of your components, for example change Component/header/header.scss to Component/header/_header.scss. Files prefixed with _ will not create any output (Sass default behavior).
Then create a bootstrap file (let's call is style.scss, containing only the reference to the files you want to merge in to your output css file. For each file add #import 'header/header'; for header/_header.scss. You don't need to add the extension or the _ prefix.
Change the files definition of you sass:dist task to: { 'css/style.css' : ['Component/style.scss'] }
Gruntfile.js will now look like this:
module.exports = function(grunt) {
grunt.initConfig({
sass: {
dist: {
options: {
style: 'expanded'
},
files: { 'css/style.css' : ['Component/style.scss'] }
}
},
watch: {
css: {
files: ['Component/**/*.scss'],
tasks: ['sass']
},
},
});
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.registerTask('default',['watch']);
}
That will compile Component/style.scss (containing the reference to all your components files) in to css/style.css.
I want grunt to compile sass every time grunt is executed if my Sass files haven't changed. Sometimes the watcher fails to detect if the compiled result is different from the existing CSS file, and the only way to force it to compile is by editing one of the Sass files.
Grunt file:
/**
* #file
*/
module.exports = function(grunt) {
// This is where we configure each task that we'd like to run.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
watch: {
// This is where we set up all the tasks we'd like grunt to watch for changes.
scripts: {
files: ['js/source/{,*/}*.js'],
tasks: ['uglify'],
options: {
spawn: false,
},
},
images: {
files: ['images/source/{,*/}*.{png,jpg,gif}'],
tasks: ['imagemin'],
options: {
spawn: false,
}
},
vector: {
files: ['images/source/{,*/}*.svg'],
tasks: ['svgmin'],
options: {
spawn: false,
}
},
css: {
files: ['sass/{,*/}*.{scss,sass}'],
tasks: ['sass']
}
},
uglify: {
// This is for minifying all of our scripts.
options: {
sourceMap: true,
mangle: false
},
my_target: {
files: [{
expand: true,
cwd: 'js/source',
src: '{,*/}*.js',
dest: 'js/build'
}]
}
},
imagemin: {
// This will optimize all of our images for the web.
dynamic: {
files: [{
expand: true,
cwd: 'images/source/',
src: ['{,*/}*.{png,jpg,gif}' ],
dest: 'images/optimized/'
}]
}
},
svgmin: {
options: {
plugins: [{
removeViewBox: false
}, {
removeUselessStrokeAndFill: false
}]
},
dist: {
files: [{
expand: true,
cwd: 'images/source/',
src: ['{,*/}*.svg' ],
dest: 'images/optimized/'
}]
}
},
sass: {
// This will compile all of our sass files
// Additional configuration options can be found at https://github.com/sindresorhus/grunt-sass
options: {
sourceMap: true,
// This controls the compiled css and can be changed to nested, compact or compressed.
outputStyle: 'expanded',
precision: 5
},
dist: {
files: {
'css/base/base.css': 'sass/base/base.sass',
'css/components/components.css': 'sass/components/components.sass',
'css/components/tabs.css': 'sass/components/tabs.sass',
'css/components/messages.css': 'sass/components/messages.sass',
'css/layout/layout.css': 'sass/layout/layout.sass',
'css/theme/theme.css': 'sass/theme/theme.sass',
'css/theme/print.css': 'sass/theme/print.sass'
}
}
},
browserSync: {
dev: {
bsFiles: {
src : [
'css/**/*.css',
'templates/{,*/}*.twig',
'images/optimized/{,*/}*.{png,jpg,gif,svg}',
'js/build/{,*/}*.js',
'*.theme'
]
},
options: {
watchTask: true,
// Change this to "true" if you'd like the css to be injected rather than a browser refresh. In order for this to work with Drupal you will need to install https://drupal.org/project/link_css keep in mind though that this should not be run on a production site.
injectChanges: false
}
}
},
});
// This is where we tell Grunt we plan to use this plug-in.
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-imagemin');
grunt.loadNpmTasks('grunt-svgmin');
grunt.loadNpmTasks('grunt-sass');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-browser-sync');
// Now that we've loaded the package.json and the node_modules we set the base path
// for the actual execution of the tasks
// grunt.file.setBase('/')
// This is where we tell Grunt what to do when we type "grunt" into the terminal.
// Note: if you'd like to run and of the tasks individually you can do so by typing 'grunt mytaskname' alternatively
// you can type 'grunt watch' to automatically track your files for changes.
grunt.registerTask('default', ['browserSync','watch']);
};
grunt.registerTask('default', [
'browserSync',
'sass',
'watch',
]);
Simply register sass as a task to run when you type grunt.
If you do this and the sass files are still not giving you the results you want, then you need to revisit your sass task and make sure you're piping the files where you want them to go.
More cool options:
newer: When you run grunt you want sass to compile to CSS only if there is a difference between the new CSS and the old. In that case, try grunt-newer. Appending newer:taskyouwanttorun:option will work.
watch:sass: You want sass to compile during a watch based on something besides changing one of the sass files. Easy, just set up a watch task that looks for whatever file you want to modify, image/javascript/html/whatever and set the task as sass
I'm trying to use sass with grunt and I'm having a weird behavior.
If I create any file with underscore it doesn't work anymore, and it doesn't import either.
That is my Gruntfile, really simple:
module.exports = function(grunt) {
'use strict';
require('load-grunt-tasks')(grunt);
grunt.initConfig({
watch: {
sass: {
files: 'scss/**/*.{scss,sass}',
tasks: ['sass']
}
},
sass: {
example: {
options: {
outputStyle: 'expanded'
},
files: {
'public/css/app.css': 'scss/**/*.{scss,sass}'
}
}
}
});
grunt.registerTask('default', ['watch']);
};
If I create a file, for example, application.scss in scss/, it works and creates the file app.css in public/css, but if I create any file with underscore, for instance: _variables in scss/ it doesn't work anymore, it doesn't create the file or changes anything and it doesn't import either.
application.scss:
#import "variables";
body {
background-color: $bg-color;
}
_variables.scss:
$bg-color: red;
Files with names starting with an underscore are considered as partial in the eyes of SASS. This means that SASS would not make an actual css file out of them. To prevent this, either create an index.scss file and import your partials in it or remove the underscore from their names.
Official DOcs
I solved it by using:
files: [{
expand: true,
cwd: 'scss',
src: '**/*.{scss,sass}',
dest: 'public/css',
ext: '.css'
}]
I find Web Essentials autoprefixer not auto enough - I need to manually say it to add prefixes. Also it doesn't offer me prefixes when I'm writing .less or .scss.
Is there any extension or option to make it automatically add prefixes on css compilation from .less or .scss stage?
I've tried Web Compiler extension, but it doesn't support prefixing for sass, and says that it supports prefixing for less, but I've tried enabling autoprefix in compilerconfig.json while writing .less and it didn't add anything.
Is there something for visual studio? Or maybe I should dump it and use some editor + gulp?
I'm sure there will be an extension out there but it isn't too much work to create a Grunt/Gulp file to do your compiling for you. Task Runner Explorer will then manage the running of the file. Writing your own will give you the control and the flexibility that an extension will not.
Here is a sample using Grunt, taken from my post on the subject Getting started with Grunt, SASS and Task Runner Explorer
module.exports = function (grunt) {
'use strict';
grunt.loadNpmTasks('grunt-sass');
grunt.loadNpmTasks('grunt-autoprefixer');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
// Sass
sass: {
options: {
sourceMap: true, // Create source map
outputStyle: 'compressed' // Minify output
},
dist: {
files: [
{
expand: true, // Recursive
cwd: "sass", // The startup directory
src: ["**/*.scss"], // Source files
dest: "stylesheets", // Destination
ext: ".css" // File extension
}
]
}
},
// Autoprefixer
autoprefixer: {
options: {
browsers: ['last 2 versions'],
map: true // Update source map (creates one if it can't find an existing map)
},
// Prefix all files
multiple_files: {
src: 'stylesheets/**/*.css'
},
},
// Watch
watch: {
css: {
files: ['sass/**/*.scss'],
tasks: ['sass', 'autoprefixer'],
options: {
spawn: false
}
}
}
});
grunt.registerTask('dev', ['watch']);
grunt.registerTask('prod', ['sass', 'autoprefixer']);
};
I have a .sass-cache folder that is being auto generated. Trying to figure out how not to let it generate it at all. To be more clear, I don't want the .sass-cache folder.
I've tried several approaches but can't seem to keep it from generating.
Here's a couple approaches attempted:
noCache: false or true
config.rb file with: asset_cache_buster = :none
config.rb file with: cache = false
Here is what my watch is doing:
module.exports = function (grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
watch: {
scripts: {
files: ['assets/js/*.js'],
tasks: ['concat', 'uglify', 'copy', 'clean'],
options: {
spawn: false
}
},
scss: {
files: ['assets/scss/*.scss'],
tasks: ['compass', 'cssmin'],
}
},
then later on, here is what Compass is doing & a snippet of my tasks:
compass: {
development: {
options: {
config: './config.rb',
sassDir: 'assets/scss',
cssDir: 'assets/css'
}
}
},
clean:{
build: {
}
}
});
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-contrib-compass');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-cssmin');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.registerTask('default', ['watch']);
grunt.registerTask(
'build',
'Compiles all the assets and copies the files to the build directory.',
['less', 'compass', 'cssmin', 'concat', 'uglify', 'copy', 'clean']
);
};
here is what I'm trying in my config.
if File.file?( './.nosasscache' )
asset_cache_buster = :none
cache = false # Uncomment to disable cache.
end
Setting cache = false in your config.rb should be enough. You could try disabling all caching:
asset_cache_buster = :none
cache = false
If that doesn't work you could always run a clean to remove the folder.(see link)
https://github.com/gruntjs/grunt-contrib-compass#clean
If you are running Sass from the command line, you can add the --no-cache flag:
sass --no-cache input.scss output.css