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

Already on GitHub? Sign in to your account

jQuery is undefined when certain path alias is given #435

Closed
gsklee opened this Issue Aug 26, 2012 · 7 comments

Comments

Projects
None yet
4 participants

gsklee commented Aug 26, 2012

While setting the path for jQuery, whenever I am using:

require.config({
    paths: {
        'jQuery': './libs/jquery-1.8.0.min'
    }
});

Then:

define(['jQuery'], function($) {
    console.log($);
};

$ is gonna be undefined.

However if I am using:

require.config({
    paths: {
        'jquery': './libs/jquery-1.8.0.min'
    }
});

Then:

define(['jquery'], function($) {
    console.log($);
};

Everything is working great all in a sudden.

What's the issue with defining jQuery's alias with "jQuery", rather than "jquery"?

PS. Technically this doesn't happen only for "jQuery"/"jquery", but "Backbone"/"backbone" and many other libs I've tried.

The simple answer: this is because of how jQuery made itself AMD compatible.

You have to use lowercase 'jquery' otherwise jQuery won't recognise it's been loaded via AMD.

Mark McDonnell

On Sunday, 26 August 2012 at 09:34, Gias Kay Lee wrote:

While setting the path for jQuery, whenever I am using:
require.config({ paths: { 'jQuery': './libs/jquery-1.8.0.min' } });
Then:
define(['jQuery'], function($) { console.log($); };
$ is gonna be undefined.
However if I am using:
require.config({ paths: { 'jquery': './libs/jquery-1.8.0.min' } });
Then:
define(['jquery'], function($) { console.log($); };
Everything is working great all in a sudden.
What's the issue with defining jQuery's alias with "jQuery", rather than "jquery"?
PS. Technically this doesn't happen only for "jQuery"/"jquery", but "Backbone"/"backbone" and many other libs I've tried.


Reply to this email directly or view it on GitHub (jrburke#435).

gsklee commented Aug 26, 2012

I'm not sure how and why the inner work was being implemented in such a way that results in this behavior, but seems like a pretty severe pitfall to me. Beginners can have a totally failing RequireJS experience with about absolutely no idea where went wrong when following the most basic RequireJS tutorial, simply because they opted to define the lib with "jQuery" instead of "jquery".

Owner

jrburke commented Aug 26, 2012

AMD dependency IDs normally follow file name casing rules, since they can map to file paths. Also, if we consider that we want to reuse a bunch of AMD modules that all use jQuery, it is best if they all agree on a common name, with the same casing, since dependency IDs are case sensitive. This allows them to use the reuse the same dependency, and only load it once. So for larger interop, using 'jquery' is best.

Also, because anonymous modules could trigger errors in AMD loaders if they are loaded outside an AMD loader's load calls, the AMD define() call in jQuery is a named call: define('jquery',.... More details about anonymous/named modules and jQuery here:

https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon

I agree this can be confusing though for someone starting out. If there are particular places in any starter docs on the requirejs site/projects you used to get started where this should be mentioned, please let me know and I will add a note about this.

All that said, this should only affect jQuery. Most modules are anonymous, and if they name themselves, then they should be calling that out in their docs, mentioning what dependency ID to use for them. But ideally they should be anonymous define() calls.

gsklee commented Aug 28, 2012

One more thing, this following pattern seems to work:

require.config({
    paths: {
        'jQuery': './libs/jquery-1.8.0.min'
    }
});
define(['jQuery'], function(jQuery) {
    console.log($);
};

Why, and if this can be seen as an acceptable alternative? Thanks!

Owner

jrburke commented Aug 28, 2012

@gsklee in that example, the jQuery argument passed to the define() factory function is not being tested, but instead doing a console.log($). jQuery will still export a global $ and jQuery even when calling define() to minimize breaking jquery plugins that assume the globals. That global is what is being tested above.

If that jQuery variable passed in to the function was tested, it would be undefined. However if 'jquery' is used as the dependency name w/the corresponding paths change, it will have a value.

Going to close as part of bug triage, but feel free to continue discussion in this issue.

@jrburke jrburke closed this Aug 28, 2012

xixixao commented Apr 2, 2014

I must have seen this three times now, yet again, I fell into this trap. Maybe http://requirejs.org/docs/jquery.html#modulename could say explicitly

Using define(['lib/jquery'], function ($) {...}) or require('lib/jquery') will not work

or something of that sort for those slow of us...

Owner

jrburke commented Apr 4, 2014

@xixixao thanks for pointing that out, I updated that section.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment