Grunt dynamic dest location sass - css

This could possibly be a repeat question but I couldn't figure out a solution for my requirement
I am trying to create a sass grunt task which can generate css files in a dynamic location. Here is my structure
/components
--> xyz
--> scss
--> xyz.a.scss
--> xyz.b.scss
--> abc
--> scss
--> abc.a.scss
--> abc.b.scss
Can the grunt task create a new folder relative to its component i.e
/components
--> xyz
--> scss
--> xyz.a.scss
--> xyz.b.scss
--> css
--> xyz.a.css
--> xyz.b.css
--> abc
--> scss
--> abc.a.scss
--> abc.b.scss
--> css
--> abc.a.css
--> abc.b.css
My current SASS task, generates CSS files in the same folder of SCSS
sass: {
dist: {
files: [{
expand: true,
cwd: '<%= yeoman.client %>/components/',
src: ['**/*.scss'],
dest: '<%= yeoman.client %>/components/',
extDot: 'last',
ext: '.css'
}]
}
},
I understand we could achieve this by providing component folder name in the dest, for example for xyz component I could use dest as <%= yeoman.client %>/components/xyz/css. But I will have to write seperate task for each component. Is there a way to keep dest in the same parent folder without actually specifying the name of the folder? i.e src: ['**/scss/*.scss'] and dest be: ['**/css/'] Is there a way to do this?

You can use dynamic parameters to pass in the task:
for example:
grunt sass:xyz
than in the code you can use something like this:
sass: {
dist: {
files: [{
expand: true,
cwd: '<%= yeoman.client %>/components/',
src: ['**/<%= grunt.task.current.args[0] %>/sass/*.scss'],
dest: '<%= yeoman.client %>/components/<%= grunt.task.current.args[0] %>/css',
extDot: 'last',
ext: '.css'
}]
}
},
the only things that you must set is a generic task that execute it for all the components for example:
grunt.registerTask('sassAll', [ 'sass:xyz', 'sass:abc' ]);
you can even generate an array and cycling it:
grunt.registerTask('sassAll', function() {
gruntUtils.sassTasks.forEach(function(param){
grunt.task.run('sass:' + param);
});
});
var gruntUtils = {
sassTasks : [ 'xyz', 'abc' ]
};
you can use even more parameters for setting dest and source:
grunt sass:xyz/sass:xyz/css
and reference to the second parameter:
<%= grunt.task.current.args[1] %>
I found a way to retrive the directory(not sub-directory) inside a base one:
var templates = grunt.file.expand({
filter: "isDirectory",
cwd: "(your base dir path in relation to the gruntfile.js)/components"
},["*"]);
var dirs = templates.map(function (t) {
return t;
});
than you have an array(dirs) to use instead of [ 'xyz', 'abc' ]

Related

Trying to compile sass/scss file into css files (one to one)

