RequireJS load Wicket library

615 Views Asked by At

I am using the library Wicket for map stuff. If I reference it as the script tag as normal, It works fine. Working link as below.

https://arthur-e.github.io/Wicket/sandbox-gmaps3.html

The problem comes when our project using RequireJS for module loader.

This is the following code that I tried.

require.config({    
    waitSeconds: 200,
    paths: {
        'wicket': '/Vendor/Wicket/wicket',
        'wicketGmap3': '/Vendor/Wicket/wicket-gmap3'
    },
    shim: {
        wicket: {
            exports: 'Wkt'
        },
        wicketGmap3: {            
            deps: ['wicket']
        }          
    },
});
require(['wicket', 'wicketGmap3'],(Wkt) => {
    $(() => {
        angular.bootstrap(document, ['app']);
    });
});

The error is still as below.

Uncaught ReferenceError: Wkt is not defined at wicket-gmap3.js:744

Has anyone experienced the same?

1

There are 1 best solutions below

0
On BEST ANSWER

The wicket.js file has a call to define. So setting a shim for it is useless, because shim is meaningful only for non-AMD "modules" (i.e. files that are not really modules but which we want to behave as if they were). AMD modules call define.

On the other hand wicket-gmap3.js is not an AMD-module. So you do need the shim for it. However, it depends on Wkt being present in the global space. The logic in wicket.js is such that when it calls define it does not set Wkt in the global space. (Which is the correct behavior for well-behaved AMD modules.) You need to perform the leakage yourself.

Change your config to:

define("wicket-glue", ["wicket"], function (wicket) {
    Wkt = wicket; // Deliberately leak into the global space.
    return wicket;
});

require.config({    
    waitSeconds: 200,
    paths: {
        'wicket': '/Vendor/Wicket/wicket',
        'wicketGmap3': '/Vendor/Wicket/wicket-gmap3'
    },
    map: {
        '*': {
            wicket: 'wicket-glue',
        },
        'wicket-glue': {
            wicket: 'wicket'
        }
    }
    shim: {
        wicketGmap3: {            
            deps: ['wicket']
        }          
    },
});

I've added a new module named wicket-glue. I often place such modules together with the configuration so that they don't require an additional data fetch. You could just as well put it in a separate file if you want. (If I did that, I'd remove the first argument to define though and name the file wicket-glue.js so that RequireJS takes the module name from the file name.)

I've also added a map which essentially says "in all modules, when the module wicket is required, load wicket-glue instead, but in wicket-glue when wicket is required, load wicket".

The net effect is that whenever wicket is required, Wkt will be leaked to the global space and wicket-glue should work fine.