2

So, I'm moving from grunt to gulp (or trying to anyway), and I'm having trouble getting gulp to do what I'm doing in grunt. Specifically the $templateCache stuff.

My angular app is broken up into several components/modules. Each module contains everything it needs to run (controllers, directives, partials, scss, etc.).

Using Grunt, I've been able to boil each module down into 5 files:

  • module.min.css // all module scss files compiled and concatenated
  • module.min.js // all module controllers, directives, services, etc. concatenated
  • module.tpls.min.js // all partials in $templateCache for this module
  • module.mocks.min.js // all unit test mock objects for this module
  • module.specs.min.js // all unit test specs for this module

This has worked really well for 2 years now and been a cornerstone of my modular architecture. My only reasons to try out gulp was 1) Curiosity, 2) My grunt file is getting kinda hairy as we add in deployment and environment specific stuff and so far gulp has really slimmed that down.

For the most part, I've figured out how to do all my grunt tasks in gulp, but I'm having trouble figuring out how to generate a template cache file for each module. All the gulp-ng|angular-templates|templatecache plugins take all my partials and create one file. I'd like to take all my files under module/partials/*.html and create a single module.tpls.min.js; and do that for each module.

This was actually a problem with grunt too, but I figured it out with grunt.file.expand().forEach() like this:

grunt.registerTask('prepModules', '...', function(){

    // loop through our modules directory and create subtasks
    // for each module, modifying tasks that affect modules.
    grunt.file.expand("src/js/modules/*").forEach(function (dir) {

        // get the module name by looking at the directory we're in
        var mName = dir.substr(dir.lastIndexOf('/') + 1);

        // add ngtemplate subtasks for each module, turning
        // all module partials into $templateCache objects
        ngtemplates[mName] = {
            module: mName,
            src: dir + "/partials/**/*.html",
            dest: 'dev/modules/' + mName + '/' + mName + '.tpls.min.js'
        };
        grunt.config.set('ngtemplates', ngtemplates);

    });

});

My current gulp for this same task:

var compileTemplates = gulp.src('./src/js/modules/**/partials/*.html', {base:'.'})
    .pipe(ngTemplates())
    .pipe(gulp.dest('.'));

I've only really looked at the options, but none of them seemed to do what I wanted. They were all around changing the file name, or the final destination of the file, or a module name, or whatever else; nothing that said anything about doing it for only the directory it happens to be in.

I had thought about using gulp-rename because it worked well for me when doing the CSS compilation:

var compileScss = gulp.src('./src/js/modules/**/scss/*.scss', {base:'.'})
    .pipe(sass({includePaths: ['./src/scss']}))
    .pipe(rename(function(path){
        path.dirname = path.dirname.replace(/scss/,'css');
    }))
    .pipe(gulp.dest('.'));

However, when I pipe rename() after doing ngTemplates() it only has the path of the final output file (one log entry). When you console.log() path after sass(), it has all the paths of all the files that it found (lots of log entries).

Any ideas? Thanks!

2 Answers 2

2

This SO post has the correct answer, but the wasn't coming up in my searches for this specific usage. I was going to vote to close my question, but since someone else might search using my own specific terms (since I did), it seems more appropriate to leave it alone and just redirect to the original question as well as show how I solved my own particular problem.

var fs = require('fs');
var ngTemplates = require('gulp-ng-templates');
var rename = require('gulp-rename');

var modulesDir = './src/js/modules/';

var getModules = function(dir){
    return fs.readdirSync(dir)
        .filter(function(file){
            return fs.statSync(path.join(dir, file)).isDirectory();
        });
};

gulp.task('default', function(){
    var modules = getModules(modulesDir);
    var moduleTasks = modules.map(function(folder){
        // get all partials for this module
        // parse into $templateCache file
        // rename to be /dev/modules/_____/______.tpls.min.js
        return gulp.src(modulesDir + folder + '/partials/*.html', {basedir:'.'})
            .pipe(ngTemplates({module:folder}))
            .pipe(rename(function(path){
                path.dirname = './dev/apps/' + folder + '/';
                path.basename = folder + '.tpls.min';
            }))
            .pipe(gulp.dest('.'));
    });
});

It's essentially like the tasks per folder recipe but with a change to use gulp-ng-templates. I'll probably be using this same pattern for my SCSS and JS now that I'm more aware of it.

Seems like the gulp equivalent of grunt.file.expand().forEach().

Sign up to request clarification or add additional context in comments.

Comments

0

Whenever I deal with scss/sass for gulp tasks, I will only put one scss file as the source parameter. This parameter file is composed of a list of imports. This way you don't need to rely on gulp to concat the scss file contents for you.

 //in gulpfile
 gulp.src('./src/js/modules/**/scss/main.scss', {base:'.'})

 //in main.scss
 @import 'a', 'b', 'c';

a, b, and c would represent your other scss files.

1 Comment

Hey Jake, thanks for taking a stab. I guess I created confusion by showing how I was doing my scss processing. I'm actually looking to generate a $templateCache file per module [directory] like how I do it in grunt. Your solution is more for someone who would be managing scss with gulp. Good practice but not what I was looking for. :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.