Skip to content

Instantly share code, notes, and snippets.

@jjt
Created August 9, 2012 18:36
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jjt/3306911 to your computer and use it in GitHub Desktop.
Save jjt/3306911 to your computer and use it in GitHub Desktop.
RequireJS "global" dependencies

I'd like the ability to have single-instance, page-wide libraries like jQ/Zepto or Underscore/lodash available with their standard global vars ($, _) for every module to use without having to explicitly type in their deps in every define call (see not-so-dry.js).

How I handle this currently is by using separate script tags for the global libs before the tag for RequireJS, leaving them out of the RequireJS system entirely. While this solution works, it adds sync loading/execution requirements handled by the order of the markup.

While some modules wouldn't need DOM methods, thus not having jQ/Zepto/etc as a dep, I don't see much benefit to my web app(s) being able to load those modules first, then jQ/Zepto/etc, then the view/template modules that do the on-screen work.

What about if I were to define the non-AMD version of these libs in a shim block (AFAIK, that should still "pollute" the global namespace), and then reference them as deps in the main require block? Would that ensure that these libs would be loaded and executed before the other modules? See shim-main.js.

// Not so DRY:
// module_1.js
define(["underscore", "zepto", "momentjs",...], function(_, $, Moment, ... ) {
// ...
});
// module_2.js
define(["underscore", "zepto", "momentjs",...], function(_, $, Moment, ... ) {
// ...
});
// module_3.js
define(["underscore", "zepto", "momentjs",...], function(_, $, Moment, ... ) {
// ...
});
// Called with <script data-main="config.js"...>
// config.js
require.config({
deps: ["main"],
shim: {
zepto: {
exports: "$"
},
underscore: {
exports: "_"
}
});
// main.js
require(["zepto","underscore"], function() {
// ...
});
@jrburke
Copy link

jrburke commented Aug 9, 2012

I would probably have the config.js do the common lib loading, and then load "main" which would load your app modules after that, and not use deps:

// Called with <script data-main="config.js"...>
// config.js
require.config({
  shim: {
    zepto: {
      exports: "$"
    },

    underscore: {
      exports: "_"
    }
});

// load common things first
require(["zepto","underscore"], function() {
  //Now load main and its modules that have
  //implicit dependencies on the common things.
  require(["main"]);
});

Note though if all your modules need access to jquery, backbone and zepto to do their job, then the module responsibility may be too large. It also means it is harder to reuse those modules in another project without knowing of these implicit dependencies and loading them first.

All that said though, the above approach is perfectly fine to use.

@jjt
Copy link
Author

jjt commented Aug 9, 2012

Agreed on sprawling module responsibility. At worst though, modules should be able to tolerate _ and $ being in the global scope.

Thanks!

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