When integrate a javascript libary,i met error:Uncaught Error: Mismatched anonymous define() module: function()

dear everyone:
forgive my poor english,pls.
i want to develope some extensions,but when i integreate some javalibrary,i met error:
Uncaught Error: Mismatched anonymous define() module: function()
following is my steps:
1.follow the instructions on https://www.xwiki.org/xwiki/bin/view/Documentation/DevGuide/FrontendResources/IntegratingJavaScriptLibraries/
2. create a panel ,then code as below(i add some spaces in “script”,pls ignore):

{{velocity}}
{{html}}
< s c ript src="//cdnjs.cloudflare.com/ajax/libs/viewerjs/1.3.0/viewer.min.js"
type=“text/javascript”></s c r ip t>
{{/html}}
{{/velocity}}

i tried the first 4 ways on this page https://www.xwiki.org/xwiki/bin/view/Documentation/DevGuide/FrontendResources/IntegratingJavaScriptLibraries/,all get this error

so ,how can i fix this problem

this is due to de configuration of require.js
i should use its shim option to integreate js modules

I’m hitting this trying to integrate Frappe Gantt lib: Open Source Javascript Gantt (which depends on momentjs and snapsvg).

Can you share how you solved it?

@watery can you share the code that you tried and that didn’t work? And what version of XWiki are you using? What JavaScript error are you getting exactly?

Sure:

require(['jquery'], function ($) {
    $.getScript("https://frappe.io/gantt/js/moment.min.js")
        .done((data, textStatus) => {
            $.getScript("https://frappe.io/gantt/js/snap.svg-min.js")
                .done((data, textStatus) => {
                    console.log(data); // Data returned
                    console.log(textStatus); // Success

                    $.getScript("https://frappe.io/gantt/js/frappe-gantt.min.js")
                        .done((data, textStatus) => {
                            console.log(data); // Data returned
                            console.log(textStatus); // Success

                            console.log('Snap object: ', typeof Snap)
                            console.log('Ganttobject: ', typeof Gantt)
                        })
                        .fail(() => { alert('No frappe') })
                })
                .fail(() => { alert('No snap') })
        })
        .fail(() => { alert('No moment') })
});

