Require.js is hurting my brain. Some fundamental questions about the way it loads scripts/modules

javascript, jquery, module, requirejs

Solution

Paths tell require.js where to look when you require that dependency.

For example i have things configured like this:

"paths": { 
    "jquery": "require_jquery"
},
"shim": {
    "jquery-cookie"  : ["jquery"],
    "bootstrap-tab"  : ["jquery"],
    "bootstrap-modal": ["jquery"],
    "bootstrap-alert": ["jquery"]
},

this means that every time in a module I do

define( ['jquery']

requirejs loads the file `require_jquery` from the main path instead of trying to load jquery.js. In your case it would load the jQuery source file, which would then be globally available. I personally don't like that approach and for that reason in the require_jquery.js file I do:

define( ["jquery_1.7.2"], function() {
    // Raw jQuery does not return anything, so return it explicitly here.
    return jQuery.noConflict( true );
} );

which means that jQuery will be defined only inside my modules. (This is because i write Wordpress plugins and so I can include my own version of jQuery without touching the outside version)

Exports (reading from the docs simply should be the name of the module you are using so that it can be detected if loading went correctly. Here is explained. So if you want to set an export for underscore it should be `_`

jQuery should be global as I explained, if you simply import it the file is executed and jQuery is global

EDIT - to answer the comments.

yes i mean that, you must export $ or jQuery for jQuery and _ for backbone. From what i got from the docs this is needed only in some edge cases and would not be necessary for libraries that declare themselves in the global namespace as jQuery.

I think that requirejs needs them when it has to fallback from loading jQuery from a CDN. i think that requirejs first tries to load jQuery from the CDN, then makes a check to verify that it was loaded correctly by checking that the "exported" variable exists, and if it doesn't it loads it form the local filesystem (if you had configured fallbacks, of course). This is something that it's needed when requirejs can't see a 404 coming back.

jQuery is globally available because it's declared global. If you simply load and execute the jQuery script, you will end up with two globals, `$` and `jQuery` (or you can do as i did and avoid that). Inside the `define()` function you can alias jQuery to be whatever you want.

define( [ 'jquery' ], function( jq ) {
    // jq is jquery inside this function. if you declared it 
    // globally it will be also available as $ and jQuery
} );

Problem

Let's assume this is my config.js or main.js: ``` require.config({ // paths are analogous to old-school <script> tags, in order to reference js scripts paths: { jquery: "libs/jquery-1.7.2.min", underscore: "libs/underscore-min", backbone: "libs/backbone-min", jquerymobile: "libs/jquery.mobile-1.1.0.min", jquerymobilerouter: "libs/jquery.mobile.router.min" }, // configure dependencies and export value aliases for old-school js scripts shim: { jquery: ["require"], underscore: { deps: ["jquery"], exports: "_" }, backbone: { deps: ["underscore", "jquery"], exports: "Backbone" }, jquerymobilerouter: ["jquery", "backbone", "underscore"], jquerymobile: ["jquery", "jquerymobilerouter", "backbone", "underscore"] } }); require(["jquery", "backbone", "underscore", "app/app.min", "jquerymobilerouter", "jquerymobile"], function ($, Backbone, _, App) { console.log($); console.log(Backbone); console.log(_); $("body").fadeIn(function () { App.init(); }); }); ``` If I understand correctly, the `paths` config option allows you to reference scripts, a-la the `<script>` tag within HTML. Assuming this is the case, do I still need to alias scripts like jQuery with a `$` or underscore with a `_` in my actual require statement below? It seems strange that I'd have to, given that if you reference jQuery with a standard `<script>` tag, `$` can be used throughout your script automatically. Shouldn't it be the same using the `paths`? I'm new to the `shim` config option, which I understand has replaced the deprecated `order!` plugin. What does the `exports` property actually DO? It doesn't seem to create an alias for a script; for example, if I set the `exports` for underscore to `"whatever"`, and then try to `console.log(whatever)`, it's undefined. So what's the point? How would scripts like jQuery be properly used "globally?" That is, what's the proper way to be able to use the `$` alias within my App.js module, or any other module in my "app" folder? Do I have to require jQuery within every individual module and alias `$` every single time? Or is the way I've done it here the proper way? I'd greatly appreciate any other criticisms of this particular script as well; the documentation for Require.js, in my opinion, leaves much to be desired; things I'd really like to know more about seem to get glossed over and leave me scratching my head.

Original source