marionette.inspector
marionette.inspector copied to clipboard
Capture _classPath, _className, _templatePath via patchDefine
Overview
One of the things we do at Etsy that I really like, is that we add _classPath
and _className
properties to all of our class prototypes. The way we do it, is to monkeypatch the define
function in development and detect the classes as they're defined. When we find a class, we use the require path as the class path.
I think we can do something similar in patchDefine
for the inspector. The way it would work, is that we'd add some extra functionality to patchFactoryFunc so that in addition to checking to see if the module is Marionette or Backbone, it also checks to see if it's a Backbone View or Model class. If it is, it adds those properties to the prototype.
The benefit of having _className
on the prototype is that the inspector can show the class instead of the generic type. In the case of the footer view,'<Backbone.View 12>
would be replaced with <FooterView 12>
. How cool is tha? So cool!
Implementation
- improve
_patchFactoryFunc
_patchFactoryFunc = function () {
var functionBody = function (bodyArguments) {
var module = originalFunction.apply(this, bodyArguments);
var Candidate = module || this;
// check for backbone
// check for marionette
if (loadedModules.Backbone
&& instanceof module == loadedModules.Backbone.View
|| module == loadedModules.Backbone.model) {
module._classPath = the.definePath // we'll have to find that somewhere... could be (views/footerView)
module._className = the.definePath.split('/').chomp()
module._templatePath = the.templatePath // might be hard to find "template!foo/blah" in the dependencies
}
}
I think we should consider using displayName
instead of _className
It is a non-standard way of doing this that some browsers currently handle in one way or another: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/displayName
But one reason to use it, is that other people are. JSX and react add displayName. https://github.com/facebook/react/pull/799 And their devtools uses it to determine what objects are. https://github.com/facebook/react-devtools/blob/e47bccd514121574c95fcfc80f4bf2b3e5bb91ca/injected/InjectedScriptHost.js#L47
neat - good thinking
Might be easier to add a polyfill for Function.name
.
Function.name
unfortunately doesn't work here.
var m = new Backbone.Model();
console.log(m.constructor.name); // => undefined
Ah, it doesn't work for anonymous functions.