I have lots of different partials and sass files to generate 11 individual website specific style sheets so if I make a changes in a partial that is being used in all 11 style sheets then I have to wait for grunt to compile all these before I can refresh my browser and see the change, one workaround I have is to use the specify option and change the site ID depending on which site I am working on -
compass: {
dev: {
options: {
sassDir: "assets/sass",
specify: "assets/sass/site_##.scss",
cssDir: "assets/styles",
outputStyle: "expanded",
noLineComments: false,
sourcemap: true
}
}
},
watch: {
css: {
files: 'assets/sass/**/*',
tasks: 'compass',
},
},
Is there a way I could make this dynamic in the watch task, i.e. using an ID appended to the body or something?
My partials -
_reset
_grid
_layout
_variables
_mixins
_brand1
_brand2
_brand3
_summer
_winter
_site_1_specific
_site_2_specific
_site_3_specific
_site_4_specific
_site_5_specific
_site_6_specific
_site_7_specific
_site_7_specific
_site_9_specific
_site_10_specific
_site_11_specific
I then have 11 SCSS files importing a combination of the above partials to make the final style sheets.
You can use grunt-newer, that helps you to execute the compass task only in the file that is changed:
https://github.com/tschaub/grunt-newer
npm install grunt-newer --save-dev
grunt.loadNpmTasks('grunt-newer');
Then, you have to change your watch task:
watch: {
css: {
files: '<%= tui.sass %>/**/*',
tasks: ['newer:compass']
},
},
Hope it helps.
Regards.
Related
I setup a grunt tast to compile all sass and scss files into css using grunt-contrib-sass.
The issue I am facing is because it's a modular architecture, I don't have a single sass and css folder.
Instead I have a sass and css folder for each module.
When I specify the module name it works and compiles the sass file into css, but only for that module, like so:
sass: {
dev: {
expand: true,
cwd: 'public/modules/someModuleName/sass',
src: ['*.{scss,sass}'],
dest: 'public/modules/someModuleName/css',
ext: ['.css']
}
}
Instead I need it to compile the sass files into css for each module dynamically, like so:
sass: {
dev: {
expand: true,
cwd: 'public/modules/**/sass',
src: ['*.{scss,sass}'],
dest: 'public/modules/**/css',
ext: ['.css']
}
}
Here is the folder structure:
|-public
|--modules
|---SomeModuleName1
|----Sass
|-----*.scss
|----CSS
|-----*.css
|---SomeModuleName2
|----Sass
|-----*.scss
|----CSS
|-----*.css
From the looks of the directory structure and based on the mean.io tag, I'm assuming you are using meanjs.org or mean.io.
What I did and recommend is that if you are going with sass, you go all in sass.
Rename your each css folder under public/modules/*/ to scss
Convert the existing *.css files to *.scss files
Create a new [style/scss/stylesheets] folder in the public directory
Create a new file(style.scss or main.scss) as the main style file. Recommend main.scss as a convention.
In your main.scss you import the module scss files:
#import "../modules/core/style/core";
#import "../modules/users/style/users";
This step is kind of annoying and I'm sure it can be automated somehow. (2 options below)
https://www.npmjs.com/package/grunt-sass-directory-import
https://github.com/chriseppstein/sass-globbing
For your sass task:
sass: {
options: {
sourcemap: 'none',
update: true
},
dev: {
options: {
lineNumbers: true
},
files: {
'public/dist/application.css': 'public/style/main.scss'
}
},
dist: {
options: {
style: 'compressed'
},
files: {
'public/dist/application.min.css': 'public/style/main.scss'
}
} },
Cleanup work to your gruntfile:
You would need to add clientSCSS to your watchFiles if you want and
run the sass:dev task.
csslint task is not needed and should be
replaced with scsslint.
cssmin task is not needed as the sass:dist
has the compressed option.
Cleanup work in all.js and production.js:
Remove references to *.css files in the assets:lib:css and assets:css with the exception of public/dist/application.css and public/dist/application.min.css
Use the corresponding sass version of bootstrap if you want instead and follow the #include approach in main.scss
I'm trying to install 'modular-scale' (https://github.com/Team-Sass/modular-scale) via my Gruntfile but I can't get it to work.
Note that I don't use a config.rb, I want to require the plugin using Grunt via grunt-contrib-compass.
I thought it was as simple as adding this to my Gruntfile (after the grunt.initConfig({ etc):
compass: {
dist: {
options: {
require: ['modular-scale'], // This line here
sassDir: 'setup',
cssDir: 'css'
}
}
},
watch: {
css: {
files: '**/*.scss',
tasks: ['compass']
}
}
The watch task is absolutely fine. The problem is that if I use one of the SASS variables that are part of the 'modular-scale' plugin, I'll get an error thrown up, suggesting that the 'modular-scale' isn't actually being required.
Am I missing something here?
You no longer need Compass or a config.rb file to use modular-scale.
This is probably an affect of my inefficient setup and not a problem with grunt/livereload.
Here's my watch test in my grunfile.js:
watch: {
images: {
files: ['images/**/*.{png,jpg,gif}', 'images/*.{png,jpg,gif}'],
tasks: ['imagemin'],
options: {
spawn: false
}
},
js: {
files: ['js/*.js','js/**/*.js'],
tasks: ['jshint'],
options: {
spawn: false
}
},
svgs: {
files: ['images/*.svg','images/**/*.svg'],
task: ['svgmin'],
options: {
span: false
}
},
scss: {
files: ['sass/*.scss', 'sass/**/*.scss'],
tasks: ['sass','autoprefixer'],
sourceComments: 'normal',
options: {
nospawn: true,
livereload: true
}
}
},
This will recompile my SASS and the reload the page, but it takes 5-6 seconds to complete the CSS compilation, then it does a full page refresh, instead of just reloading the CSS file that changed.
So my questions are this:
How do I keep it from taking so long to compile the SASS and refresh the page, or am I just being to picky, and this is an inherit part of grunt?
How keep if from reloading the entire page, and just reload the CSS file that changed from my SASS compilation?
Check my other answer: Fastest way to compile SCSS (Compass) + refresh the browser?
grunt-contrib-sass uses Ruby sass which is very slow, it has nothing to do with grunt itself.
Use grunt-sass instead, it uses libsass which is lighting fast c implementation of sass.
Read this article:
http://benfrain.com/lightning-fast-sass-compiling-with-libsass-node-sass-and-grunt-sass/
The best solution is to move from grunt-contrib-sass to grunt-sass, but if you don't have much time to fix this, i think, you should move your 'autoprefixer' task from watch section to deploy section.
scss: {
files: ['sass/*.scss', 'sass/**/*.scss'],
tasks: ['sass',
sourceComments: 'normal',
options: {
nospawn: true,
livereload: true
}
}
In my project this trick help me, because 'autoprefixer' task works very slowly
Or you could use a live reloader tool, like fast-live-reload, in combination with the ruby sass compiler.
Note that they offer their own watcher that is very fast (e.g. for compass run: compass watch).
Disclaimer: I am the creator of fast-live-reload.
I'm trying to get sass working with grunt but there's a few things that aren't very clear, even after reading the documentation.
In my gruntfile I have:
grunt.loadNpmTasks('grunt-contrib-sass');
compass: {
files: ['<%= yeoman.app %>/styles/{,*/}*.{scss,sass}'],
tasks: ['compass']
},
grunt.registerTask('default', ['sass']);
My questions is should I create scss or css files inside my styles folder and in my html file, should I link to css or scss files?
Also, if I have a very large amount of style files, should I always include each one of them manually or is there an easier way, like in rails where every file inside the styles folder is added automatically?
EDIT
This is what my project structure looks like, only change I've made from the default yeoman angular app was adding the random.scss file that I'm trying to turn into regular css.
Your config is kind of wrong, mixing compass with sass. Take a look at that config: https://github.com/gruntjs/grunt-contrib-watch#examples
Of course you create sass or scss files that compile to css. That's what sass is for. In your html you include your final compiled css-files. You could use a plugin like assetpush which could generate the html in your files from the compiled css files. A config maybe could look like this:
grunt.initConfig({
sass: {
compile: {
files: {
'<%= yeoman.app %>/styles/main.css': ['<%= yeoman.app %>/styles/{,*/}*.{scss,sass}']
}
}
},
assetpush: {
css: {
files: {
"path/to/your.html": ["css/*.css"]
}
}
}
});
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.loadNpmTasks('grunt-assetpush');
grunt.registerTask('default', ['sass', 'assetpush']);
I want to use watch mode in my development environment. It works fine with single less file. But I have so many less files which are imported to app.less. My app.less looks
#import "variables";
#import "mixins";
It seems I can not use watch mode in this setting. Is there any other ways?
Upd. This syntax is for old grunt versions so it should not be used.
You need to use LiveReload app for this. Or maybe another software that can reload page with LiveReload browser extension (maybe Sublime Text editor with a plugin).
Possible setup is Node.js with Grunt which has grunt-contrib-less and grunt-reload modules installed.
Your grunt.js config should look like this:
module.exports = function(grunt) {
grunt.initConfig({
// Start LiveReload server
reload: {
port: 35729,
liveReload: {}
},
// Simple css compilation
less: {
src: 'less/app.less',
dest: 'css/app.css'
},
// Reload files on change
watch: {
less: {
files: ['less/*.less'],
tasks: 'less'
},
reload: {
files: ['*.html',
'css/app.css',
'js/*.js'],
tasks: 'reload'
}
}
});
// Third party modules
grunt.loadNpmTasks('grunt-reload');
grunt.loadNpmTasks('grunt-contrib-less');
// Register default task
grunt.registerTask('default', 'less');
};
Then you need to run
$ grunt watch:less
and
$ grunt watch:reload
in two separate terminal windows.
I'm totally agree with this comment
Refresh less css which has other imported less files without page load .
Thanks, thevasya.
But there's no need to start several terminals.
watch: {
less: {
files: ['less/*.less'],
tasks: 'less'
},
reload: {
files: ['*.html',
'css/app.css',
'js/*.js'],
tasks: 'reload'
}
}
after that you can start watching by
$ grunt watch
and that's it. If you change any less file, it will start only less task.
P.S.: This answer was updated for proper work with grunt 0.4.