I'm attempting to use Dennis Becker's grunt-sass-globbing plug-in with libsass since libsass doesn't support sass-globbing. https://github.com/DennisBecker/grunt-sass-globbing
I've tried setting up a libsass project using the documentation that the developer has provided.
I'm having trouble figuring out exactly where files need to be placed and how imports should be called.
The below setup throws this error:
Running "sass_globbing:files" (sass_globbing) task
Running "sass:app" (sass) task
>> file to import not found or unreadable: layout/**/*
>> Current dir: /Users/dlahay/Documents/Workspaces/SusyLibsass/css/sass/
>> Line 3 Column 9 css/sass/main.scss
File structure:
css
|_ main.css
|_ sass
|_ layout
|_ _base.scss
|_ typography
|_ _base.scss
|_ _layoutMap.scss
|_ _typographyMap.scss
|_ main.scss
Gruntfile.js
grunt.initConfig({
sass_globbing: {
files: {
'css/sass/_layoutMap.scss': 'css/sass/layout/**/*.scss',
'css/sass/_typographyMap.scss': 'css/sass/typography/**/*.scss',
},
options: {
useSingleQuotes: false
}
},
// Grunt-sass
sass: {
app: {
files: [{
expand: true,
cwd: 'css/sass',
src: ['*.scss'],
dest: 'css',
ext: '.css'
}]
},
options: {
sourceMap: false,
outputStyle: 'nested',
imagePath: "../",
}
},
// Grunt-contrib-watch
watch: {
sass: {
files: ['css/sass/**/*'],
tasks: ['sass']
},
options: {
livereload: true,
spawn: false
}
},
});
grunt.loadNpmTasks('grunt-sass');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-sass-globbing');
grunt.registerTask('default', ['sass_globbing', 'sass', 'watch']);
main.scss:
#import "../../bower_components/susy/sass/susy";
#import "layout/**/*";
#import "typography/**/*";
I've also posted this question/issue on the grunt-sass-globbing repo.
Dennis Becker, the developer of grunt-sass-globbing helped me identify the two issues with my setup:
I didn't identify a target in the sass_globbing task in the Gruntfile:
sass_globbing: {
my_target: {
files: {
'css/sass/_layoutMap.scss': 'css/sass/layout/**/*.scss',
'css/sass/_typographyMap.scss': 'css/sass/typography/**/*.scss',
},
},
options: {
useSingleQuotes: false
}
},
My main.scss should have had the name of the map file in the #import:
#import "../../bower_components/susy/sass/susy";
#import "layoutMap";
#import "typographyMap";
Things are now working smoothly. Thanks, Dennis.
I have answered this on the GitHub repository website. It was just an issue with the Gruntfile.js configuration - thee was no target defined on the sass_globbing task.
Related
I've started to learn this just now. I installed the grunt.
If I get grunt watch it is automatic but only in case one file.
How could I make it wath all scss file in my theme, and make the css in different folders.
I don't really undestand how could it working in big.
This is my gruntfile.js now:
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
connect: {
uses_defaults: {}
},
sass: {
dev: {
options: { sourceMap: true },
files: { 'sites/all/themes/uj/css/uj.styles.css' : 'sites/all/themes/uj/sass/uj.styles.scss' }
}
},
watch: {
css: {
files: 'sites/all/themes/uj/**/*.scss',
tasks: [ 'sass:dev' ],
options: { livereload: true }
}
}
});
// Load Grunt plugins
// grunt.loadNpmTasks('');
// Default task(s).
grunt.registerTask('default', []);
// Load Grunt plugins
grunt.loadNpmTasks('grunt-contrib-connect');
grunt.loadNpmTasks('grunt-sass');
grunt.loadNpmTasks('grunt-contrib-watch');
};
Per the official documentation on file globbing, to watch for changes for files of a certain file type in the directory path and its subdirectories, you'll want:
files: ['js/**/*.js']
or:
files: ['css/**/*.*']
Having looked at, File to import not found or unreadable: susy, I was unable to get the answer.
My Partial gruntfile.js
sass: {
options: {
/** Only use include_paths if extracting elements from Node_Modules */
includePaths: ['node_modules/susy/sass']
}, //options
dist: {
options: {
outputStyle: 'expanded',
sourceMap: false,
require: 'susy'
},
files: {
'css/main.css': 'scss/main.scss'
}
}
}, // sass
My scss file
#import 'susy';
Did you ever get this to work?
I got mine to work using grunt-sass and susy like this:
sass: {
options: {
includePaths: ['node_modules/susy/sass'],
require: 'susy',
outputStyle: 'compressed',
sourceMap: true
},
build: {
files: {
'stylesheets/css/styles.min.css': 'stylesheets/scss/styles.scss'
}
}
},
And then I'm using #import susy in my styles.scss file.
I've installed bootstrap-sass and grunt-sass, and want to customise the bootstrap components included in my build.
I've created a copy of _bootstrap.scss in my app/styles/ folder and need to override the default import paths - what changes do I need to make to my Gruntfile for this to work?
I've tried including the full path the Bootstrap partials in my _bootstrap.scss file, but that doesn't compile. Gruntfile extract below.
Gruntfile
// Compiles Sass to CSS and generates necessary files if requested
sass: {
options: {
sourceMap: true,
sourceMapEmbed: true,
sourceMapContents: true,
includePaths: ['.']
},
dist: {
files: [{
expand: true,
cwd: '<%= config.app %>/styles',
src: ['*.{scss,sass}'],
dest: '.tmp/styles',
ext: '.css'
}]
},
server: {
files: [{
expand: true,
cwd: '<%= config.app %>/styles',
src: ['*.{scss,sass}'],
dest: '.tmp/styles',
ext: '.css'
}]
}
},
Here is what I did using Grunt and Bower along with Bootstrap to make a custom install including / excluding bootstrap components which might help you.
Once I had Grunt and Bower set up I added bootstrap-sass using bower install boostrap-sass --save-dev so that my bower.json file was updated.
Modifying Bootstrap
I imported bower_components/bootstrap-sass/assets/stylesheets/_bootstrap.scss into my my styles.scss file.
Then edited _bootstrap.scss commenting out which ever components I didn't want or need.
Next, created a file called _main.scss and stored this in a subdirectory (partials) of where my styles.scss file was, then imported _main.scss below the _bootstrap.scss.
This way I could override bootstrap if need be with my own custom styles by editing _main.scss.
Here's a starter grunt setup I used which might help explain the file structure.
Styles.scss file
// Bootstrap
#import 'bower_components/bootstrap-sass/assets/stylesheets/bootstrap';
// Custom styles
#import 'partials/main';
Gruntfile.js
module.exports = function(grunt){
// Configure task(s)
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
// setup uglify task
uglify: {
build: {
files: {
'js/scripts.min.js': ['bower_components/jquery/dist/jquery.min.js', 'bower_components/bootstrap-sass/assets/javascripts/bootstrap.min.js', 'src/js/*.js']
},
},
dev: {
options: {
beautify: true,
mangle: false,
compress: false,
preserveComments: 'all'
},
files: {
'js/scripts.min.js': ['bower_components/jquery/dist/jquery.js', 'bower_components/bootstrap-sass/assets/javascripts/bootstrap.js', 'src/js/*.js']
},
},
},
// setup watch task
watch: {
js: {
files: ['bower_components/**/*.js', 'src/js/*.js'],
tasks: ['uglify:dev']
},
css: {
files: ['src/scss/**/*.scss'],
tasks: ['sass:dev']
},
},
// setup sass
sass: {
dev: {
options: {
outputStyle: 'expanded'
},
files: {
'css/styles.min.css' : 'src/scss/styles.scss'
},
},
build: {
options: {
outputStyle: 'compressed'
},
files: {
'css/styles.min.css' : 'src/scss/styles.scss'
},
},
},
});
// Load the plugins
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-sass');
// Register task(s)
grunt.registerTask('default', ['uglify:dev','sass:dev']);
grunt.registerTask('build', ['uglify:build', 'sass:build']);
};
From there you should be able to add your own custom bootstrap styles and / or remove components from bootstrap you don't want. Then just run grunt or grunt build depending on whether you want a development output (non minified or not). Or grunt watch while you are editing for instant compile. Add in livereload chrome extension and the app and you'll have live updates across all files.
A couple of months late.. but hope this helps!
Here is my workflow I have 20 scss files that are imported into one 'app.scss' see below
#import
"base/normalize",
"base/foundation/functions",
"base/settings",
"app/functions",
"app/mixins",
"app/components/icons",
etc
the SASS folder structure is organized 'SASS/base and SASS/base' root has one 'app.scss' file that imports everything
I compile compile and watch changes via 'Gruntfile.js' -- it looks something like this
sass: {
dist: {
options: {
includePaths: ['scss'],
imagesDir: 'assets/img',
cssDir: 'assets/css'
},
files: {
'assets/css/app.css': 'sass/app.scss'
}
}
},
watch: {
sass: {
files: 'sass/**/*.scss',
tasks: ['sass']
},
css: {
files: 'assets/**/*.css',
options: {
livereload: true
}
},
javascript: {
files: ['app/**/*.js', 'app/**/*.hbs'],
options: {
livereload: true
}
}
},
This is great for production but while in dev I would like to have different css files for debugging purposes..
is there a way of having multiple css files via Gruntfile and SASS for development without having to include 20 <link rel="stylesheet"... while in dev stage...
based on comment about using sourceMap, sourceComments here is what my grunt looks like
sass: {
dist: {
options: {
includePaths: ['scss'],
imagesDir: 'assets/img',
cssDir: 'assets/css'
},
files: {
'assets/css/app.css': 'sass/app.scss'
}
}
sourceComments: {
options: {
sourceComments: 'normal'
},
files: {
'assets/css/source-comments-app.css': 'sass/app.scss'
}
},
sourceMap: {
options: {
sourceComments: 'map',
sourceMap: 'source-map.css.map'
},
files: {
'assets/css/source-maps-app.css': 'sass/app.scss'
}
},
},
but am getting an error... is grunt suppose to get all the mapping information from app.scss for the sourcemap and sourceComments?
You can use a source map to easily identify which sass file a part of the compiled app.css comes from.
See the sourceComments and sourceMap options in the grunt-sass plugin.
I found the answer via grunt..after a lot of trials
sass: {
dist: {
options: {
includePaths: ['scss'],
imagesDir: 'assets/img',
cssDir: 'assets/css',
sourceComments: 'map',
sourceMap:'assets/css/app.css.map'
},
files: {
'assets/css/app.css': 'sass/app.scss'
}
}
},
it has to be inside the options of the scss compile!
I'm using Grunt with Foundation 5 (a Foundation 5 Drupal subtheme, to be exact), and it worked when I added sourceComments: "map" to dist, like so:
dist: {
options: {
**YOUR OTHER OPTIONS HERE***
sourceComments: "map"
}
}
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