“Legacy” ember app, no ember-cli, bower, require.js, common.js.
Build process based on grunt-ember-templates
Handlebars templates precompiled on the server and served with handlebars-runtime
Manual update, without the easy ember-cli based option.
Here are the lessons.
You no longer need an EmberEnv switch to enable HTMLBars. There was a short lived bug that had produced some misleading google results.
grunt-ember-templates that is on npm ATM doesn’t support what is needed to make this work, but their master on git has the needed fixes. I believe this will be fixed shortly.
There is no replacement for handlebars and/or handlebars-runtime js files you needed to link in manually. Htmlbars is now baked into ember.
There’s an ember-template-compiler project on git. However the version there is 2 months old (last stable) and doesn’t support HTMLBars. That led me on the wrong path of believing I needed to utilize…
HTMLBars project on github. I actually hacked together a grunt task using this raw compiler and it actually worked… until I tried using the “{#each}” helper.
I spent a good few hours digging through the output of both github-derived and baked-in htmlbars compiler. Here’s what it comes down to:
Once the basic HTMLBars started working, other stuff started breaking. Namely, all the old handlebars helpers. There’s supposedly a compatibility layer, but if you’re doing anything more ambitious, you’re better off rewriting them into htmlbars helpers.
Rewriting a helper into htmlbars comes down to changing all the Ember.Handlebars.registerHelper() calls into Ember.HTMLBars.registerHelper(). And then changing the method signature, which now takes 4 arguments:
params: array with the ordered arguments. All the stuff that used to be before options
hash: what used to be at options.hash, only simplified
options: the old options, stripped down of a few things
env: I think this is the old buffer/context that used to be in options, didn’t touch it
There are no longer contexts and types info for the values in params and hash (ever since the 1.9 actually). Everything is now either a literal string or a stream (which you should check for). I still have no idea how to manipulate these streams, but it seems setting up ValueBinding still produces bound property, and that was good enough for my use case.
If you are calling any built-in helper you need to call helper.helperFunction instead of just helper. Example: return Ember.HTMLBars.helpers.view.helperFunction.call(this, [App.MyView], hash, options, env);
That’s it so far. Speed increase feels about 50%, although I’m yet to run more elaborate tests.
Note: I suspect that most of this could have been prevented by finding the right articles or forum posts where this stuff is explained. However, if such things do exist, Google was unable to find them.
I believe Ember has always differed from “native” handlebars (and I assume by extension htmlbars) by providing it’s own helpers and extensions that hook things up the Ember Way in order that computed properties and so on work correctly.
Correct. HTMLBars compiler is baked into debug versions of Ember (ember.js and ember.debug.js), but will not be included in production versions (ember.prod.js). If you need to precompile assets with a production version of Ember, you will have to also load ember-template-compiler.js into your app (essentially replacing loading handlebars.js).
The ember-template-compiler is now paired with the version of Ember you are using. Both ember.prod.js and ember-template-compiler.js are published (to S3 and Bower) in tandem. The ember-template-compiler NPM package will likely be released to support 1.10.0, but contain information on it being deprecated (in favor of using the specific version for each Ember release).
This should not be true, please open a bug report with details at Issues · emberjs/ember.js · GitHub. Helpers that previously worked should absolutely continue to work.
Directly calling helpers from within other helpers is not really supported. While it may work, it is certainly not part of Ember’s public API and is something to be avoided.
Agreed. I am sorry that the information was not readily available, and thank you for taking the time to write up your findings.
Since I already have a grunt pipeline, I’m doing my own minimization instead of using ember.prod.js. Still, good to know.
I was doing stuff like manipulate options.fn, options.hashTypes, options.hashContexts… Before 1.9, even more than that. Also, injecting my own hacks using grunt. So, not exactly a proper usage.
I suspect plain, interface-respecting helpers will work just fine. Except the next part.
ember.prod.js is not minified, it contains a number of performance improvements over using ember.debug.js (as much as 15% faster). To make this more obvious to folks, we have renamed the generated ember.js file to ember.debug.js.
This is absolutely not a public API, and any usage of it has no guarantee to work across versions. In most cases today, these sorts of helpers should be rewritten as components (which can easily invoke other helpers via their layout).
We have no documentation that suggest using helpers that call helpers, and as such I don’t really think that we should document that you shouldn’t do it either (we don’t document the things not to do).
There’s some confusion surrounding the name change, I was actually already using prod for minimization. Either way, I’ll update the build config to include the ember-templates, thx.
I wished I bumped in to this earlier it could saved me at least 4 hours…
As of Ember 1.11.1, Ember.HTMLBars.helpers.view.helperFunction.call(this, [App.MyView], hash, options, env); is no longer valid Ember.HTMLBars.helpers returns undefined
still trying to figure out how to fix ember easyForm helpers e.g
Ember.Handlebars.helpers.view.call(this, Ember.EasyForm.Error, options);