"require.js:166 Uncaught Error: Mismatched anonymous define() module" trying to load 3rd party JS module

"require.js:166 Uncaught Error: Mismatched anonymous define() module" trying to load 3rd party JS module

by Mark Webster -
Number of replies: 8

 Moodle 2.9 (moving to 3 not an option I'm afraid), I'm trying to load a 3rd party javascript module via AMD and it's giving me the error:

require.js:166 Uncaught Error: Mismatched anonymous define() module

I'm getting this before I even try to use it, just having it in the theme amd folder is causing it (it still happen if I try to make use of it, too).

The module in question is masonry (http://masonry.desandro.com/) and it supports loading via requirejs (supposedly). The module definition is as follows:

( function( window, factory ) {
  // universal module definition
  /* jshint strict: false */ /*globals define, module, require */
  if ( typeof define == 'function' && define.amd ) {
    // AMD
    define( [
        'outlayer/outlayer',
        'get-size/get-size'
      ],
      factory );
  } else if ( typeof module == 'object' && module.exports ) {
    // CommonJS
    module.exports = factory(
      require('outlayer'),
      require('get-size')
    );
  } else {
    // browser global
    window.Masonry = factory(
      window.Outlayer,
      window.getSize
    );
  }

}( window, function factory( Outlayer, getSize ) {
  // module code
}

Loading it manually via the theme config.php javascripts array seems to work, but I'd like to make use of the AMD loader if possible. Any ideas?

Average of ratings: -
In reply to Mark Webster

Re: "require.js:166 Uncaught Error: Mismatched anonymous define() module" trying to load 3rd party JS module

by Justin Hunt -
Picture of Particularly helpful Moodlers Picture of Plugin developers

You are fortunate because the module that you seek to load is AMD ready. 

Just load it using the AMD apis . See here. https://docs.moodle.org/dev/Javascript_Modules

I have loaded masonry in Moodle with AMD so I can confirm that it works.




In reply to Justin Hunt

Re: "require.js:166 Uncaught Error: Mismatched anonymous define() module" trying to load 3rd party JS module

by Mark Webster -

Trying to load it via AMD is what's giving me the error...

In reply to Mark Webster

Re: "require.js:166 Uncaught Error: Mismatched anonymous define() module" trying to load 3rd party JS module

by Justin Hunt -
Picture of Particularly helpful Moodlers Picture of Plugin developers

 Without seeing your code, its hard to help. FWIW as you know, you need to

  1. write an amd module for masonry and put it in your plugins amd/src folder(see below)
  2. compile that using grunt.  i.e.
    cd /var/www/mymoodle/mod/myplugin/amd
    grunt
  3. call it from within your module. Maybe like this ....
    $PAGE>requires->js_call_amd('myplugin/moodlemasonry','init');


Your moodlemasonry AMD module might look like this. But I never ran this particular code, it just might help you , thats all

define(['jquery','https://cdnjs.cloudflare.com/ajax/libs/masonry/4.0.0/masonry.pkgd.js'], function($,masonry){ 
 return {
  init: function(opts){var elem = document.querySelector('.grid');
      var msnry = new masonry( elem, {
       itemSelector: '.grid-item',
       columnWidth: 200
      }); 
    };
  } 
});


In reply to Justin Hunt

Re: "require.js:166 Uncaught Error: Mismatched anonymous define() module" trying to load 3rd party JS module

by Amy Groshek -
@Mark running into the same thing here with Masonry. If I load from the CDN, as per Justin's example, I have no problem. If I load from the AMD module, or **if I even place a minified file in my plugin's amd/build without calling it in my AMD define call, I get the same error. Works a charm from the CDN.
In reply to Amy Groshek

Re: "require.js:166 Uncaught Error: Mismatched anonymous define() module" trying to load 3rd party JS module

by Amy Groshek -

Have also found that AMD does not throw the anonymous define call if I construct a URL to the additional JS library outside of the plugin's amd/build directory. For example:

M.local_rlsiteadmin = M.local_rlsiteadmin || {};
M.local_rlsiteadmin = {
    masonryjs: ''
};
if (M.cfg) {
    M.local_rlsiteadmin.masonryjs = M.cfg.wwwroot + '/local/rlsiteadmin/js/masonry.pkgd.min.js';
}
define(['jquery', 'core/yui', M.local_rlsiteadmin.masonryjs], function ($, Y, Masonry) {

    return /** @alias module:local_rlsiteadmin/dashboard */ {
        /**
         * init dashboard
         * @access public
         */
        init: function() {
        // etc... 

Though this solution does make me sad because this is the kind of thing I thought we would be able to avoid with AMD.

In reply to Amy Groshek

Re: "require.js:166 Uncaught Error: Mismatched anonymous define() module" trying to load 3rd party JS module

by Justin Hunt -
Picture of Particularly helpful Moodlers Picture of Plugin developers

I am pretty sure that you don't need to do it this way, which I agree is a sad way. 

The example I posted was from a Generico template I write for Masonry , and I use CDNs a lot for those, because I can just share the template around with other people/sites and it will work. 

Can you post a minimal version of your code that doesn't work, written without CDNs or URLs? Maybe I can see what is going wrong.

In reply to Justin Hunt

Re: "require.js:166 Uncaught Error: Mismatched anonymous define() module" trying to load 3rd party JS module

by Amy Groshek -

Basically, it doesn't work to implement as documented:

define(['core/yui', 'local_pluginname/masonryfile'], function (Y, Masonry) {

    return /** @alias module:local_pluginname/dashboard */ {
        /**
         * init dashboard
         * @access public
         */
        init: function() {
        // etc... 

You can load the file from a CDN, or else where in the plugin dir, but as soon as you treat it like the documentation says you should treat it, you get "Anonymous define" error.

The error is thrown as soon as the external library is loaded. Nothing within the plugin's AMD module even executes. Clearly Moodle's AMD implementation is choking on the format of the define in the external lib. In fact, if I remove every single define from the Mosaic JS file, the error goes away (but of course the library is broken).

I've run into this Anonymous define call error before, and in that case the solution was to get a more up-to-date version of the plugin that was AMD-compatible. But Mosaic clearly has a define in it and supports requirejs.

In reply to Amy Groshek

Re: "require.js:166 Uncaught Error: Mismatched anonymous define() module" trying to load 3rd party JS module

by Justin Hunt -
Picture of Particularly helpful Moodlers Picture of Plugin developers

I did try this. 

It seems to load without the Anonymous define errors you reported, but Masonry would never work. I usually get an error that Masonry is not a constructor.

But if I use the exact same code with the CDN url instead, it works. So its sad. FWIW my code looks like this:

define(['jquery','core/log','filter_poodll/masonry.pkgd'], function($, log, Masonry) {
    "use strict"; // jshint ;_;
    log.debug('Masonry: initialising');
    return {
    init: function(){
var elem = document.querySelector('.grid');
var msnry = new Masonry( elem, {
 // options
 itemSelector: '.grid-item',
 columnWidth: 200
});
    }//end of init
    }//end of returned object
});//total end