####1) FLATTEN COMPILATION PROCESS (remove recursion--Templates should not compile themselves) so this:
replace: function(match, className, code) {
const markup = ReactTemplate.compile(className, code || '');
return `ReactTemplate["${className}"] = (component, context) => { return (${markup}) }; RT.body("${className}");`
}
becomes:
replace: function(match, className, code) {
return `ReactTemplate["${className}"] = (component, context) => { return (${markup}) }; RT.body("${className}");`
}
#####a) HELPERS: within ReactTemplate.compile()
helpers dont need to be compiled recursisvely within a template anymore:
ReactRegex.forEach(function (obj) {
markup = markup.replace(obj.regex, obj.replace);
});
the markup within templates can be compiled separately since the only param it needs is markup
.
#####b) EVENTS: events currently need the className
of the compnent:
static appendEventMap(className, markup) {
var events = Events.getEvents(className);
...well it doesnt need classNames if it passes over all the code itself, getting the className from template name's. So we do events separately as well.
The general idea is flattening the execution process will reduce complexity a lot for developers. We can code it sequentially now...
####2) MAKE COMPILER EXECUTE SEQUENTIALLY:
instead of:
source = "" + new ReactTemplate(original);
const result = ReactTemplateCompiler.transpile(source, inputFile);
we do this:
source = ReactCompiler.parse(original);
const result = ReactTemplateCompiler.transpile(source, inputFile);
ReactCompiler = class {
parse(code) {
code = this.injectEventHandlers(code);
code = this.parseMarkup(code);
return this.parseTemplates(code);
}
}
and done. The idea being that developers can way more easily trace the flow of what's going on.
####3) COMBINE RENDER ASSIGNMENT + COMPONENT CREATION:
return `ReactTemplate["${className}"] = (component, context) => {
return (${markup})
};
RT.template("${className}");`;
becomes:
return `React.Component.createFromBlaze("template", "${className}", (component, context) => {
return (${markup}) ;
});`;
and React.Component.createFromBlaze()
(which is our new version of RT.template()
) at application runtime assigns our core BlazeReact mixin, this render function, utilizing the correct name + type of course:
React.Component.createFromBlaze = function(type, className, renderFunc) {
React.components[className] = class extends React.Component {
type: type,
mixins: [ReactMeteorData, BlazeReact],
render: renderFunc
}
}
...that consolidates like 3 files, and eliminates the need for this function: https://github.com/timbrandin/react-templates/blob/master/exports.js#L79
and related STATIC functions like body
in export.js.
AHA! I figured it out!! So RT has both STATIC functions that generate the components (RT.template
, RT.body, etc
) and "DYNAMIC" ones that run within the markup (RT.get
, RT.lookup
)
Now that we have started to remove the static ones, lets do the same with the dynamic instance ones--by moving them to our BlazeReact mixin, eg: BlazeReact.prototype.lookup()
, which is accessible at this.lookup()
in the markup.
This was a core complication that made it confusing. One can't tell what methods are essentially "static" and which ones are "dynamic"
in RT
within export.js. Now we have moved all these methods to locations that truly make sense.
Specifically, the static ones are now React.Component.createFromBlaze
and maybe another one or 2 like that. And the instance ones are essentially on the prototype of React.Component
via our BlazeReact
mixin. Those 2 locations deeply convey their purpose and the difference between the 2: static vs. dynamic, and maybe more importantly: unrelated to our compilation code!
####4) MOVE DYNAMIC RT METHODS (eg. lookup
) + TEMPLATE.JSX METHODS (eg. subscribe
) TO BlazeReact
MIXIN.
We now have instance methods in their correct place coming from 2 places: the old incongruent export.js file containing the RT
singleton and methods like this.subscribe
already on the resulting component. The only difference for the latter being that they are now more clearly defined on a simple Mixin.
That will give us the foundation we need to focus on regexes and lookup-related instance methods. From there we can work out all the context lookup issues.
Also by taking away ReactTemplate, I'm afraid we're taking away the possibility to easily override a template.