Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to tell if a javascript library supports AMD

Tags:

javascript

amd

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".

like image 580
Stig Perez Avatar asked Nov 24 '13 22:11

Stig Perez


People also ask

Can I use CommonJS with AMD?

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.

What is the AMD format in jQuery?

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.

Should I use AMD modules for web development?

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.

What is AMD?

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?


2 Answers

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.

like image 61
Joseph Avatar answered Oct 01 '22 16:10

Joseph


You'll be looking for AMD format define() calls in the sources, where they usually come in three flavors:

  • No AMD module defined, where you'll have to configure a shim in RequireJS;
  • Optional AMD support, where there's usually some sniffing going on for the define() dependency in the globals at the bottom;
  • First-class AMD module, where everything is wrapped in a call to 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.

like image 20
Filip Dupanović Avatar answered Oct 01 '22 16:10

Filip Dupanović