Current status of ESRI and require.js?

1390
2
04-19-2018 05:29 PM
comScoreMovies
New Contributor

I've been assigned to add some mapping functionality to a mid size Durandal application which uses require.js as its module loader.  I've been unsuccessfully tinkering around with building a sample app.

The most recent require.js threads here are all three years old or more, so I'm wondering what the current status is.  https://community.esri.com/thread/102952 looked to me to be the last big conversation on the topic.

I have also had a look at Tom Wayson's recent post on esri-loader.  Durandal doesn't use node, so I can't directly use that, but I took a try at cleaning up the esri-loader.js file out of the dist/umd directory.  However this did not work for a couple of reasons.  First, esri-loader.js uses window['require'], which in my case is require.js.  Second, I had hoped to persuade require.js to load the built Dojo module off of /4.6/dojo/dojo, however this failed (stackoverflow tells me that require.js can load dojo from source, but not a built module).  If it had worked, I might have saved it off in window['dojo'] or something of that nature.

I'm unsure of what my next move ought to be.  Any suggestions?

Tags (1)
0 Kudos
2 Replies
ReneRubalcava
Frequent Contributor II

We've tried our best to continue support for RequireJS as an alternative AMD loader with the API.

You can still get pretty close with 3x, take a look at this sample app.

jsapi-resources/3.x/bower/requirejs at master · Esri/jsapi-resources · GitHub 

There's a lot of trickery in there when trying to use the r.js optimizer to build the app. There are lots of modules you need to ignore for various reasons

...
paths: {
  "moment/templates": "empty:",
  "dgrid": "empty:",
  "xstyle": "empty:",
  "esri/moment": "empty:",
  "esri/layers/GraphicsLayer": "empty:",
  "dgrid1/demos": "empty:",
  "dojo/query": "empty:", // becasue css selector engine is dynamically loaded
  "dojox/gfx": "empty:", // because this dynamically loads a renderer
  "dojo/i18n": "i18n/i18n", // only needed to get build working
  "dojo/text": "text/text",
  "dojo/domReady": "domReady/domReady"
}
...‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

But I think you can get a 3x r.js optimizer build with a couple dozen files.

Main issue is loader plugins, not just some of the common ones like dojo/i18n!, but some internal to Dojo that don't work with the r.js optimizer.

I've done numerous testing with 4x and the number of modules that needs to be ignored is almost not worth it, I think I'm ready to say that the r.js optimizer can't build 4x.

But, that doesn't mean you can't use the RequireJS AMD loader to load the modules without building.

That does work and we actually helped someone at the recent Developer Summit do just that for an application they had. You can use the github repo of the API, point RequireJS config settings to the location of the API and that should work.

GitHub - Esri/arcgis-js-api at 4master 

You can get an idea of the packages, paths, and maps by looking at the build profile for Dojo in this sample app.

jsapi-resources/build.profile.js at master · Esri/jsapi-resources · GitHub 

That should get you pretty close to loading 4x with RequireJS, I just wouldn't recommend trying to use the r.js optimizer.

Thanks!

RyanWever
New Contributor II

I am also in your situation and ended up including the entirety of the necessary JS API modules in my project. It's an awful solution. But it does work.

In case that is also feasible for other people, here is the relevant section of my RequireJS config:

requirejs.config({
    paths: {
        //arcgis libraries
        'esri': '../Scripts/arcgis/esri',
        'dojo': '../Scripts/arcgis/dojo',
        'dojox': '../Scripts/arcgis/dojox',
        'dijit': '../Scripts/arcgis/dijit',
        'gismoment': '../Scripts/arcgis/moment',
        'domReady': '../Scripts/arcgis/dojo/domReady'
    },
    map: {
        //make all modules requiring moment use vanilla moment
        '*': {
            'moment': 'moment'
        },
        //except ArcGIS modules must use special version of moment for whatever reason
        'esri': {
            'moment': 'gismoment'
        },
        'dojo': {
            'moment': 'gismoment'
        },
        'dojox': {
            'moment': 'gismoment'
        },
        'dijit': {
            'moment': 'gismoment'
        }
    }
});
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Like Rene Rubalcava says, this only works with 3.x version of the library.

I am currently in the process of trying to see if I can use a CDN version of the library, but it looks like RequireJS doesn't allow the mapping of URLs for directories (i.e., your CDN reference must point to an actual file, NOT a directory). So I am stuck with a massive Scripts library!

0 Kudos