-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Conversation
I would like to avoid introducing hacks to account for various JavaScript framework, all the more since the JavaScript world evolves very quickly. |
The answer may be to set the |
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. |
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. |
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. |
undefine "define" to avoid requirejs conflict
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.
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.
undefine "define" to avoid requirejs conflict
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.
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:
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.