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()" error after r.js optmization #589

Closed
adambiggs opened this issue Jun 27, 2016 · 7 comments
Closed

Comments

@adambiggs
Copy link

adambiggs commented Jun 27, 2016

The change introduced by #580 seems to have broke this plugin when used with the RequireJS r.js optimizer.

Prior to this change, r.js was able to parse the UMD wrapper correctly and give the anonymous module a name in the optimized file:

(function (factory) {
    if (typeof define === "function" && define.amd) {
        define('bootstrap-slider',["jquery"], factory);
    } else if ((typeof module === "undefined" ? "undefined" : _typeof(module)) === "object" && module.exports) {
    // ...
})

But after #580 was merged, the r.js optimizer doesn't give the module a name, causing Error: Mismatched anonymous define() errors:

(function (factory) {
    if (typeof define === "function" && define.amd) {
        try {
            define(["jquery"], factory);
        } catch (err) {
            define([], factory);
        }
    } else if ((typeof module === "undefined" ? "undefined" : _typeof(module)) === "object" && module.exports) {
    // ...
})

The issue seems to be cause by wrapping the define() call in a try ... catch. I confirmed this by installing the latest version (v7.1.1), manually removing the try/catch statement, and then running the result through the r.js optimizer.

The optimizer was then able to parse the UMD wrapper correctly again and give the anonymous module a name:

(function (factory) {
    if (typeof define === "function" && define.amd) {
        define('bootstrap-slider',["jquery"], factory);
    } else if ((typeof module === "undefined" ? "undefined" : _typeof(module)) === "object" && module.exports) {
    // ...
})

My suggestion would be to revert the #580 changes so that this module conforms to standard UMD.

I don't have any experience with Webpack, but I'm assuming the correct way to deal with #578 would be to use something like resolve.alias to define jquery as a stub module.

Another option might be to split this library into two modules - a "core" module without any dependencies, and a "jquery plugin" module that depends on the core module and jquery.

@rovolution
Copy link
Collaborator

we would greatly welcome a PR around this that accommodates all major build systems/module types

@rovolution
Copy link
Collaborator

rovolution commented Jun 29, 2016

My suggestion would be to revert the #580 changes so that this module conforms to standard UMD.

I have not used AMD in ages, but do you know of a way (if any) to declare optional dependencies with AMD @adambiggs?

My initial hunch is to follow the first answer in this Stackoverflow post and define that optional fallback module within the if (typeof define === "function" && define.amd) block. its kind of hacky but it could prove to be a workable solution

Another option might be to split this library into two modules - a "core" module without any dependencies, and a "jquery plugin" module that depends on the core module and jquery.

This is probably the best solution long-term but requires a lot of work.

@rovolution
Copy link
Collaborator

rovolution commented Jul 12, 2016

@adambiggs after talking some time to further understand this issue, I agree with your comment:

My suggestion would be to revert the #580 changes so that this module conforms to standard UMD.

I don't have any experience with Webpack, but I'm assuming the correct way to deal with #578 would be to use something like resolve.alias to define jquery as a stub module.

I will make the PR that reverts this and adds a section to our README for stubbing out jquery for webpack apps where it is not an explicit dependency.

@TomiS after I revert the PR, you will have to go into the Webpack config file for your specific project and add something like the following to your resolve.alias section:

resolve: {
    alias: {
         "jquery": path.join(__dirname, "./jquery-stub.js");
    }
}

Then in your project, you will have to create a module that exports a null value. Whenever require("jquery") is mentioned in your project, it will load this stubbed module.

// Path: ./jquery-stub.js
module.exports = null;

Your Webpack build should work fine (just verified this on a sample project). I will publish this as a major bump so that it is explicit that it is a breaking change

@adambiggs
Copy link
Author

@rovolution sorry for the slow response, I've been on vacation. Sounds like a good plan. Nice of you to test out the Webpack config for @TomiS too. Cheers!

@rovolution rovolution mentioned this issue Jul 13, 2016
3 tasks
@rovolution
Copy link
Collaborator

will be published to 8.0.0

@adambiggs
Copy link
Author

Thanks @rovolution, the latest v9.0.0 now compiles without any issues using r.js 👍.

@TomiS
Copy link
Contributor

TomiS commented Jul 14, 2016

Nice to see a better solution for this. Works for our Webpack config too as expected. Thanks @rovolution and @adambiggs

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