javascriptrequirejsamdalmond

Using shim config with almond


I am trying to shim certain modules for usage with almond like so:

<script>
requirejs.config({
  shim: {
    'jQuery': { exports: 'jQuery' },
  //etc.
</script>

as certain scripts will already be included. However, this code:

require(['jQuery', function($) {

});

results in "undefined missing jQuery". If I shim jQuery like this:

define('jQuery', function() {
  return jQuery;
});

it works.

I am not building my JS at all, just dropping almond.js into an existing web software so I can develop my new components with AMD. I would like to shim existing globals for my new modules.

I am guessing shims are only resolved on build and that the build does exactly what I am doing above, is that correct?


Solution

  • The name for jQuery is hard-coded to "jquery". If you deviate from this you'll run into trouble. But that's not your only problem.

    Using shim is not the same as calling define with a module name. When you use shim like you do in your question you tell the loader that there exist a module with the name jQuery and that once that module is loaded, RequireJS should return as a module value the value of the variable jQuery. The emphasized text is important: the loader will fetch and load a module named jQuery.

    The define you show in your question would usually be placed together with the call to require.config, either just before it or just after it. This declares a module named jQuery. Because the module is already there, when the loader needs to get this module, there is nothing to fetch. This is an important difference when it comes to Almond.

    Almond has restrictions, one of them is:

    optimize all the modules into one file -- no dynamic code loading.

    (Emphasis added.) Using the terms I've used in this answer this means "no fetching". When you use your define call, you are fine. When you use the shim, then unless you optimized your modules into one file, the loader has to try fetching the module. Almond cannot do that.