Search code examples
javascriptdojorequirejsamdarcgis-js-api

Fixing Dojo's and JQuery dependant libraries multipleDefine conflict via Javascript


This question has been answered many times before, and I know one solution is to simply change it so (Esri's)dojo is the last one to load.

Problem is I'm working on a modular widget that has no access to the page's html to change the order, I must only load libraries via Dojo's AMD Loader.

Folder structure :

/Widget
--/Main.js
--/Datatable.js

This is the Main.js file:

define([
  './Datatable', 
  'https://code.jquery.com/jquery-3.3.1.min.js',
  'https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.bundle.js',
  ],
function(Datatable){ ... }

And Datatable.js (just another module I created for organization) :

define([
    'https://cdn.datatables.net/v/bs4/dt-1.10.18/r-2.2.2/datatables.min.js'
    ],function(){ ... }

I have two major issues here;

1) The AMD Loader is asynchronous and doesn't resolve non-AMD modules dependencies, meaning that order should be important

datatables.min.js requires bootstrap.bundle.js that requires jquery-3.3.1.min.js

So, If I'm lucky the request will load in order depending on latency, not very reliable...

2) Both Bootstrap and Datatable generic javascript files raise a "multipleDefine" error, probably due to them trying to define "jquery", I'm really not sure how to fix this (having a local edited copy of them wouldn't be ideal)

How can I resolve these 2 problems?


Solution

  • For the order, you can probably do something like :

    require(['https://code.jquery.com/jquery-3.3.1.min.js'], function() {
        require(['https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.bundle.js'], function() {
            define(['./Datatable'], function(Datatable){ ... }
        });
    });
    

    Which will force the resolution in a certain order.
    The multipleDefine error is raised when 2 components are trying to create a function define on the global scope (here, the window).
    It's pretty hard to give a perfect answer on that one.
    If you can setup a fiddle or something similar, I could have a deeper look.
    One thing that comes to my mind : You could try to delete window.define right before loading one of the file that throw the error... But that's ugly and might not even work...