Leaflet.markercluster
Leaflet.markercluster copied to clipboard
Does not work with ES6 imports for leaflet
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({
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'
Yes but then you throw away all the benefits of ES6 modules. Which is to load only what you really need.
If you find a solution let me know, what modules does this work with so far on leaflet?
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:
- https://github.com/Leaflet/Leaflet/pull/5620
- https://github.com/Leaflet/Leaflet/pull/6021
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
.
Hi @himerus,
By curiosity, please what is your build engine, version, and what are the Leaflet and Leaflet.markercluster versions you are using?
@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
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.
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
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
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...
Right under the imports, I have used this to declare L.
const L = window['L'];
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'];
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).
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!
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
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/
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.
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.
@danzel What do you say about this? Shall we try to make this package independent on global L
and instead use ES6 imports?
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.
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
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.
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
import * as L from "leaflet"; import * as L1 from "leaflet.markercluster"; ... var markers = new L1.MarkerClusterGroup();
Hope it works for you guys
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
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 });
I guess this still has not been fixed?
Might be able to work around this by adding to webpack.config.js under exports.plugins:
new webpack.ProvidePlugin({
L: 'leaflet',
'window.L': 'leaflet',
}),
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)
}
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.