Start using ES6 for development and distribution
See original GitHub issueNow that ES 2015 (ES6) has been submitted to ECMA General Assembly for approval this seems like an idea time to start thinking about aligning Esri Leaflet with the standard and with the best possible development practices.
First this probably means a few things:
- Add Babel to the toolchain so we can compile ES 2015 code down to ES 5 code for release and testing.
- This means that we need a real development environment setup not just the
working
folder that is gitignored
Once those things were done we could take advantage of new features like arrow functions and Maps/WeakMap immediately spring to mind. Of course the biggest change would be using ES 2015 modules.
In addition to ES 2015 modules I still want to support Browserify and AMD based tools without ES 2015 out of the box. There are quite a few variations on the syntaxes for each system so I’ll summarize and leave it open for comments:
Browserify
One require to rule them all - this is how this currently works and is pretty much how everything else works in Browserify land.
var EsriLeaflet = require('esri-leaflet');
The maintenance overhead of trying to separate every component into separate modules is probably crazy from a maintenance standpoint because of the whole one repo per module rule. However we could (maybe, might be too crazy) on the commits tagged for release create a whole bunch of CommonJS modules in the root of the repo so you could do:
var FeatureLayer = require('esri-leaflet/Layers/FeatureLayer');
var Query = require('esri-leaflet/Tasks/Query');
Or we could use Babel to build all the module 1:1 int he dist folder so the above could also be done with:
var FeatureLayer = require('esri-leaflet/dist/commonjs/Layers/FeatureLayer');
var Query = require('esri-leaflet/dist/commonjs/Tasks/Query');
Which has kind of a bad code smell but thats kind of intentional http://blog.izs.me/post/44149270867/why-no-directories-lib-in-node-the-less-snarky but it works.
I need to test the last option but defining babelify
as a transform in package.json
might let you do this…
var FeatureLayer = require('esri-leaflet/lib/Layers/FeatureLayer');
var Query = require('esri-leaflet/lib/Tasks/Query');
AMD
The current way is to also do a single require statement for the whole library;
require([
'esri-leaflet'
], function(EsriLeaflet){
// do stuff
});
But since in AMD land we can map esri-leaflet
to anywhere we want we can do this to get smaller builds:
require([
'esri-leaflet/Layers/FeatureLayer',
'esri-leaflet/Tasks/Query'
], function(FeatureLayer, Query){
// do stuff
});
JSPM
JSPM is a newer package manager designed with ES 2015 modules the solves distribution and packaging problems. it just uses the ES 2015 syntax:
import {FeatureLayer, Query} from 'esri-leaflet';
However like most AMD loaders you can also load in individual files from a specified directory. Unlink AMD loaders JSPM lets package owners declare this directory at the package level so the following syntax also works and will result in smaller builds:
import {FeatureLayer} from 'esri-leaflet/Layers/FeatureLayer';
import {Query} from 'esri-leaflet/Tasks/Query';
Native ES 2015
Identical to the JSPM syntax this means that we will have to distribute Esri Leaflet in ES 2015 form. This would be for people who want to use Esri Leaflet without a package manager but are still using Babel, another compiler, or use the asynchronous System.import
syntax:
// sync
import {FeatureLayer, Query} from 'esri-leaflet'; // import everything
import {FeatureLayer} from 'esri-leaflet/layers/FeatureLayer'; // just FeatureLayer and its dependencies
import {Query} from 'esri-leaflet/Tasks/Query'; // just Query and its dependencies
// async
System.import('esri-leaflet').then(function(EsriLeaflet){}) // import everything
System.import('esri-leaflet/layers/FeatureLayer').then(function(FeatureLayer){}); // just FeatureLayer and its dependencies
System.import('esri-leaflet/Tasks/Query').then(function(Query){}); // just Query and its dependencies
Requirements
- Global
L.esri
build. You can download this and host it yourself. This is also what we make available on the CDN. - CommonJS build for Browserify.
- AMD build for Dojo/RequireJS/other AMD loaders.
- JSPM build (could be CommonJS or ES 2015).
- An ES 2015 build for native ES 2015 support. This should probably also be on the CDN for when browsers support
System.import
. - Distribute on CDN, GitHub, Bower, NPM and JSPM.
Workflow
- Write everything in the ES 2015 syntax
- To get the
L.esri
build we need a small wrapper file (lets call itall.js
) that imports everything, and assigns it toL.esri
. This is what we build and host on the CDN. - To support AMD we use Babel with
--modules amd
and distribute it in a specialamd
folder. Users will have to configure the path to'esri-leaflet'
to point to something likeesri-leaflet/dist/amd
. This is really similar to what you already have to do. - To support Browserify we would use Babel with
--modules common
to build ourall.js
file and distribute in a special location likeesri-leaflet/dist/commonjs/esri-leaflet.js
folder. This would be the value ofmain
inpackage.json
which is used by Browserify when yourequire('esri-leaflet')
. - At this point JSPM can use same file that Browserify does since it treats everything as CommonJS be default. An alternative to this would be to point JSPM the folder full of the raw ES 2015 code to allow users use import things on a file-by-file basis like the JSPM example above. You could also override the
main
value to look at the raw source for all.js with the specialjspm
property inpackage.json
as detailed in the JSPM docs - At this point we should host the compiled AMD modules and the uncompiled ES 2015 source code on the CDN to support AMD users not using a package manager and people using
System.import
Concerns
- Using Babel will require use of a polyfill. Luckily we can automatically include this seamlessly in the Browserify/JSPM use cases with the Babel Runtime. However this is a big problem for AMD users or people who want to use the CDN as they now have and additional download to worry about.
- This also means dropping IE 8 support since Babel will assume you have an complete ES 5 environment. This MIGHT be able to work with es5-shim though.
Any thoughts on this from @odoe @robertd @stdavis @dbouwman @chelm @ngoldman @paulcpederson @nikolaswise @alaframboise @jgravois?
Issue Analytics
- State:
- Created 8 years ago
- Comments:12 (12 by maintainers)
Top GitHub Comments
@patrickarlt I don’t think a full ES6/2015/? rewrite is necessary to accomplish the majority of the build tooling changes you mentioned above. My recommendation is still to let Leaflet lead in terms of conventions (if anything, propose an ES6 rewrite there and then do it here once that’s happened).
With that said I’m just a bystander and occasional user, not a core contributor. If it makes maintaining and distributing easier, doesn’t negatively impact contributors, and isn’t a huge departure from Leaflet conventions, then I say follow your heart. ❤️
implemented in 2.0.0-beta.1.