3

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?

Srikanth Kondaparthy
  • 3,247
  • 3
  • 16
  • 19
  • Just to clarify, [edits] you have one sass file, and you want that to be processed out to a different place per project? You run it once and it outputs the CSS to where? All projects at once? I don't understand the logistics or reason behind what you're trying to accomplish. – suzumakes Mar 09 '16 at 12:29
  • Sorry if my question wasnt clear enough. Ignore the project thing, I have edited the question. Hope it makes sense. – Srikanth Kondaparthy Mar 09 '16 at 20:36
  • I think you have a four level hierarchy for your styles (components > folder > css | scss > files) as best I can tell. You want to know if Grunt can name the second level container folder and recurse that through all of your components? Seems like you have a project architecture problem. If each component only has one scss file, you don't need this 2nd level folder at all. Just put all the scss components in one folder and output them to a CSS folder. Maybe I'm missing something... – serraosays Mar 10 '16 at 18:15
  • You got the requirements quite right @staypuftman Only additional detail I can add is there are multiple scss files within each of the components. – Srikanth Kondaparthy Mar 11 '16 at 00:51

1 Answers1

2

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' ]

Emanuele Parisio
  • 1,192
  • 8
  • 27
  • Thanks for the sol. I guess it's close however we still need to provide the component folder names. The whole purpose is to avoid using component folder name – Srikanth Kondaparthy Mar 14 '16 at 06:52
  • explained a method to takes directory in an autonomous way, but i don't know if there is a possibility to do what you want without editing code of the plugin. In any case you don't have to write yourself the folder names and you need only one task! – Emanuele Parisio Mar 14 '16 at 18:01
  • I think I got what I needed. – Srikanth Kondaparthy Mar 15 '16 at 00:38