hanfeisun hanfeisun - 7 months ago 35
Javascript Question

Why does this cause "Mismatched anonymous define()" in requireJS?

I'm using a module called classie.js, whose codes can be viewed below:

/*!
* classie - class helper functions
* from bonzo https://github.com/ded/bonzo
*
* classie.has( elem, 'my-class' ) -> true/false
* classie.add( elem, 'my-new-class' )
* classie.remove( elem, 'my-unwanted-class' )
* classie.toggle( elem, 'my-class' )
*/

/*jshint browser: true, strict: true, undef: true */
/*global define: false */

( function( window ) {

'use strict';

// class helper functions from bonzo https://github.com/ded/bonzo

function classReg( className ) {
return new RegExp("(^|\\s+)" + className + "(\\s+|$)");
}

// classList support for class management
// altho to be fair, the api sucks because it won't accept multiple classes at once
var hasClass, addClass, removeClass;

if ( 'classList' in document.documentElement ) {
hasClass = function( elem, c ) {
return elem.classList.contains( c );
};
addClass = function( elem, c ) {
elem.classList.add( c );
};
removeClass = function( elem, c ) {
elem.classList.remove( c );
};
}
else {
hasClass = function( elem, c ) {
return classReg( c ).test( elem.className );
};
addClass = function( elem, c ) {
if ( !hasClass( elem, c ) ) {
elem.className = elem.className + ' ' + c;
}
};
removeClass = function( elem, c ) {
elem.className = elem.className.replace( classReg( c ), ' ' );
};
}

function toggleClass( elem, c ) {
var fn = hasClass( elem, c ) ? removeClass : addClass;
fn( elem, c );
}

var classie = {
// full names
hasClass: hasClass,
addClass: addClass,
removeClass: removeClass,
toggleClass: toggleClass,
// short names
has: hasClass,
add: addClass,
remove: removeClass,
toggle: toggleClass
};

//transport
if ( typeof define === 'function' && define.amd ) {
// AMD
define( classie );
} else {
//browser global
window.classie = classie;
}

})( window );


And I wrote this in HTML:

<script data-main="js/main.js" src="bower_components/requirejs/require.js"></script>
<script src="js/classie.js"></script>


Then the browser complains:

[Error] Error: Mismatched anonymous define() module: [object Object]
http://requirejs.org/docs/errors.html#mismatch
defaultOnError (require.js, line 141)
onError (require.js, line 545)
intakeDefines (require.js, line 1229)
(anonymous function) (require.js, line 1416)


What seems weird to me is the last lines in classie.js:

//transport
if ( typeof define === 'function' && define.amd ) {
// AMD
define( classie );
} else {
//browser global
window.classie = classie;
}


It looks like
classie.js
tries its best to keep compatible with
AMD
because it test whether
define
is a function and has
amd
attribute before using it. But unfortunately this caused an error in the browser. Shouldn't
requirejs
the most famous library that implements AMD? Why doesn't it work?

Answer

As you discovered, classie is designed to be loaded with an AMD loader. So when you load it, it detect that an AMD loader is present and calls define.

The problem is that you are trying to load it with a script element. AMD modules must be loaded through their loader, not directly through script. This is why you are getting the error message you are getting.