We are trying to compile our sass files to css files, however we want to compile each individual sass file into an individual css file (one-to-one).
For example our product_view.scss should have a product_view.css.
However all configurations we have tried create one css file for everything called styles.css in our "out/css" folder.
sass: {
dist: {
options: {
compass: true,
style: 'expanded'
},
files: [{
expand: true,
cwd: '<%= pkg.src %>/assets/sass',
src: ['*.scss'],
dest: '<%= pkg.src %>/assets/media/out/css',
ext: '.css'
}]
},
},
I use grunt-contrib-compass (Compass) to compile my SASS, which has some nice extras. For example, compass includes a reset utility you can use by using
#import 'compass/reset';
But disregarding that, compass also outputs every file individually (as long as it does not start with _ which are files that can be included but won't be compiled by themselves). Here is the setup I use in my gruntfile:
compass: {
'default': {
options: {
sassDir: "css/sass/",
cssDir: "css/",
outputStyle: "compressed"
}
}
}

Grunt usemin task not updating nested relative paths correctly

I have a Yeoman project scaffolded with 'webapp-generator' which contains a static website with nested HTML files, resembling this structure:
-root/
index.html
-directory/
file1.html
-directory2/
file2.html
-js/
(revved .js files)
-css
(revved .css files)
I'm using usemin and filerev tasks to update the filerevved file paths on the .html documents. It updates all file names correctly on js/css/images and it works correctly on the root index.html.
However, on the nested HTML files, it doesn't replace the reference to the correct nested path.
For example.
js/scripts.js gets renamed to js/827385.scripts.js
In index.html
<scripts src="js/scripts.js"></scripts>
resolves to: <scripts src="js/827385.scripts.js"></scripts>
But in directory/file1.html (or any other nested html file)
<scripts src="../js/scripts.js"></scripts>
gets also converted to: <scripts src="js/827385.scripts.js"></scripts>
Ignoring the ../ relative path
Is there any way to tweak the Grunt tasks to be aware of the relative depth of the file within the directories to keep the relative indicator ../ in the renamed path?.
Below is the code snippet for the relevant Grunt tasks.
PS: I have already followed some of the possible answers in this Stack Overflow question: How should I configure grunt-usemin to work with relative path to no avail.
// Renames files for browser caching purposes
rev: {
dist: {
files: {
src: [
'<%= config.dist %>/scripts/{,**/}*.js',
'<%= config.dist %>/styles/{,**/}*.css',
'<%= config.dist %>/images/{,**/}*.*',
'<%= config.dist %>/styles/fonts/{,**/}*.*',
'<%= config.dist %>/*.{ico,png}'
]
}
}
},
// Reads HTML for usemin blocks to enable smart builds that automatically
// concat, minify and revision files. Creates configurations in memory so
// additional tasks can operate on them
// <%= config.dist %>
useminPrepare: {
options: {
dest: 'out',
// root: '<%= config.app %>'
},
html: '<%= config.app %>/index.html'
// root: '<%= config.app %>'
},
// Performs rewrites based on rev and the useminPrepare configuration
usemin: {
options: {
assetsDirs: [
'<%= config.dist %>',
'<%= config.dist %>/images',
'<%= config.dist %>/styles'
]
},
html: ['<%= config.dist %>/**/*.html'],
css: ['<%= config.dist %>/styles/**/*.css']
},
In my case I've found out that the problem was usemin configuration in the html files:
If you have in your index.html this usemin directive:
<!-- build:js styles/jquery.js -->
<script src="bower_components/jquery/dist/jquery.js"></script>
<!-- endbuild -->
In directory/file1.html you should try to use a full path in it:
<!-- build:js /scripts/jquery.js-->
<script src="../bower_components/jquery/dist/jquery.js"></script>
<!-- endbuild-->
which will be converted to something like <script src="/scripts/jquery.34ad31c3.js"></script>.

Famo.us and Font-Awesome

anyone experienced issues while distributing a project with grunt including font awesome?
My problem is that on the final distribution project inside "dist" folder i miss font-awesome...
Font-Awesome folder in my project is located in:
app/lib/font-awesome/css/font-awesome.min.css
What i've done so far:
i tried to edit copy.js (in grunt folder) like this:
src: [
'**/**.{ico,png,gif,txt,jpg,svg,wof,ttf}',
'.htaccess',
//'images/{,*/}*.webp',
//'content/{*.*,*/}*.*',
'content/{,*/}/{,*/}/*.*',
// '{,*/}*.html',
'styles/fonts/{*.*,*/}*.*',
'lib/famous/**/**.css',
'lib/font-awesome/{,*/}/**.css'
]
..to distribute font-awesome too and now it is in the dist folder but when i open index.html it just can't seem to find the correct path and i see no icon.
Thanks
To simplify everything and speed up loading, you could just link to a CDN hosted version of Font Awesome. BootstrapCDN will serve it for you: http://www.bootstrapcdn.com/#fontawesome_tab
Given that you've got this in index.html:
<!-- build:css(app/) css/app.css -->
<link rel="stylesheet" type="text/css" href="content/vendor/font-awesome/css/font-awesome.min.css" />
<link rel="stylesheet" type="text/css" href="styles/app.css" />
<!-- bower:css -->
Grunt will place the font awesome css in dist/css. The problem is that font-awesome is looking for fonts relative to this file (../fonts), and the fonts did not move along with the css during the build process. So, alter your grunt/copy.js file to do this for you:
// Copies remaining files to places other tasks can use
module.exports = {
dist: {
files: [{
expand: true,
dot: true,
cwd: '<%= config.app %>',
dest: '<%= config.dist %>',
src: [
'**/**.{ico,png,txt,jpg,svg,wof,ttf}',
'.htaccess',
'images/{,*/}*.webp',
// '{,*/}*.html',
'styles/fonts/{,*/}*.*',
'lib/famous/**/**.css'
]
},
// add this, making sure the path is correct to your fonts
{
expand: true,
dot: true,
cwd: '<%= config.app %>/content/vendor/font-awesome/fonts/',
src: ['*.*'],
dest: '<%= config.dist %>/fonts'
}]
}
};
run grunt again, and the dist folder should now contain a fonts folder.

How to configure grunt's usemin:css task to rewrite rev'd images?

I'm building a site using the Yeoman generator: https://github.com/Thomas-Lebeau/generator-bootstrap-less.
I've installed fancybox using bower by doing the following:
bower install fancybox --save
add the fancybox script include into my usemin build block in index.html
#import "../bower_components/fancybox/source/jquery.fancybox.css"; into my only .less file
finally, copy across the fancybox vendor images using the following config in grunt's copy task.
code:
// Gruntfile.js
...
copy: {
dist: {
files: [{
expand: true,
dot: true,
cwd: '<%= yeoman.app %>',
dest: '<%= yeoman.dist %>',
src: [
'*.{ico,png,txt}',
'.htaccess',
'images/{,*/}*.{webp,gif}']
}, {
expand: true,
dot: true,
cwd: '<%= yeoman.app %>/bower_components/fancybox/source',
src: '**/*.{png,jpg,jpeg,gif}',
dest: '<%= yeoman.dist %>/bower_components/fancybox/source'
}]
},
...
(Sorry, don't know why the formatting is glitched there.. https://gist.github.com/ptim/8555923)
This is working for me, but I'd like to take it a step further to get a better understanding of what's going on. It's working simply because I'm replicating the relative path used in app/ when I copy.
What I'd like is to have the bower assets copied in with my other images, and the paths in my html rewritten (as happens with imagemin and usemin, etc)
....
}, {
expand : true,
dot : true,
cwd : '<%= yeoman.app %>/bower_components/fancybox/source',
src : '**/*.{png,jpg,jpeg,gif}',
dest : '<%= yeoman.dist %>/images'
}]
....
How do I achieve that using the conventions of this package?
(I've seen alternate suggestions: How to rewrite urls of images in vendor CSS files using Grunt)
I've tried changing the dest: path, and adding flatten: true
Here's the trail I'm following:
grunt build finishes with copy, rev, usemin,
rev is adding a version number to the fancybox files
usemin is executes usemin:html and rewrites all the image filenames to match the rev'd files
usemin:css then runs, but doesn't list any rewrites, then grunt finishes:
Running "usemin:css" (usemin) task
Processing as CSS - dist/styles/cf3b732a.main.css
Update the CSS with new img filenames
Done, without errors.
Can anyone suggest a tweak for me?

yeoman: how to compress components?

In yeoman application all my scripts are minified and compressed into single file, but all the "components" are copied as is which is an absurd - because it's a ~130 files in the starter project...
This what I belive is responsible for the concatenation task and the question is how to make it include my components which are mentioned in the index.html file? What parameters are to the files object are? Can't find anything in the documentation.
concat: {
dist: {
files: {
'<%= yeoman.dist %>/scripts/scripts.js': [
'.tmp/scripts/{,*/}*.js',
'<%= yeoman.app %>/scripts/{,*/}*.js'
]
}
}
},
I think what you're looking for is grunt-usemin.
When you include your components, you can wrap your <script> tags in <!-- build:js js/foo.js -->.
<!-- build:js js/main.js -->
<script src="js/carousel.js"></script>
<script src="js/index.js"></script>
<!-- endbuild -->
The useminPrepare task that's included in the package will cycle through any scripts within that block and add them to the concat/uglify task. Your task list might then include something like this:
useminPrepare: {
html: [ '<%= yeoman.dist%>.html' ],
options: {
uglify: 'uglify'
}
},
usemin: {
html: [ '<%= yeoman.dist%>.html' ],
options: {
basedir: 'dist'
}
},
Output to your foo.html would then be whatever you specify in the build comment. In my case, the scripts are concatenated, minified, and the reference to them is replaced with <script src="js/main.js"></script>.

Resources