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

Issues importing leaflet.css when using webpack #255

Closed
thj-dk opened this Issue Nov 18, 2016 · 19 comments

Comments

@thj-dk

thj-dk commented Nov 18, 2016

I'm seeing a strange issue when importing node_modules/leaflet/dist/leaflet.css, and it's most likely related to my webpack configuration.

When loading a map with a marker, I'm seeing the following GET request:
http://localhost:9091/2273e3d8ad9264b7daa5bdbf8e6b47f8.png%22)marker-icon.png

What appends %22)marker-icon.png? If I remove that and request the URL, the image is there. So webpack has the correct image bundled, i presume.

Here's our webpack loader configurations:

module: {
  loaders: [
    {
      test: /\.js$/,
      loaders: ['babel'],
      exclude: /node_modules/,
      include: __dirname
    },
    {
      test: /\.json$/,
      loader: "json-loader"
    },
    {
      test: /\.(sass|scss)$/,
      loaders: ['style', 'css', 'resolve-url', 'sass?sourceMap']
    },
    {
      test: /\.css$/,
      loaders: ['style', 'css'],
    },
    {
      test: /\.(woff2?|ttf|eot|jpe?g|png|gif|svg)$/,
      loader: 'url?limit=1'
    }
  ]
}

The limit of the url-loader is temporary while debugging this issue.

Any help will be much appreciated!

@PTihomir

This comment has been minimized.

PTihomir commented Nov 18, 2016

I have the same issue. But previously it worked. I just updated react-leaflet and it started to work as mentioned in the comment above.

@PaulLeCam

This comment has been minimized.

Owner

PaulLeCam commented Nov 19, 2016

Leaflet changed the way it loads image assets based on the CSS URL, please refer to their documentation as there is no specific logic regarding the CSS and assets in this lib.

@thj-dk

This comment has been minimized.

thj-dk commented Nov 20, 2016

I'm aware. I haven't been able to locate this issue in their docs, and I thought that most people here used it with webpack, so I was hoping that some could share a solution.

@danhayden

This comment has been minimized.

danhayden commented Nov 21, 2016

looks like this may be linked to Leaflet/Leaflet#4968 and Leaflet/Leaflet#5041

@PTihomir

This comment has been minimized.

PTihomir commented Nov 21, 2016

My solution to solve this problem:

import L from 'leaflet';

L.Icon.Default.imagePath = '.';
// OR
delete L.Icon.Default.prototype._getIconUrl;

L.Icon.Default.mergeOptions({
  iconRetinaUrl: require('leaflet/dist/images/marker-icon-2x.png'),
  iconUrl: require('leaflet/dist/images/marker-icon.png'),
  shadowUrl: require('leaflet/dist/images/marker-shadow.png'),
});

but if anybody has some nicer solution, please share :)

@grahamb

This comment has been minimized.

grahamb commented Nov 24, 2016

Thanks for the workaround, @PTihomir. I had to go with the delete L.Icon.Default.prototype._getIconUrl; option; doing L.Icon.Default.imagePath = '.'; resulted in a . being prepended to a data URI (e.g. .data:img/png;base64......), probably due to something in my webpack config.

@PaulLeCam

This comment has been minimized.

Owner

PaulLeCam commented Nov 26, 2016

Closing as it's not an issue that can be fixed in this lib

@PaulLeCam PaulLeCam closed this Nov 26, 2016

@jampy

This comment has been minimized.

jampy commented Dec 30, 2016

Closing as it's not an issue that can be fixed in this lib

Maybe a warning or something like that in the README?

I guess most people using react-leaflet will use Webpack and will run into the same problem, loosing quite some of time to find the reason (like me)...

@jampy jampy referenced this issue Dec 30, 2016

Closed

L.Icon.Default brings a wrong image url #4968

0 of 2 tasks complete
@codeofsumit

This comment has been minimized.

codeofsumit commented Dec 30, 2016

Thank you @PTihomir, this worked:

import L from 'leaflet';
delete L.Icon.Default.prototype._getIconUrl;

L.Icon.Default.mergeOptions({
  iconRetinaUrl: require('leaflet/dist/images/marker-icon-2x.png'),
  iconUrl: require('leaflet/dist/images/marker-icon.png'),
  shadowUrl: require('leaflet/dist/images/marker-shadow.png'),
});
@MatthewPardini

This comment has been minimized.

MatthewPardini commented Feb 8, 2018

I used @PTihomir solution, but had to change the import statement to a require variable. I also had to use the delete method as the '.' prepended the path with a '.' and the problem remained.

var L = require('leaflet');

Hope this saves someone else some time.

@yoursdearboy

This comment has been minimized.

yoursdearboy commented Apr 11, 2018

You need to use file-loader for webpack.

@Harti

This comment has been minimized.

Harti commented May 8, 2018

@yoursdearboy mind getting more specific? What options do I put where?

@knackjason

This comment has been minimized.

knackjason commented May 10, 2018

@yoursdearboy more details would indeed be appreciated. I am using file-loader (I couldn't even build w/o adding it in b/c of the leaflet CSS), but still have the error we're all dealing with here. Did you figure out a different way to get this working?

@yoursdearboy

This comment has been minimized.

yoursdearboy commented May 11, 2018

Hi @Harti @knackjason. I've made a demo to investigate this issue. See the 2nd and 3rd commits for errors descriptions and solutions.

I think the problem here is with file name generation (specifically with hash). Removing it is a major
downside of this solution. I'd like to ask webpack community for help and provide this demo but didn't have time yet.

@knackjason

This comment has been minimized.

knackjason commented May 11, 2018

@yoursdearboy ah, ok. I see what you doing.

I combined your idea with the workaround above and have this working with Leaflet 1.3.1 and Webpack 4.8.2:

webpack.config.js

...
module: {
...
    {
        test: /\.(png|svg|jpg|gif)$/,
        use: [{
            loader: 'file-loader',
            options: {
                name:'img/[name]_[hash:7].[ext]',
            }
        }]
    }]
},
...

app.js

import L from 'leaflet';

import 'leaflet/dist/leaflet.css';

// stupid hack so that leaflet's images work after going through webpack
import marker from 'leaflet/dist/images/marker-icon.png';
import marker2x from 'leaflet/dist/images/marker-icon-2x.png';
import markerShadow from 'leaflet/dist/images/marker-shadow.png';

delete L.Icon.Default.prototype._getIconUrl;

L.Icon.Default.mergeOptions({
    iconRetinaUrl: marker2x,
    iconUrl: marker,
    shadowUrl: markerShadow
});
@yoursdearboy

This comment has been minimized.

yoursdearboy commented May 12, 2018

@knackjason Doesn't @PTihomir solution work without this? I'd like to understand why the hash is broken.

@knackjason

This comment has been minimized.

knackjason commented May 13, 2018

@yoursdearboy ah, yes that is the case. The extra Webpack config is unnecessary. I'm still pretty new to Webpack, so ... yeah.

I read through a bunch of Leaflet issues related to this issue the other day. Some of them explain what's going on with the hash getting messed up. These two have most of the information that I was able to track down. It's pretty sad to me that this has been an issue for 2 years now.

Leaflet/Leaflet#4968
Leaflet/Leaflet#5771

@georgiana-gligor

This comment has been minimized.

georgiana-gligor commented May 15, 2018

Thank you @knackjason, you saved a me a good hour of debugging!

@knackjason

This comment has been minimized.

knackjason commented May 15, 2018

@georgiana-gligor @PTihomir is really the one you should be thanking. I'm glad you didn't have to spend the time debugging though. 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment