I am also looking for best practices to enhance and scale my apps through a well conceived architecture. All of the above mentioned practices work for small to medium size apps but will fail when you work in a bigger team. There are several ways I have tried:
1) I followed this strategy: https://github.com/aldeed/meteor-autoform to scale and reuse templates. The author has a very good idea on component and field design. I am currently implementing it because the community developed 36 packages that cover almost every case and I can use TypeScript to be type safe during the development phase.
<template name="autoForm">
{{#unless afDestroyUpdateForm this.id}}
{{! afDestroyUpdateForm is a workaround for sticky input attributes}}
{{! See https://github.com/meteor/meteor/issues/2431 }}
<form {{atts}}>
{{> Template.contentBlock ..}}
</form>
{{/unless}}
</template>
Here is a good blog post on how to do it: http://blog.east5th.co/2015/01/13/custom-block-helpers-and-meteor-composability/ as well as here: http://meteorpedia.com/read/Blaze_Notes
2) This one looks so promising but hasn't been updated lately. It is a package written in coffee script called. Blaze Components (https://github.com/peerlibrary/meteor-blaze-components) for Meteor are a system for easily developing complex UI elements that need to be reused around your Meteor app. You can use them in CoffeeScript, vanilla JavaScript and ES6. The best thing is, components are OOP. Here is one of their examples:
class ExampleComponent extends BlazeComponent {
onCreated() {
this.counter = new ReactiveVar(0);
}
events() {
return [{
'click .increment': this.onClick
}];
}
onClick(event) {
this.counter.set(this.counter.get() + 1);
}
customHelper() {
if (this.counter.get() > 10) {
return "Too many times";
}
else if (this.counter.get() === 10) {
return "Just enough";
}
else {
return "Click more";
}
}
}
ExampleComponent.register('ExampleComponent');
{{> ExampleComponent }}
3) I like types and transpiler that tell me where and when something will go wrong. I am using TypeScript to work with Meteor and found the following repository: https://github.com/dataflows/meteor-typescript-utils it seems like the creator tried to accomplish an MVC approach.
class MainTemplateContext extends MainTemplateData {
@MeteorTemplate.event("click #heybutton")
buttonClick(event: Meteor.Event, template: Blaze.Template): void {
// ...
}
@MeteorTemplate.helper
clicksCount(): number {
// ...
}
}
class MainTemplate extends MeteorTemplate.Base<MainTemplateData> {
constructor() {
super("MainTemplate", new MainTemplateContext());
}
rendered(): void {
// ...
}
}
MeteorTemplate.register(new MainTemplate());
<template name="MainTemplate">
<p>
<input type="text" placeholder="Say your name..." id="name">
<input type="button" value="Hey!" id="heybutton">
</p>
<p>
Clicks count: {{ clicksCount }}
</p>
<p>
<ul>
{{#each clicks }}
<li> {{ name }} at <a href="{{pathFor 'SingleClick' clickId=_id}}">{{ time }}</a></li>
{{/each}}
</ul>
</p>
</template>
Unfortunately, this project is not maintained or actively developed.
4) and I think that was mentioned already, you can scale using packages. That requires a good abstract way of thinking. It seems to work for Telescope: https://github.com/TelescopeJS/Telescope
5) meteor-template-extension – provides various ways of copying template helpers, event handlers and hooks between templates, allowing code reuse; a downside is that all copying has to be taken care by a developer, often again and again, which becomes problematic as codebase grows; moreover, without a clearly defined API community cannot build and share components
6) Flow Components – Flow Components are closer to React in the API design while Blaze Components are keeping familiar concepts like data contexts and template helpers; Flow Components on the other hand still use template-based event handlers while Blaze Components make them class methods so it easier to extend or override them through inheritance; in general Blaze Components seems to be more OOP oriented; Flow Components are not yet officially released (text credits for #5 and #6 https://github.com/peerlibrary/meteor-blaze-components#javascript-and-es6-support)
Number 2 and 3 need some getting used too, but you'll gain development speed over time. Number four lets you build and test components to make your code more stable. Number three comes with the advantage of full type safety of Typescript, which is a huge plus when you develop in a team with poor documentation. However, I am currently porting number two to TypeScript because I feel very comfortable to work with it and I don't have to tweek the compiler package to make it work with Meteor when I am not using Gulp.
It is still hard to find the right way to work with Meteor. You need to figure it out for yourself, otherwise you end up with a nicely arranged folder structure, but you have no clue where everything is. Happy coding.