Side navigation
#13504 closed bug (notabug)
Opened February 23, 2013 07:53PM UTC
Closed February 24, 2013 05:31PM UTC
Last modified June 08, 2013 08:47PM UTC
noConflict() does not undef from AMD
Reported by: | itay@neeman.net | Owned by: | |
---|---|---|---|
Priority: | undecided | Milestone: | None |
Component: | unfiled | Version: | git |
Keywords: | Cc: | ||
Blocked by: | Blocking: |
Description
When somebody calls jQuery.noConflict([true]), it does not undefine the registered module from define.
For example, if I have something like:
<script src="jquery.js"></script> <script> var my$ = $.noConflict(true); </script>
and then some other script tries to do:
<script src="other-jquery.js"></script> <script> require(["jquery"], function($) { ... }); </script>
It will get the old jQuery. Furthermore, if you try and define a path with the name of 'jquery' in require.js, it will always resolve to the first one jQuery. noConflict should also undefine itself from require.
Attachments (0)
Change History (3)
Changed February 24, 2013 05:31PM UTC by comment:1
resolution: | → notabug |
---|---|
status: | new → closed |
Changed June 08, 2013 06:48PM UTC by comment:2
//noConflict
should have nothing to do with AMD.
Ideally, perhaps. But in practice, [https:github.com/jquery/jquery/blob/master/src/exports.js#L23 jQuery butchers the global namespace], even when loaded via AMD. noConflict
is the recommended solution, remember?
Nor should you ever need to undefine a module.
Ideally, perhaps. But in practice, jQuery butchers the AMD scope by defining itself as the named module, jquery
. This greatly increases the chances of collisions in scenarios where 2 AMD modules (loaded on the same page, without knowledge of the other's existence) depend on different versions of jQuery. I don't know if the AMD spec defines how to handle module ID collisions, but it looks like the RequireJS implementation accepts the first module definition and ignores any subsequent attempts to redefine it. It also provides a means of undefining a module, but that's substantially different from noConflict
's behavior (which returns the conflicting variables to their previous owner).
Another problem that could arise from jQuery naming itself jquery
is that a developer could publish an AMD module that uses a customized copy of jQuery. The developer probably wouldn't think to customize the module ID. As a result, an AMD script can essentially hijack the jquery
module ID before the real jquery.js has a chance to claim it. Any AMD modules that depend on jquery
would transparently be given the customized version. This might even be exploited for malicious purposes...?
The real issue here, in my opinion, is that jQuery defines itself as jquery
, and this makes it difficult for developers to create robust, jQuery-dependent AMD apps/widgets that will be embedded in uncontrolled environments. Undefining (or rolling back) jquery
via noConflict
is one possible solution, but I think a better solution is to make this an anonymous define call. I know jrburke had some reasoning for hard-coding the jquery
module ID, but perhaps that decision deserves another look.
If the jQuery AMD module is anonymous, developers have the option of assigning it a unique module ID and using it privately (e.g., in their widget), without worrying about breaking jquery
-dependent modules that might already exist on the host page.
Changed June 08, 2013 08:47PM UTC by comment:3
I posted a response to dslatten's anonymous module registration question here:
https://github.com/jquery/jquery/pull/557#issuecomment-19155140
and suggest either keeping that discussion there, or broken out separately as a different, standalone ticket from deciding how to deal with a global jQuery variable if AMD is in use (see above comment for details).
noConflict
should have nothing to do with AMD. Nor should you ever need to undefine a module. AMD loaders have their own processes for loading different versions of jQuery. Burke wrote a little loader plugin for requirejs on the fly for this problem. https://github.com/jrburke/requirejs/issues/221