The new @arcgis/webpack-plugin and esri-loader

4113
0
05-10-2018 01:20 PM
TomWayson
Esri Contributor
2 0 4,113

This post is aimed at helping you decide when to use the new @arcgis/webpack-plugin or esri-loader in applications built with webpack. I've recently had the opportunity to put the new webpack plugin through it's paces, and I came away with the impression that Rene Rubalcava, Yann Cabon‌, and the team have taken an important step forward in making the ArcGIS API for JavaScript more interoperable with other JavaScript frameworks and build tools.

TLDR: Scroll down to see the Conclusion.

Rumors of esri-loader's demise have been greatly exaggerated

So you may be wondering why would you ever want to use esri-loader now that we have the plugin?

First, if you're not using at least v4.7 of the ArcGIS API for JavaScript, you can stop reading this and head right on over to the esri-loader documentation. It also goes without saying that if you're using another module bundler besides webpack (such as rollup.js or parcel) that the webpack plugin won't be able to help you and that you'll need esri-loader instead. If you're developing Ember.js applications, which use Broccoli.js instead of webpack, head on over to ember-esri-loader.

Functional parity? Very close...

Still here? Great! Before getting into the details, I should start by identifying the ArcGIS API + webpack scenarios for which there was previously no other workable solution besides esri-loader. These scenarios are listed from more common to more advanced:

  1. You do not have access to the weback configuration (i.e. you were using a framework's CLI tool)
  2. You want to lazy-load the ArcGIS API after the rest of the application was loaded and rendered
  3. You want to use the ArcGIS API in a server-side rendered (SSR) application

Handles the hard stuff well

I'm happy to report that the new webpack plugin handles the more advanced scenarios (lazy-loading and use in a SSR application) very well! For each of the plugin's two demo applications I was able to make a branch that demonstrates how to lazy-load the esri bundles using dynamic import(). Here are the relevant TypeScript and Babel commits. I also able to confirm that each of those branches had roughly the same initial load performance as their esri-loader equivalents. Importantly, using lazy-loading (with either the webpack plugin or esri-loader) resulted in a 4x decrease in the time it took to see anything other than a blank white screen. Stephen Sylvia‌ expanded on that idea by creating a lightning fast (loads on a mobile phone on 3G in under 2 seconds) prototype that uses placeholder images for maps until the user wants to interact with them. Finally, I riffed on his work and created a branch that uses server-side rendering to demonstrate how you could optimize such a site for SEO. It would be easy to add a commit to that branch that leverages sever-side rendered Open Graph meta tags for rich social media sharing.

Some work to be done

However, these are still early days for the webpack plugin, and there are a few kinks to be worked out so that you can just use it in any webpack project. Specifically, at a bare minimum you need to be able to add it to the webpack config's array of plugins. The CLIs are getting better these days about letting you have access to the webpack config, but worst case scenario you may need to "eject" from the CLI in order to do so. You may find that even once you are able to add the plugin to your webpack config, some of it's settings conflict with those of other plugins added by the CLI. I had this problem when trying to add the webpack plugin to a create-react-app application. I poked and prodded a bit, and was able to resolve certain issues, but others were beyond my webpack fu (which isn't saying much).

Coming soon...

All in all though, I am confident that these incompatibilities will be worked out soon, and we'll have functional parity between the webpack plugin and esri-loader. If you're using the ArcGIS API with angular-cli, vue-cli, create-react-app, etc I hope you'll jump into the fray and try to help us figure out how to resolve these types of issues.

So, which should I use?

Let's say you've rolled your own webpack config (rather than starting from a CLI) and you can use either the webpack plugin or esri-loader in your app today. Why would you choose one or the other? Generally, I'd say that esri-loader makes it easier to integrate the ArcGIS API into a webpack application, because there is zero configuration. However it forces you into using complicated async patterns when working with 'esri' modules. In contrast, I'd say that the webpack plugin may be a bit more complicated to set up and configure, but once you do it offers more flexibility. Also, the webpack plugin does result in increased build times, but they're working on that, but coming from the ember-cli, I barely noticed.

import and import()

The biggest difference is that only the webpack plugin allows you to use import statements for esri modules. Instead esri-loader's asynchronous loadModules() API forces developers to consider the cost of loading esri modules and to use strategies that defer that cost by consolidating their use. This works well in applications that make very simple use of the ArcGIS API, such as a single map component. However this can become cumbersome in an application that has multiple components that work with the ArcGIS API such as a map component, a legend component, and a drawing toolbar, etc. Those types of applications will be easier to develop using the webpack plugin and import statements. However, if you want to lazy-load the ArcGIS API and it's modules (and if you're targeting mobile you should), you won't be able to freely use import statements anyway. Instead you'll end up grouping them into one or a few modules that you lazy-load with dynamic import() and you'll probably end up creating your own internal async API that looks a lot like that of esri-loader! Hopefully someday we'll be able to just use import statements for esri modules w/o either of these libraries and have support for things like tree-shaking of the ArcGIS API modules. To that end, the webpack plugin is more future-proof than esri-loader.

Conclusion

Here's a side-by-side comparison of the high level capabilities.

Capabilityesri-loader@arcgis/webpack-plugin
Works with ArcGIS API < v4.7YesNo
Works with other bundlers besides webpackYesNo
"Just works" with any framework CLI or webpack pluginYesNot yet
Can lazy-load the ArcGIS API and it's modulesYesYes
Can be used in a server-side rendered applicationYesYes
Can import esri modulesNoYes
Is future-proofNoYes

When you look at that list, it becomes clear that that esri-loader is the versatile, backwards-compatible fallback solution, and  @arcgis/webpack-plugin is a forward-looking link toward a brighter future. If you are able to give the plugin a try in your application I recommend that you do. If not, or if it doesn't work out for you, esri-loader will always be here for you.