Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How should plugin authors deal with lack of a global "L" variable at 0.8? #2783

Closed
patrickarlt opened this issue Jul 7, 2014 · 1 comment

Comments

@patrickarlt
Copy link
Member

Looking at the 0.8 source Leaflet 0.8 will not declare a global L variable when it detects an AMD or common.js environment https://github.com/Leaflet/Leaflet/blob/master/src/Leaflet.js#L18-L28.

I think this has some interesting implications for plugin authors who (by and large) are relying on and exporting to the global variable. The big problem here is how plugins should load Leaflet as a dependency.

This is a best approach I could come up with, its based on https://github.com/umdjs/umd/blob/master/returnExportsGlobal.js.

(function (factory) {

    //define an AMD module that relies on 'leaflet'
    if (typeof define === 'function' && define.amd) {
        define(['leaflet'], function (L) {
            return (exports = factory(L));
        });

    //define a common js module that relies on 'leaflet'
    } else if (typeof exports === 'object') {
        module.exports = factory(require('leaflet'));

    // attach your plugin to the global
    } else {
        window.L.YourPlugin = factory(L);
    }
}(function (L) {
    // define your plugin using L just like it was a global
    var exports = {};

    // return your plugin when you are done
    return exports;
}));

This approch works just fine for both Browserify (provided the plugin is published on NPM)

var L = require('leaflet');
var Plugin = require('a-leaflet-plugin');

var map = L.map('map').setView([37.75, -122.23], 10);
Plugin.thing().addTo(map);

And Require js (provided you setup the paths to the plugin and Leaflet correctly)

requirejs.config({
    baseUrl: 'your base path',
    paths: {
        leaflet: 'the/path/to/leaflet', // dont include .js
        'a-leaflet-plugin': 'the/path/to/leaflet-plugin' // dont include .js
    }
});

requirejs([
    'leaflet',
    'a-leaflet-plugin'
], function (L, Plugin) {
    var map = L.map('map').setView([37.75, -122.23], 10);
    Plugin.thing().addTo(map);
});

The only real problem with this approch is that when using Require.js users will need to decare the path to Leaflet WITH THE RIGHT NAME. If you setup requirejs.config like this...

requirejs.config({
    baseUrl: 'your base path',
    paths: {
        Leaflet: 'the/path/to/leaflet', // dont include .js
        'leaflet-plugin': 'the/path/to/leaflet-plugin' // dont include .js
    }
});

Require.js won't know where to find 'leaflet' when the plugin relies upon it.

So in order for users to avoid having to do...

requirejs.config({
    baseUrl: 'your base path',
    paths: {
        Leaflet: 'the/path/to/leaflet', // dont include .js
        leaflet: 'the/path/to/leaflet', // dont include .js
        leafLet: 'the/path/to/leaflet', // dont include .js
        LeAfLeT: 'the/path/to/leaflet', // dont include .js
        'leaflet-plugin': 'the/path/to/leaflet-plugin' // dont include .js
    }
});

It would probably be nice to standardize around using 'leaflet' when configuring Require.js and put examples of this pattern in the plugin guide so authors have something to go on. It would also be nice to have examples of setting up Leaflet and using Leaflet plugins in Browserify and Require.js.

Should I write all this up and make a PR to the plugin guide?

@mourner
Copy link
Member

mourner commented Oct 14, 2014

Yep, also discussed in #2364 with the same conclusion as yours in the PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants