Skip to content

Instantly share code, notes, and snippets.

@faceyspacey
Created December 1, 2015 13:01
Show Gist options
  • Save faceyspacey/a6658f78e2dc80b29676 to your computer and use it in GitHub Desktop.
Save faceyspacey/a6658f78e2dc80b29676 to your computer and use it in GitHub Desktop.
meteor-react notes for Tim Brandin
Plugin.registerCompiler({
extensions: ['jsx'],
}, function () {
return new BabelCompiler({
react: true
});
});
var oldProcessFilesForTarget = BabelCompiler.prototype.processFilesForTarget;
var parentReg = /(<([A-Z][a-z0-9]+[\s\S]*?)(\/>|>))/g;
var lookupReg = /(?:this\.(\w+)\(([\s\S]*?)\))/g;
var parentReplace = "<$2 __parent={this} $3"; //allow for climbing component tree backwards via `__parent`
var lookupReplace = "this.__lookup('$1', [$2])"; //`this.__lookup` will perform method search utilizing `__parent`
BabelCompiler.prototype.processFilesForTarget = function (inputFiles) {
var proto = inputFiles[0].__proto__.__proto__; //anyone know a better way to access this prototype?
if(!proto.__modified) {
this.assignNewGetContentsAsString(proto); //streamline modified transpilation
}
return oldProcessFilesForTarget.apply(this, arguments);
};
BabelCompiler.prototype.assignNewGetContentsAsString = function(proto) {
var oldGetContentsAsString = proto.getContentsAsString;
var self = this;
proto.getContentsAsString = function() {
var code = oldGetContentsAsString.apply(this, arguments);
return self.meteorizeJsx(code); //apply regex/replace
};
//same prototype used between builds; this is how we check if its modified:
proto.__modified = true;
};
BabelCompiler.prototype.meteorizeJsx = function(code) {
return code.replace(parentReg, parentReplace).replace(lookupReg, lookupReplace);
};
//** BELOW IS A METHOD IN THE REACT COMPONENT MIXIN **/
__lookup(prop, args) {
let component = this;
let method;
let oldProps;
let ret;
while(component && !method) { //climb component tree backwards to find first component that defines method
if(component[prop]) method = component[prop]; //component has method
else component = component.props.__parent; //or we climb to next parent
}
if(method) {
oldProps = component.props; //switch props to Blaze helper/event context (fixing helpers to be like events)
component.props = this.props; //i.e. context of component where helper/event triggered
ret = method.apply(component, args); //gather return value
component.props = oldProps; //put props back for other methods to utilize like normal
return ret;
}
else return ''; //similar to how undefined variables in spacebars return an empty string
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment