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

Does not work with ES6 imports for leaflet #874

Open
pke opened this issue Feb 21, 2018 · 30 comments · May be fixed by #984
Open

Does not work with ES6 imports for leaflet #874

pke opened this issue Feb 21, 2018 · 30 comments · May be fixed by #984
Assignees

Comments

@pke
Copy link

pke commented Feb 21, 2018

It seems this plugin makes the assumption that L is still exported globally.
However using leaflet the ES6 way with direct imports like
import { map } from "leaflet/src/map/Map"

does not expose a L global anymore. So trying to include this plugins MarkerClusterGroup fails cause of this definition.

export var MarkerClusterGroup = L.MarkerClusterGroup = L.FeatureGroup.extend({

The correct way would be to write this like this:

import { FeatureGroup } from "leaflet/src/layer/FeatureGroup"
export var MarkerClusterGroup = FeatureGroup.extend({
@kgrosvenor
Copy link

works fine for me if you just import all of it...

import 'leaflet/dist/leaflet.css' import 'leaflet/dist/leaflet' import 'leaflet-draw' import 'leaflet-draw/dist/leaflet.draw.css' import 'leaflet.markercluster' import 'leaflet.markercluster/dist/MarkerCluster.css'

@pke
Copy link
Author

pke commented Mar 13, 2018

Yes but then you throw away all the benefits of ES6 modules. Which is to load only what you really need.

@kgrosvenor
Copy link

If you find a solution let me know, what modules does this work with so far on leaflet?

@himerus
Copy link

himerus commented Mar 22, 2018

Yeah, I'm interested in this proper solution as well...

I've taken from the above and was able to get it working, although, as mentioned without the benefit of ES6 and selectively loading what was needed.

// Import CSS from Leaflet and plugins.
import 'leaflet/dist/leaflet.css';
import 'leaflet.markercluster/dist/MarkerCluster.css';
import 'leaflet.markercluster/dist/MarkerCluster.Default.css';

// Import images directly that got missed via the CSS imports above.
import 'leaflet/dist/images/marker-icon-2x.png';
import 'leaflet/dist/images/marker-shadow.png';

// Import JS from Leaflet and plugins.
import 'leaflet/dist/leaflet';
import 'leaflet.markercluster/dist/leaflet.markercluster';
import 'leaflet.gridlayer.googlemutant/Leaflet.GoogleMutant';

Related PRs and discussions for Leaflet:

I'd love to figure out how to use the correct, minimalistic ES6 way with my custom Leaflet setup. The only plugins I'm using are markercluster, because who wouldn't use it?! and the Google maps layer.

If I use: import * as L from 'leaflet'; instead of import 'leaflet/dist/leaflet';, I get TypeError: L.markerClusterGroup is not a function.

@ghybs
Copy link
Contributor

ghybs commented Mar 24, 2018

Hi @himerus,

By curiosity, please what is your build engine, version, and what are the Leaflet and Leaflet.markercluster versions you are using?

@azrin1972
Copy link

@ghybs,

I too have the same problem as @himerus.

import * as L from 'leaflet';instead of import 'leaflet/dist/leaflet';, I get TypeError: L.markerClusterGroup is not a function.

but if I use

import 'leaflet/dist/leaflet';

I got error 'L' is not defined no-undef

I'm using maven to build
Leaflet 1.3.1
Leaflet.markercluster 1.3.0

@himerus
Copy link

himerus commented Mar 25, 2018

Same as above mentioned by @azrin1972 . Only difference in my setup is I'm using Webpack.

The 'L' is not defined no-undef is coming from eslint.
The TypeError: L.markerClusterGroup is not a function is a fatal error that stops MarkerCluster from working.

@ghybs
Copy link
Contributor

ghybs commented Mar 26, 2018

Hi,

Thank you @azrin1972 and @himerus for the details of your setup.

Very strange, I have no issue at all with webpack, either with import * as L from 'leaflet' or just import 'leaflet':
https://github.com/ghybs/test-mcg-import-webpack
(ignoring the ESLint warning for now)

  • webpack 4.2.0
  • Leaflet 1.3.1
  • Leaflet.markercluster 1.3.0

@HarelM
Copy link

HarelM commented Mar 27, 2018

I have the same issue. only happens with leaflet 1.3.1 but not with 1.3.0.
Uncaught ReferenceError: L is not defined
Using anuglar-cli (which uses webpack) and using import * as L from "leaflet" in various places in the code.
Project can be found here if it can help:
https://github.com/IsraelHikingMap/Site/tree/master/IsraelHiking.Web

@HarelM
Copy link

HarelM commented Mar 28, 2018

My mistake, I was using a branch version of leaflet: https://github.com/va2ron1/Leaflet which doesn't have the oldL defined and so marker cluster crashes (I think). Not sure if this is a part of leaflet next release or the branch...

@dallasclymer
Copy link

Right under the imports, I have used this to declare L.

const L = window['L'];

@severinbeauvais
Copy link

I'm using

"leaflet": "^1.3.1",
"leaflet.markercluster": "^1.3.0"

and

"@types/leaflet": "^1.2.6",
"@types/leaflet-markercluster": "^1.0.3"

The following worked for me:

import 'leaflet';
import 'leaflet.markercluster';

const L = window['L'];

@helllamer
Copy link

Make things working on leaflet-src.esm.js and without window.L:

  • Leaflet.markercluster-1.3.0
  • leaflet-1.3.2 (NOT 1.3.3 or 1.3.1), see leaflet#6239
  • Need some shims using import/export loaders:
import Leaflet from 'leaflet'
import MarkerClusterGroup from 'imports-loader?L=leaflet!exports-loader?L.MarkerClusterGroup!./node_modules/leaflet.markercluster/dist/leaflet.markercluster.js'

// Create cluster:
val mcg = new MarkerClusterGroup(...);
Leaflet.addLayer(mcg);

Solution based on earlier crunch (L<=1.3.1).

@markomalis
Copy link

I'm using webpack to bundle my project. When I put leaflet and leaflet.markerclusterer together in the vendor bundle I don't have this issue anymore. Maybe helpful for people using this with webpack!

@azrin1972
Copy link

Hi, I'm still unable to load markercluster in my project. what I'm trying to do is to add markercluster to https://github.com/thingsboard/thingsboard. Really need some help on how to solve this. it uses webpack 1.13.2. and I cannot use webpack 4 - I'm getting error compiling it.

I've tried all the solution here and still getting the same issue

@azrin1972
Copy link

Finally found the solution

instead of using
import * as L from 'leaflet'

I use

import L from 'leaflet'

some reading http://www.thedreaming.org/2017/04/28/es6-imports-babel/

@rednil
Copy link

rednil commented Dec 5, 2018

Ran into this issue while trying to use Markercluster in a web component based PWA (no packaging involved yet, just dev server). I can import all the leaflet modules like this:

import { TileLayer } from 'leaflet/src/layer/tile'
import { GeoJSON } from 'leaflet/src/layer'
import { CircleMarker } from 'leaflet/src/layer/vector'
import { Marker, Icon, DivIcon } from 'leaflet/src/layer/marker'

but
import { MarkerClusterGroup } from 'leaflet.markercluster/src'
results in ReferenceError: L is not defined
None of the workarounds mentioned here works for me.

konstin added a commit to meine-stadt-transparent/meine-stadt-transparent that referenced this issue Dec 15, 2018
konstin added a commit to meine-stadt-transparent/meine-stadt-transparent that referenced this issue Dec 15, 2018
@kontrollanten
Copy link
Contributor

A guess the way to solve this is to stop depending on window.L in all the files, and instead do ES import, like leaflet/leaflet does. It would be a pretty great step forward.

@kontrollanten
Copy link
Contributor

@danzel What do you say about this? Shall we try to make this package independent on global L and instead use ES6 imports?

@danzel
Copy link
Member

danzel commented Mar 5, 2019

We follow what leaflet recommends for plugins (AFAIK).
https://github.com/Leaflet/Leaflet/blob/master/PLUGIN-GUIDE.md

If we want to change this, probably fire up an issue on the leaflet tracker for discussion.
Would be good to improve this support.

@kontrollanten
Copy link
Contributor

I can't see anything in their recommendations against this, we'll still bundle the plugin so it'll work as before for those who're using the UMD version

@pke
Copy link
Author

pke commented Jan 7, 2020

Coming back here after 2 years I'd have thought this issue to be resolved. It seems its still not possible to properly import leaflet and this plugin.
I am going to open a new PR over at leaflet to suggest a 2.0 release and intentionally breaking all the plugins depending on a global 'L' var. It seems otherwise we can not get any plugin owner to move forward to packages.

@m1gu3l m1gu3l linked a pull request Jan 21, 2020 that will close this issue
@m1gu3l
Copy link

m1gu3l commented Jan 23, 2020

I've made PR #984 that should fix this few days ago, I'd like some backup.

Basically in source files L is used as global and it leaked to the bundle. I've configured rollup to feed L variable from UMD require - which works as well with global L outside the bundle.

And it's ok with guidelines:
https://github.com/Leaflet/Leaflet/blob/master/PLUGIN-GUIDE.md#module-loaders

@AliBayatpour
Copy link

import * as L from "leaflet";
import * as L1 from "leaflet.markercluster";
...
var markers = new L1.MarkerClusterGroup();

Hope it works for you guys

@daslicht
Copy link

daslicht commented Dec 4, 2020

import * as L from "leaflet";
import * as L1 from "leaflet.markercluster";
...
var markers = new L1.MarkerClusterGroup();

Hope it works for you guys

this gives me :

Uncaught TypeError: t is undefined
    <anonymous> /webcomponents/leafletmap/leaflet/leaflet.js:5
    <anonymous> /webcomponents/leafletmap/leaflet/leaflet.js:5

@andreasnuesslein
Copy link

just in case anybody runs into the same situation I had here:
I tried to go from;

import "leaflet";
import "leaflet.markercluster";

...
let mcluster = L.markerClusterGroup({ chunkedLoading: true });

to:

import { Map, Marker,  } from "leaflet";
import { MarkerClusterGroup } from "leaflet.markercluster/src";

...
let mcluster = MarkerClusterGroup({ chunkedLoading: true });

I banged my head against a wall until I realized I had to call it with new:

let mcluster = new MarkerClusterGroup({ chunkedLoading: true });

@lukebouch
Copy link

I guess this still has not been fixed?

@jacobweber
Copy link

Might be able to work around this by adding to webpack.config.js under exports.plugins:

      new webpack.ProvidePlugin({
        L: 'leaflet',
        'window.L': 'leaflet',
      }),

@disarticulate
Copy link

since we're posting hotfixs. I've got a Vue app in Quasar 2. Before the Vue app is initialized:

import * as L from "leaflet/dist/leaflet-src.esm.js"
globalThis.L = L

in a component then:

  async mounted() {
    const { MarkerClusterGroup } = await import('leaflet.markercluster')
    console.log(this.$options.name, this.projects, MarkerClusterGroup)
  }

@willianspraciano
Copy link

I was having a similar problem using leaflet in Vite:
No matching export in "node_modules/leaflet/dist/leaflet-src.esm.js" for import "toLatLngBounds"

Using import 'leaflet/dist/leaflet'; instead import L from 'leaflet'; or import 'leaflet'; worked for me.

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

Successfully merging a pull request may close this issue.