dbashford / mimosa-handlebars

A Mimosa 2.0 module for Handleabars template compiling
0 stars 0 forks source link

issue with handlebars.wrapType = 'common' #2

Closed breathe closed 10 years ago

breathe commented 10 years ago

I'm trying to compile handlebars templates for use in a nodejs app.

The generated templates don't seem to reference the handlebars library properly -- I've tried with both an explicit config.handlebars.lib=require('handlebars') and with leaving the handlebars.lib value to default. Here is my mimosa-config:

exports.config =
  modules: ["jshint", "coffeescript", "handlebars"]
  coffeescript:
    options:
      bare: false
  watch:
    sourceDir: "src"
    compiledDir: "lib"
    javascriptDir: null
  jshint:
    rules:
      node: true
  template:
    outputFileName: "templates"
    wrapType: "common"

This is the templates.js file produced -- require('null') on line 1?

var Handlebars = require('null');
if (!Handlebars) {
  throw new Error("Handlebars library has not been passed in successfully");
}

var template = Handlebars.template, templates = {};
Handlebars.partials = templates;

//
// Source file: [/Users/ncohen/software/win-projects/winbuild/src/startnet.cmd.hbs]
// Template name: [startnet.cmd]
//
templates['startnet.cmd'] = template(function (Handlebars,depth0,helpers,partials,data) {
  this.compilerInfo = [4,'>= 1.0.0'];
helpers = this.merge(helpers, Handlebars.helpers); data = data || {};
  var buffer = "", stack1, helper, functionType="function", escapeExpression=this.escapeExpression;

  buffer += ":: Dynamic values in this template are filled in at winpe build time and\n:: copied into the winpe boot image.  This script is then run when winpe boots.\n\n:: When run it performs the following operations:\n:: - initializes network adapter\n:: - mount remote storage\n:: - prompt user for which windows version to install (currently win7 or win8)\n:: - kick off appropriate setup.exe with correct arguments for this build variant\n\n\n@echo off\ntitle Mount remote share and start network installation\n:home\ncls\n\nwpeinit\nwpeutil initializenetwork\nping 127.0.0.1 -n 16 -w 1000>null\n\necho Attempting to mount the samba fileserver\n\ngoto marfac\n\necho.\necho Mount the network share containing the windows installer\necho You will be prompted to enter a password for that share\necho =============\n\n:mounting\necho attempting to mount share \\\\sts-cdn.ucsd.edu\\windows_installer as user STS\\unattended\necho --\necho Enter password for user STS\\unattended\nset /p password=\nnet use z: \\\\sts-cdn.ucsd.edu\\windows_installer /user:STS\\unattended || goto mount\n\n: if the script gets here that should mean the mount succeeded ... now kickoff the installer\n\n:chooseversion\necho ... mount succeeded\necho Select which windows release to install:\necho =============\necho.\necho 1) win7 x64 sp1 professional\necho 2) win8.1 x64 professional\necho.\nset /p win_install_version=option:\nif \"%win_install_version%\"==\"1\" goto win7\nif \"%win_install_version%\"==\"2\" goto win8\ngoto chooserelease\n\n:win7\necho Preparing to install windows 7\nz:\\win7\\os\\x64\\setup.exe /unattend:z:\\win7\\site\\unattend_x64.xml /installfrom:z:\\win7\\os\\images\\win7.{variant}.wim}\n\ngoto exit\n\n:win8\necho Preparing to install windows 8.1\nz:\\win8\\os\\x64\\setup.exe /unattend:z:\\win8\\site\\unattend_x64.xml /installfrom:z:\\win8\\os\\images\\win8.";
  if (helper = helpers.variant) { stack1 = helper.call(depth0, {hash:{},data:data}); }
  else { helper = (depth0 && depth0.variant); stack1 = typeof helper === functionType ? helper.call(depth0, {hash:{},data:data}) : helper; }
  buffer += escapeExpression(stack1)
    + ".wim\n\ngoto exit\n\n:exit\n";
  return buffer;
  })

module.exports = templates;
breathe commented 10 years ago

I see the option to control this is templates.commonLibPath

https://github.com/dbashford/mimosa-handlebars/blob/master/src/index.js#L57

Is it strange that this is part of the template config instead of the handlebars compiler config ... Somehow that seems odd to me ... given that I could set handlebars.lib = require('handlebars') and additional configuration of the generated commonjs output ends up still being required or the generated module won't work ...

Not sure if I should close this issue -- I'm pasting the 'correct' config below -- but I think there is a question whether template.commonLibPath should need to be set explicitly when wrapType='common' ... I'll let you close if you think no changes are warranted.

breathe commented 10 years ago

In case anyone comes across this -- the appropriate mimosa-config for this is:

exports.config =
  modules: ["jshint", "coffeescript", "handlebars"]
  coffeescript:
    options:
      bare: false
  watch:
    sourceDir: "src"
    compiledDir: "lib"
    javascriptDir: "./"
  jshint:
    rules:
      node: true
  template:
    outputFileName: "templates"
    wrapType: "common"
    commonLibPath: 'handlebars'
dbashford commented 10 years ago

You'll remember back a ways when all the template compilers lived inside mimosa. When I broke them out, I had to decide, do I duplicate all of these settings inside each template compiler, or do I keep the template compilers a little more lean and keep things that make sense inside template, which means managed by mimosa core's validation, etc.

For why commonLibPath is needed, two things to keep in mind, 1) mimosa still contains a bit of a slant towards AMD/require and 2) Mimosa has always been a browser dev tool first; the fact that you can do server dev is a happy accident.

While Mimosa has grown beyond it a bit, it's still slanted towards AMD dev. mimosa-require is the biggest and most powerful module in the module set. So there's not been a need to provide a path to your client template compiler if you are using AMD because Mimosa almost entirely has that figured out via mimosa-require and via the fact that each template compiler comes with an AMD version of the client library.

If you imagine that you are building templates for the client, which is still Mimosa's chief use case (rather than the server development), then the require('handlebars') still requiring a commonLibPath makes more sense. require('handlebars') just points me to where your server-side compiler is. It is what lets you very easily swap versions of the compiler.

commonLibPath is still needed because for commonjs in the browser what the commonLibPath needs to be is something like public/javascripts/vendor/handlebars/handlebars. So require('handlebars') and require('public/javascripts/vendor/handlebars/handlebars') are obviously solving two entirely different problems.

On the first point, template config rolled up into template, I hear ya, and I suspect that if I had to do it over again I may head in a different direction, maybe moving more of the template config to each compiler, but it would be an epic and wide ranging fix. I'd have to address every template compiler, adding boilerplate to each for default config, validation, etc. And it plusses up the LOE for adding another template compiler down the road.