marionette.inspector icon indicating copy to clipboard operation
marionette.inspector copied to clipboard

Uncaught TypeError when using noConflict on libs

Open timsnadden opened this issue 9 years ago • 9 comments

When I enabled the Marionette Inspector I get: Uncaught TypeError: Cannot read property 'View' of undefined

I suspect that this is caused by the fact that our application uses requirejs and loads jQuery, lodash, Backbone and Marionette with noConflict set and mappings in the requirejs config so that requiring 'backbone' (for example) pulls in 'backbone-private' for all modules except 'backbone-private'.

I'm wondering if Marionette Inspector will be able to handle this setup or whether I need to modify things to make the inspector work.

apply_now

timsnadden avatar Feb 26 '15 21:02 timsnadden

Thanks for the report. Mind running this locally and setting a breakpoint in patchDefine. You'll see the fund in the call stack and in the inspector agent source

https://github.com/marionettejs/marionette.inspector/blob/master/docs/developing_locally.md

jasonLaster avatar Feb 27 '15 03:02 jasonLaster

Thanks for looking into this.

window.__agent.allPropertiesSet is called twice. The first time it succeeds and the second time it fails.

Before and after the error window.__agent.Backbone is defined.

When allPropertiesSet fails the properties argument is undefined.

I noticed the caveats around browserify and webpack. As I said, we are using requirejs but the libs are loaded with noConflict. I tried the following but still get the error.

require(['backbone', 'marionette'], function(Backbone, Marionette){
    if (window.__agent) {
        window.__agent.start(Backbone, Marionette);
    }
});

timsnadden avatar Feb 28 '15 21:02 timsnadden

@timsnadden - interesting finds. I'd like to know when the first call is made and when the second one is made. I assume you're looking inside of patchDefine and there's a ton of useful data available to you at that point wrt to the module loaded and other params to see who initiates the two calls.

I think you're onto something here that a lot of people will find who use noConflict.

jasonLaster avatar Mar 01 '15 00:03 jasonLaster

When noConflict is called on Backbone previousBackbone is undefined. The error is thrown at this point:

root.Backbone = previousBackbone;

I was able to work around the issue by not calling noConflict for Backbone and Marionette.

previousbackbone

timsnadden avatar Mar 01 '15 20:03 timsnadden

hmm, is there an easy PR here that'd fix patchDefine?

jasonLaster avatar Mar 01 '15 23:03 jasonLaster

As a first step I thought I would created the simplest Marionette app I could to demonstrate the problem. Without the inspector running this works as expected and shows 'Example content'. With the inspector running I get the Uncaught TypeError.

https://github.com/timsnadden/marionette-noconflict

timsnadden avatar Mar 14 '15 22:03 timsnadden

That's a huge step. Thanks!

Reproducing helps a lot.

jasonLaster avatar Mar 15 '15 02:03 jasonLaster

I did the same as timsnadden, I commented out the Backbone.noConflict() part the Inspector loads.

But when the inspect load, the UI tab only shows "timestamp" with the console message "Marionette Inspector: Hmmm... couldn't find yo Backbone".

When digging into the issue, I found that window.__agent.patchedBackbone is undefined.

On typing "window.__agent.patchedBackbone" on the Console of DevTools, it return the backbone object:

Object {VERSION: "1.1.2", $: function, noConflict: function, emulateHTTP: false, emulateJSON: false…}

Not sure on how to proceed from here, so any help/advice/guidance would be great.

vairav avatar Mar 17 '15 22:03 vairav

What do you mean console of DevTools?

The next step is to break in patchDefine when either Mn or BB is defined and see what happens.

this will be where patchedBackbone gets set

jasonLaster avatar Mar 18 '15 13:03 jasonLaster