So I've started to learn how to use requirejs and combine it with some of the other javascript libraries available. As I understand it you need to shim all the libraries that are not Asynchronous module definition compatible (AMD), but apart from searching through the library code for "require" is there an easier way to figure out which libraries support AMD and which do not? As an example I know that jquery supports AMD but jqueryui does not, and I only know this because "someone told me".
The CommonJS modules that would not work in an AMD wrapper will also not work as a Harmony module. AMD's code execution behavior is more future compatible. One of the criticisms of AMD, at least compared to CJS modules, is that it requires a level of indent and a function wrapping.
define(['jquery'] , function ($) { return function () {}; }); The AMD format comes from wanting a module format that was better than today's "write a bunch of script tags with implicit dependencies that you have to manually order" and something that was easy to use directly in the browser.
Most web developers use a function wrapper anyway, to avoid polluting the page with globals. Seeing a function wrapped around functionality is a very common sight and does not add to the reading cost of a module. AMD modules require less tooling, there are fewer edge case issues, and better debugging support.
Why AMD? This page talks about the design forces and use of the Asynchronous Module Definition (AMD) API for JavaScript modules, the module API supported by RequireJS. There is a different page that talks about general approach to modules on the web. What are JavaScript modules? What is their purpose?
This is how jQuery declares its AMD. It's just a bunch of if statements. Unless libraries have some library.AMD === true
, there's no way to check from the library itself.
if ( typeof module === "object" && module && typeof module.exports === "object" ) {
module.exports = jQuery;
} else {
window.jQuery = window.$ = jQuery;
if ( typeof define === "function" && define.amd ) {
define( "jquery", [], function () { return jQuery; } );
}
}
However, there's a way to check already loaded modules. This answer states you can check require.s.contexts._.defined
, which is an object containing the names-definition mapping of already loaded modules.
For example, if I loaded jQuery (which by default has AMD) into the page that also has RequireJS, a jquery
property will exist in that object and contain the same jQuery object as the global. You can then compare. The following will return true
:
require.s.contexts._.defined.jquery === jQuery
require.s.contexts._.defined.jquery === $
However, this assumes that you know the module name and/or there's a global to compare against. This might not work in all cases. For example, jQuery UI isn't just one big piece of code. It's a bunch of plugins housed under a jquery-ui.js
. There's a possibility that either they could be named collectively or a module per widget. jQuery UI doesn't even have a global.
You'll be looking for AMD format define()
calls in the sources, where they usually come in three flavors:
define()
dependency in the globals at the bottom;define()
.It's good to note that you'll get an error if your trying to shim an AMD module by mistake, or load a script as an AMD module that never calls define()
to create one.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With