Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RequireJS 'Mismatched anonymous define() module' #238

Closed
Razinsky opened this issue Aug 13, 2014 · 10 comments
Closed

RequireJS 'Mismatched anonymous define() module' #238

Razinsky opened this issue Aug 13, 2014 · 10 comments

Comments

@Razinsky
Copy link

Hi @julianshapiro, awesome work on Velocity.js!
I got this error:

Mismatched anonymous define() module

while trying to include Velocity into my compiled r.js (using grunt-contrib-requirejs). After looking for issue #232 I made some tests to find out that I needed to describe the module name in the define call. So instead of


if (window.Velocity) {
define(factory);
} else {
define(["jquery"], factory)
}
I would have to add 'Velocity' to make it work on my side once compiled:

if (window.Velocity) {
    define('Velocity', factory);
} else {
    define(["jquery"], factory)
}
@LukeChannings
Copy link

Hi @julianshapiro,

Please can you reopen this issue? There is a problem with this implementation for a few reasons:

  1. The module can only ever be required as "velocity", even if you map {"*":{"foo/yourname": "velocity"}} and excludeShallow velocity, that will only result in an error.
  2. The module should only be named when it's included with other AMD definitions and loaded via a <script> tag directly. That's true in @Razinsky's case, and he's also requiring it as "velocity", which it why it works for him.
  3. The module can only be loaded via requirejs loading mechanism if the define call is anonymous, which it isn't. This means that in a development environment where everything isn't run through r.js all of the time Velocity will not load.

The issue that I believe @Razinsky was having is that the r.js optimiser will skip naming modules if there is more than one define call. The case with Velocity is that there are two, one with the jquery dependency and one without. If there was only one define, e.g. define(['jquery', factory]) then r.js would transform it to define('whateveryoucalledit', ['jquery', factory]).

The solution I propose is to remove the shim option and have a separate build file with that define call, and also remove the name from the define call. This means that the number of define calls will be reduced to one, which will fix the issue.

Also see requirejs/r.js#716 for the issue I've raised on r.js with multiple define calls.

@julianshapiro
Copy link
Owner

Hey @TheFuzzball,

Urgent request, if I may:

Can you change the shimmed Velocity loading code to this:

    /* CommonJS module. */
    if (typeof module === "object" && typeof module.exports === "object") {
        module.exports = factory(window.Velocity ? window.jQuery : require("jquery"));
    /* AMD module. */
    } else if (typeof define === "function" && define.amd) {
        define(window.Velocity ? factory : [ "jquery" ], window.Velocity ? undefined : factory);
    /* Browser globals. */
    } else {        
        factory(window.jQuery);
    }

And tell me if that fixes everything?

@LukeChannings
Copy link

Hi Julian,

That was the first thing that I tried, unfortunately any dynamism isn't going to work here.

r.js parses each file for define calls, which define both the module and the dependencies of that module. It then builds up a single file with all of your code using the names of these modules also ensuring the dependencies that they have declared are also in the file.

The problem is that r.js is evaluating the define call, and if it hits anything other than ArrayExpression followed by a FunctionExpression, or just a FunctionExpression, otherwise it won't match the call. r.js can't possibly evaluate the ConditionalExpression, because then it'd be different from the environment in which the call would actually be executed in. So what you're telling it is that your module both does and doesn't need jquery as a dependency.

I think this issue comes down to having optional dependencies in a single build, where clearly having two define calls implies that there should be two variants of this module.

I suggest working with a build tool to generate distribution files, one variant that isn't dependent on jquery (and has a bundled shim), and another that is. That's the cleanest solution that I can see.

@julianshapiro
Copy link
Owner

I was hoping that wasn't the case.

On a side note, I dislike changing my code for the behavior of one optimizer. But I presume rjs is fairly popular.

I only want one build of Velocity.

I'm cool with changing my build process, though, such that I actually reposition the shim inside the module's IIFE. Stay tuned.

Thank you, as always.

@LukeChannings
Copy link

Okay,

I'll create a test build with the four options (w & w/o jQuery, built w/ r.js and unbuild),
we can fix this problem by having jQuery global (which it is in the latest build), and not declare the jquery dependency in the AMD definition, that allows us to decide to use the shim or not at runtime.

I'll create a pull request in a bit to fix this once and for all. You shouldn't have to change the way you structure your project for this.

@LukeChannings
Copy link

Hi Julian,

I've made a pull request for a change that allows those four (most common) RequireJS use cases.
I've also created a few example projects with the build/unbuild w/wo jQuery which can be found here.

I've also updated the documentation to be more accurate. If you need anything else from me -- the documentation will probably need fixing up, it's late here so there will probably be typos -- let me know.

Velocity with RequireJS

Velocity presently has two builds, jquery.velocity.js and velocity.js.

jquery.velocity.js depends on jquery, and velocity.js includes a shim so that it can run without jQuery in IE8+. If jQuery is present it will be used over the shim, however.

Both velocity builds can be used with requirejs and r.js simply by including it in your project and requiring it.

If you're using jquery.velocity.js, ensure that jQuery is also in your project (and that it is required before Velocity).

As is usual for jQuery plugins, jquery.velocity.js extends jQuery.fn, which means that you only have to require it once if you choose to use it like $(<<selector>>).velocity(<<velocity-options>>).

If you want to use the Velocity utility function in your jQuery project, simply require velocity as a dependency, and the value for that dependency will be the utility function. If you're not using jQuery then you will be using the utility function in all cases.

If you're using a custom build of jQuery, please ensure that the exports/global module is included in the build.

@julianshapiro
Copy link
Owner

When you say "and that it is required before Velocity" do you in fact mean "make sure jQuery is shimmed as a dependency in your requirejs configuration"? Because, as far as I'm aware, there's no way to require one library "before" another since requirejs loads scripts asynchronously.

@LukeChannings
Copy link

That is what I meant, but I didn't include it in my example. (Updated now.)

pajtai pushed a commit to grasshopper-cms/grasshopper-admin that referenced this issue Aug 26, 2014
…ub repo. Should update bower.json when the following tickets show progress: julianshapiro/velocity#264 julianshapiro/velocity#238
@julianshapiro
Copy link
Owner

I've done an overhaul of the module loading code and I've officially dropped the jquery.velocity.js file. Expect a push tomorrow.

@julianshapiro
Copy link
Owner

This should be fixed now. Please update to the latest version of Velocity and get back to me.

Rycochet pushed a commit that referenced this issue Aug 3, 2020
Fixes CommonJS module loading. Closes #232. Closes #238.

Allow animating with the raw utility function (Velocity) instead of its
property (Velocity.animate), e.g. $.Velocity(element, propertiesMap,
options);

Copy over _cacheValues option for the UI pack. Closes #239.

Reverts Velocity.mock to original (asynchronous) behavior. Closes #237.

Fixes IE7 error throwing in UI pack. Closes #246.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants