gruntjs/grunt-contrib-handlebars

compilerOptions not applied

Opened this issue · 8 comments

Using options like min or m to minify content doesn't work. Nor does amd, etc.

version 0.9.2

compile: {
    options: {
        compilerOptions: {
            amd: true,
            min: true
        }
    },
    files: {
        'templates/build/templates.min.js': 'templates/*.hbs'
    }
}

compilerOptions are passed as a second argument to method Handlebars.precompile, which means it accepts the following keys:

- data
- compat
- knownHelpers
- knownHelpersOnly
- trackIds
- noEscape
- strict
- assumeObjects
- preventIndent
- srcName
- destName

Options such as min, simple, bom, etc are meant for the command line script, but this grunt task doesn't deal with that one.

@amenadiel What's the proper way to minify the file generated by this plugin? Does it have to separately be run through the uglify plugin?

FYI, I migrated a long time ago from this plugin to using handlebars module natively... There's not much magic this plugin does, anyway.

@dwelle ha, well now I feel silly. I was originally using the handlebars command directly as well, but just switched to this plugin because I thought it would be better to use grunt for this task rather than my cobbled together script.

Do you still use grunt to run the handlebars command for you, or do you run it directly yourself from the command line?

Still using grunt coz we have a build pipeline that's hugely dependent on it. So for handlebars, it's a just another grunt task we register.

@dwelle Any way you can share some of the code from that task? I'm just looking for an example of running the handlebars bash command from within a grunt task.

@flyingL123 our task is pretty huge coz it does many other things, but I've factored out the gist of it, for you ;)

  1. First, install necessary packages

    $ npm i -D uglify-js handlebars html-minifier
    
  2. the grunt task

    const uglify     = require("uglify");
    const Handlebars = require("handlebars");
    const Minifier   = require("html-minifier");
    
    function compileFile ( filepath ) {
    
        // for this example, each file should have one single hbs template/partial
        const html = grunt.file.read( filepath );
    
        // minify the template's HTML
        const minified = Minifier.minify( html, {
            removeComments: true,
            caseSensitive: true
        });
    
        const name = filepath.match(/([\w-]+)\.hbs$/)[1];
    
        // if the file contains a HBS template, or HBS partial.
        // By default, let's make it a template.. you should parse this from the filename 
        //   or something like that
        const type = "template";
    
        const js = Handlebars.precompile( html, {} );
    
        return type === "template"
            ? `window.hbs["${name}"] = Handlebars.template(${js});`
            : `Handlebars.registerPartial(
                "${name}", window.hbs["${name}"] = Handlebars.template(${js})
            );`;
    }
    
    grunt.registerTask( "hbs", function () {
    
        const filepaths    = grunt.file.expand("/path/to/hbs/templates/*.hbs");
        const declarations = filepaths.map( compileFile );
    
        let output = `
            window.hbs = window.hbs || {};
            ${ declarations.join("\n") }
        `;
    
        // minify JS output
        output = uglify.minify( output, { fromString: true }).code;
    
        grunt.file.write( "./hbsTemplates.js", output );
    });

thanks @dwelle