Consider that these are just quick experiments to see whether a library fits well (like I did with others, like in Is there a timeline macro / plugin or similar? - #5 by watery), I didn’t read much about properly develop extensions, just the bare minimum (or maybe less than that :sweat_smile:)

14.6

This is the console output (Firefox):

JQMIGRATE: Migrate is installed with logging active, version 3.3.2 jquery-migrate.min.js:2:709
Uncaught Error: Mismatched anonymous define() module: function(){"use strict";function a(){return md.apply(null,arguments)}
// This is done to register the method called with moment()
// without creating circular dependencies.
function b(a){md=a}function c(a){return a instanceof Array||"[object Array]"===Object.prototype.toString.call(a)}function d(a){
// IE8 will treat undefined and null as object if it wasn't for
// input != null
return null!=a&&"[object Object]"===Object.prototype.toString.call(a)}function e(a){var b;for(b in a)
// even if its not own property I'd still call it non-empty
return!1;return!0}function f(a){return a instanceof Date||"[object Date]"===Object.prototype.toString.call(a)}function g(a,b){var c,d=[];for(c=0;c<a.length;++c)d.push(b(a[c],c));return d}function h(a,b){return Object.prototype.hasOwnProperty.call(a,b)}function i(a,b){for(var c in b)h(b,c)&&(a[c]=b[c]);return h(b,"toString")&&(a.toString=b.toString),h(b,"valueOf")&&(a.valueOf=b.valueOf),a}function j(a,b,c,d){return …
    makeError require.min.js:5
    T require.min.js:5
    s require.min.js:5
    [...]
    emit require.min.js:5
require.min.js:5:1795
console.trace() jquery-migrate.min.js:2:1010
    jQuery 2
    init bootstrap.min.js:6
    [...]
    enable require.min.js:5
    bind require.min.js:5
undefined WebHome:6:28
success WebHome:7:28
undefined WebHome:11:36
success WebHome:12:36
Snap object:  undefined WebHome:14:36
Ganttobject:  undefined WebHome:15:36
Uncaught Error: Mismatched anonymous define() module: function(c){return b(a,c)}
https://requirejs.org/docs/errors.html#mismatch
    makeError require.min.js:5
    T require.min.js:5
    [...]
    enable require.min.js:5
    init require.min.js:5
require.min.js:5:1795

I must say it doesn’t come out always the same, i.e. this is after two or three page refreshes, here some console.log() have been executed, it seems:

Spostato su http://<xwiki-host>/xwiki/bin/view/XWikiExperiments/Gantt/Frappe/
JQMIGRATE: Migrate is installed with logging active, version 3.3.2 jquery-migrate.min.js:2:709
console.trace() jquery-migrate.min.js:2:1010
    jQuery 7
    <anonima> http://<xwiki-host>/xwiki/webjars/wiki:xwiki/bootstrap/3.4.1/js/bootstrap.min.js?r=1:6
    <anonima> http://<xwiki-host>/xwiki/webjars/wiki:xwiki/bootstrap/3.4.1/js/bootstrap.min.js?r=1:6
console.trace() jquery-migrate.min.js:2:1010
    jQuery 2
    [...]
    bind require.min.js:5
Uncaught Error: Mismatched anonymous define() module: function(){"use strict";function a(){return md.apply(null,arguments)}
// This is done to register the method called with moment()
// without creating circular dependencies.
function b(a){md=a}function c(a){return a instanceof Array||"[object Array]"===Object.prototype.toString.call(a)}function d(a){
// IE8 will treat undefined and null as object if it wasn't for
// input != null
return null!=a&&"[object Object]"===Object.prototype.toString.call(a)}function e(a){var b;for(b in a)
// even if its not own property I'd still call it non-empty
return!1;return!0}function f(a){return a instanceof Date||"[object Date]"===Object.prototype.toString.call(a)}function g(a,b){var c,d=[];for(c=0;c<a.length;++c)d.push(b(a[c],c));return d}function h(a,b){return Object.prototype.hasOwnProperty.call(a,b)}function i(a,b){for(var c in b)h(b,c)&&(a[c]=b[c]);return h(b,"toString")&&(a.toString=b.toString),h(b,"valueOf")&&(a.valueOf=b.valueOf),a}function j(a,b,c,d){return …
    makeError http://<xwiki-host>/xwiki/webjars/wiki:xwiki/requirejs/2.3.6/require.min.js?r=1:5
    T http://<xwiki-host>/xwiki/webjars/wiki:xwiki/requirejs/2.3.6/require.min.js?r=1:5
    [...]
    <anonymous> http://<xwiki-host>/xwiki/webjars/wiki:xwiki/xwiki-platform-tree-webjar/14.6/require-config.min.js?evaluate=true:3
require.min.js:5:1795
undefined WebHome:6:28
success WebHome:7:28
Uncaught Error: Mismatched anonymous define() module: function(c){return b(a,c)}
https://requirejs.org/docs/errors.html#mismatch
    makeError http://<xwiki-host>/xwiki/webjars/wiki:xwiki/requirejs/2.3.6/require.min.js?r=1:5
    T http://<xwiki-host>/xwiki/webjars/wiki:xwiki/requirejs/2.3.6/require.min.js?r=1:5
    [...]
    <anonymous> http://<xwiki-host>/xwiki/webjars/wiki:xwiki/xwiki-platform-ckeditor-webjar/14.6/ckeditor.js:1600
require.min.js:5:1795
Uncaught TypeError: c is null
    setLang http://<xwiki-host>/xwiki/webjars/wiki:xwiki/xwiki-platform-ckeditor-webjar/14.6/ckeditor.js:255
    <anonymous> http://<xwiki-host>/xwiki/bin/jsx/CKEditor/Translations?language=en:9
    [...]
    <anonymous> http://<xwiki-host>/xwiki/bin/jsx/CKEditor/Translations?language=en:1
ckeditor.js:255:411
undefined WebHome:11:36
success WebHome:12:36
Snap object:  undefined WebHome:14:36
Ganttobject:  undefined WebHome:15:36

This worked for me:

require.config({
  paths: {
    'Gantt': 'https://frappe.io/gantt/js/frappe-gantt.min',
    'snap.svg': 'https://frappe.io/gantt/js/snap.svg-min'
  }
});

require(['moment', 'Gantt', 'snap.svg'], function(moment, Gantt, snap) {
  ...
});

When integrating an external JavaScript library in XWiki you should use RequireJS and thus you should check if that library supports RequireJS out of the box or not. In your case:

  • moment.js is already bundled in XWiki and you can simply ask for it
  • Gantt and snap.svg both support RequireJS (look for define( in their code) so you just have to tell RequireJS their paths

Hope this helps,
Marius

1 Like

Sorry, I must have missed the reply notification!

I’ll try your code as soon as possible, thanks.

Thank you for the clarifications. Knowing nothing about RequireJS and most of XWiki integrations surely doesIn’t help :laughing: given the little time I can dedicate to XWiki, I often try to inspect whether something can be integrated, before deciding to spend time on it.
Your help is very much appreciated.

Cool, that worked indeed.

Almost… unfortunately I’ve hit another roadblock.

This is the code I’ve entered:

require.config({
  paths: {
    'Gantt': 'https://frappe.io/gantt/js/frappe-gantt.min',
    'snap.svg': 'https://cdnjs.cloudflare.com/ajax/libs/snap.svg/0.5.1/snap.svg-min'
  }
});

require(['moment', 'Gantt', 'snap.svg'], function(moment, Gantt, snap) {
  var tasks = [
  {
	id: 'Task 1',
	name: 'Redesign website',
	start: '2016-12-28',
	end: '2016-12-31',
	progress: 20,
	dependencies: 'Task 2, Task 3'
  },
]
  console.log("Checking for moment lib: " + !!moment)
  console.log("Checking for Gantt lib: " + !!Gantt)
  console.log("Checking for snapsvg lib: " + !!snap)

  var gantt = new Gantt("#gantt", tasks);
});

This outputs:

Checking for moment lib: true
Checking for Gantt lib: true
Checking for snapsvg lib: true
Uncaught ReferenceError: moment is not defined
tasks frappe-gantt.min.js:1

in the console.

I tried with a url from CDN: https://cdnjs.cloudflare.com/ajax/libs/frappe-gantt/0.6.1/frappe-gantt.min

but got:

Checking for moment lib: true
Checking for Gantt lib: false
Checking for snapsvg lib: true 
Uncaught TypeError: a is not a constructor

but there’s no define() in this last file, it looks like there’s a difference between the libraries at the two urls.

This probably is an issue with the library itself: if that’s the case, is there any way to mix libraries loaded via RequireJS and added to the page with a <script /> tag?

The reason is because https://frappe.io/gantt/js/frappe-gantt.min.js defines a RequireJS module but it uses moment inside without declaring a dependency on moment. Basically it expects a global moment variable that is not defined when you load moment through RequireJS (one of the benefits of using AMD and RequireJS is to avoid polluting the global namespace). You cannot change the code of frappe-gantt.min.js so the hack is to set the expected global variable before calling the Gantt constructor.

window.moment = moment;
var gantt = new Gantt("#gantt", tasks);

This version https://cdnjs.cloudflare.com/ajax/libs/frappe-gantt/0.6.1/frappe-gantt.min.js doesn’t define a RequireJS module but it also doesn’t use moment inside. If you want to use this version then:

  • you don’t need moment
  • since it doesn’t use define you need to tell RequireJS what is the output (export) of this module
require.config({
  paths: {
    'Gantt': 'https://cdnjs.cloudflare.com/ajax/libs/frappe-gantt/0.6.1/frappe-gantt.min',
    'snap.svg': 'https://cdnjs.cloudflare.com/ajax/libs/snap.svg/0.5.1/snap.svg-min'
  },
  shim: {
    Gantt: {
      'exports': 'Gantt'
    }
  }
});

Hope this helps,
Marius

1 Like

Absolutely!

Thank you, I finally managed to get it to work:

immagine

Well, I believe you, though it kept spitting out that Uncaught ReferenceError: moment is not defined message, but thanks to your previous explanation, I copied the window.moment = moment line and this one worked too.

Thank you again, I now can move on to evaluate this library or maybe others, I’m sure I’ll have less trouble adding them to my pages now.

@mflorea I’m sorry to call you in again, but another library, another issue :sweat_smile:

XWiki 14.10.13

I’m trying DHTMLX gantt lib: https://www.npmjs.com/package/dhtmlx-gantt

The library code does have define's in it.

require.config({
  paths: {
    // 'dhtmlx-gantt': 'https://unpkg.com/dhtmlx-gantt@8.0.3/codebase/dhtmlxgantt'
    'dhtmlx-gantt': 'https://unpkg.com/dhtmlx-gantt@8.0.3/codebase/sources/dhtmlxgantt'
  }
});

require(['moment', 'dhtmlx-gantt'], function(moment, gantt) {

  console.log('moment: ', moment)
  console.log('gantt: ', gantt)
  
});

There are no errors, but I get (moment is there just to check the code runs as expected):

moment: function f()
gantt: undefined

I’ve tried two JS urls, and even the previous major version, but I got the same; I can see the library GET request is properly completed.

Any suggestion? Having no error code or anything else, I have no idea what to look for here :confused:

Hi,

I checked https://unpkg.com/dhtmlx-gantt@8.0.3/codebase/sources/dhtmlxgantt.js and I saw:

define("dhtmlxgantt", [], factory);

When the library you’re loading calls define with a module name you need to use the same module name in your require configuration.

require.config({
  paths: {
    'dhtmlxgantt': 'https://unpkg.com/dhtmlx-gantt@8.0.3/codebase/sources/dhtmlxgantt'
  }
});

Does this fix your problem?

1 Like

Yes!!

moment:  function f()
gantt:  Object { gantt: {…}, Gantt: {…}, default: {…}, … }

I’ll test it further, but I’m quite positive about it.
Thank you very much!