Skip to content

undefine "define" to avoid requirejs conflict #591

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 17, 2014

Conversation

mbarrien
Copy link
Contributor

Even with the vendored RequireJS and the call to noConflict(), we are still having problems using Django Debug Toolbar.

Even though the function noConflict removes jquery from the global namespace, simply including the jquery.js script still affects the jquery loaded by RequireJS, since the following lines in jquery.js from http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.js are run unconditionally, and are not undone by noConflict:

if ( typeof define === "function" && define.amd ) {
    define( "jquery", [], function() {
        return jQuery;
    });
}

This patch temporarily undefines RequireJS's "define" while loading the vendored jQuery, preventing itself from registering.

This is especially important in our case, where we have no global jQuery since it is only loaded via RequireJS. Our jQuery is loaded asynchronously, and since this vendored version of jQuery is loaded inline syncrhonously, this affects loading of other things that require jQuery.

@aaugustin
Copy link
Contributor

I would like to avoid introducing hacks to account for various JavaScript framework, all the more since the JavaScript world evolves very quickly.

@aaugustin
Copy link
Contributor

The answer may be to set the INSERT_BEFORE option to load the debug toolbar earlier in the page, before RequireJS. Can you try that?

@mbarrien
Copy link
Contributor Author

mbarrien commented May 6, 2014

INSERT_BEFORE was the second thing I tried after the first pull request. It too failed miserably. I'll make one last attempt to insert it even earlier, but I just kept getting different errors wherever I seemed to insert it.

@mbarrien
Copy link
Contributor Author

mbarrien commented May 6, 2014

Okay, I remember the details now why INSERT_BEFORE isn't sufficient.

The script where we end up loading our own copy of jQuery is inside the HTML "HEAD" tag. django-debug-toolbar inserts both the script tags AND the toolbar body at the same location, but you can't put the toolbar body inside of HEAD. If you really want to go down this route, than django-debug-toolbar would need to support two different places to do insertions; one for inserting the SCRIPT tags (e.g. INSERT_BEFORE_SCRIPT, possibly inside of HEAD), and one for inserting the toolbar body where it currently is.

I can try to write up a patch for that, but that seems uglier, and doesn't yet guarantee this will work in our code.

@aaugustin
Copy link
Contributor

Indeed, that's uglier.

In fact I find RequireJS particularly annoying. Its behavior makes it impossible to write code that works both with and without RequireJS, unless one resorts to dubious hacks such as this pull request.

I hope this is just an accident caused by the primitive and inconsistent model for loading JavaScript code in browsers, not a strategy to force every project to switch to RequireJS. Still, it's annoying.

aaugustin added a commit that referenced this pull request May 17, 2014
undefine "define" to avoid requirejs conflict
@aaugustin aaugustin merged commit 67affcb into django-commons:master May 17, 2014
aaugustin added a commit that referenced this pull request May 17, 2014
peap pushed a commit to peap/django-debug-toolbar that referenced this pull request Aug 20, 2015
When we undefine the entire window.define, modules loaded asynchronously
can randomly fail to register themselves. However, jQuery 2+ checks for
define.amd before registering itself as an AMD module, not just define.
So, by unsetting window.define.amd instead of window.define, we don't
break define() for other modules and we still prevent the page-global
jQuery from registering itself as an AMD module, which was the ultimate
goal of django-commons#591.
peap pushed a commit to peap/django-debug-toolbar that referenced this pull request Sep 2, 2015
When we undefine the entire window.define, modules loaded asynchronously
can randomly fail to register themselves. However, jQuery 2+ checks for
window.define.amd before registering itself as an AMD module, not just
window.define. So, by unsetting window.define.amd instead of
window.define, we don't break define() for other modules and we still
prevent the page-global jQuery from registering itself as an AMD module,
which was the ultimate goal of django-commons#591.
ryneeverett pushed a commit to ryneeverett/django-debug-toolbar that referenced this pull request Oct 2, 2016
undefine "define" to avoid requirejs conflict
ryneeverett pushed a commit to ryneeverett/django-debug-toolbar that referenced this pull request Oct 2, 2016
ryneeverett pushed a commit to ryneeverett/django-debug-toolbar that referenced this pull request Oct 2, 2016
When we undefine the entire window.define, modules loaded asynchronously
can randomly fail to register themselves. However, jQuery 2+ checks for
window.define.amd before registering itself as an AMD module, not just
window.define. So, by unsetting window.define.amd instead of
window.define, we don't break define() for other modules and we still
prevent the page-global jQuery from registering itself as an AMD module,
which was the ultimate goal of django-commons#591.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants