I am trying to create a react-typescript app along with leaflet. I used the command,
npm install leaflet react-leaflet @types/react @types/leaflet --save to install the dependencies.
But when I start the application it says,
./node_modules/@react-leaflet/core/esm/path.js 10:41
Module parse failed: Unexpected token (10:41)
File was processed with these loaders:
* ./node_modules/babel-loader/lib/index.js
You may need an additional loader to handle the result of these loaders.
| useEffect(function updatePathOptions() {
| if (props.pathOptions !== optionsRef.current) {
> const options = props.pathOptions ?? {};
| element.instance.setStyle(options);
| optionsRef.current = options;
Here's my package.json
{
"name": "aq-monitor",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^5.12.0",
"@testing-library/react": "^11.2.7",
"@testing-library/user-event": "^12.8.3",
"@types/jest": "^26.0.23",
"@types/leaflet": "^1.7.0",
"@types/node": "^12.20.13",
"@types/react": "^17.0.5",
"@types/react-dom": "^17.0.5",
"antd": "^4.15.5",
"leaflet": "^1.7.1",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-leaflet": "^3.2.0",
"react-router-dom": "^5.2.0",
"react-scripts": "4.0.3",
"typescript": "^4.2.4",
"web-vitals": "^1.1.2"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"@types/react-router-dom": "^5.1.7"
}
}
Here's map/index.tsx
import React from 'react';
import './styles.css';
import L, { LatLngExpression } from "leaflet";
import "leaflet/dist/leaflet.css";
import {MapContainer, TileLayer, Marker, Popup} from 'react-leaflet';
const position : LatLngExpression = [59.91174337077401, 10.750425582038146];
export default function MapJar() {
return (
<MapContainer center={position} zoom={13} scrollWheelZoom={false}>
<TileLayer
attribution='© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
<Marker position={position}>
<Popup>
A pretty CSS3 popup. <br /> Easily customizable.
</Popup>
</Marker>
</MapContainer>
);
};
I tried re-installing dependencies several times but still didn't work.
I understand this is a simple issue and an error that I am making but however, I have not been able to resolve this error.
Any input is appreciated. Thanks in advance.
I faced the same issue with the latest version of the leaflet: "^3.2.0", but I did overcome this problem by downgrade to version 2.7.0. Here what you should do:
Downgrade to "react-leaflet": "2.7.0".
The issue eventually seems to be related with create-react-app and the way it bundles files and seems to be resolved if you replace browser targets from:
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
to
"browserslist": [
">0.2%",
"not dead",
"not op_mini all"
],
Then stop the server and rerun it.
Credits go to bkiac official create-react-app github issue
Edit
You can reproduce the error and the fix if you download this codesandbox. When you open it, it works but if you download it and run it locally you can see the error using the first browserslist options in package.json. If you stop the server, replace browserslist options with the new and rerun the application you can see that it works as expected.
add
"react-leaflet": ">=3.1.0 <3.2.0 || ^3.2.1",
"@react-leaflet/core": ">=1.0.0 <1.1.0 || ^1.1.1"
in "package.json"
The second solution:
If you still have problems, It may be from package.json file. Check that it to be alike the following file:
{
"name": "my-app",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^5.12.0",
"@testing-library/react": "^11.2.7",
"@testing-library/user-event": "^12.8.3",
"antd": "^4.15.6",
"leaflet": "1.7.1",
"leaflet.marker.slideto": "^0.2.0",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-leaflet": "3.0.2",
"react-leaflet-drift-marker": "^3.0.0",
"react-scripts": "4.0.3",
"web-vitals": "^1.1.2"
},
"devDependencies": {
"typescript": "3.8.3"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
]
}
I found a way to fix it.
Steps to fix:-
Open your package.json file and edit your browserslist as follows.
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
to
"browserslist": [
">0.2%",
"not dead",
"not op_mini all"
],
Once you've done this, Delete node_modules/.cache directory.
Then try npm install
and npm start
Tadaaa!
References:-
In its source code React-Leaflet uses the Nullish Coalescing Operator which is not supported by a specific version of Acorn.
For more details check nnatter's explanation here:
https://github.com/PaulLeCam/react-leaflet/issues/883
To fix the problem, you can:
1- use nnater's suggested solution:
https://babeljs.io/docs/en/babel-plugin-proposal-nullish-coalescing-operator
or
2 - instead of using the official React-Leaflet package you can use
npm install --save @monsonjeremy/react-leaflet
From
https://www.npmjs.com/package/@monsonjeremy/react-leaflet
which is a fork of RL 3.2.1.
That way you do not have to downgrade nor do funny stuff.
For those running nextjs.
You can fix this enabling webpack 5 in next.config.js file.
const nextConfig = {
future: {
webpack5: true,
},
};
module.exports = nextConfig;
Thanks to this comment from marcin-piechaczek: https://github.com/PaulLeCam/react-leaflet/issues/883#issuecomment-849126348
I got this error after upgrade react-leaflet to version 3.2.0 to fix an error while removing markers with permanent tooltips from the map.
Add "@types/leaflet": "1.7.0" into dependencies of package.json.
Hacking your browserslist or downgrading packages is not a secure or long-term solution to dealing with modules that don't target a reasonable version of JS. @jlahd's answer is great, except that react-app-rewire-babel-loader is no longer supported by its author. You can achieve the same result even more easily with customize-cra (which you should be using with CRA anyway, since that's the only way to configure your Content Security Policy) by using babelInclude:
// config-overrides.js
const { babelInclude, override } = require('customize-cra');
const path = require('path');
module.exports = {
webpack: override(
babelInclude([
path.resolve('src'),
path.resolve('node_modules/@react-leaflet'),
path.resolve('node_modules/react-leaflet')
])
// and configure other stuff here like csp-html-webpack-plugin
),
};
I encountered this problem after I did an npm update.
These packages were installed:
"react-leaflet": "^3.2.0"
and as dependency (found in .lock):
"@react-leaflet/core": "1.1.0",
Forcing npm to use these versions, fixed it for me:
"@react-leaflet/core": "1.0.2",
"react-leaflet": "3.1.0",
So try npm i react-leaflet@3.1.0 @react-leaflet/core@1.0.2
I had the same problem, but all the solutions planned here did not convince me. So I solved it in the following way:
yarn add -D @babel/plugin-proposal-nullish-coalescing-operator
then I added it to the babel plugins in babel.config.js
module.exports = {
presets: [
// ... some presets here
],
plugins: [
// ... any plugins here
'@babel/plugin-proposal-nullish-coalescing-operator',
],
env: {
// ... your config
},
}
as the problem arises because the library is using the nullish (??) operator, I should add it to the list of exclusions of the bable-loader in webpack.
// webpack.common.js
module.exports = {
// ... some config here
module: {
rules: [
{
test: /\.(js|jsx)$/,
// the @react-leaflet and react-leaflet libraries must be excluded.
exclude: /node_modules\/(?!(@react-leaflet|react-leaflet)\/)/i,
use: []
}
],
// ... more config here
}
I fixed the issue by change the browserslist as other have stated. My browserslist now looks like this:
"browserslist": [
">0.2%",
"not dead",
"not op_mini all"
]
I then did the following:
node_modules foldernpm cache clean --forcenpm installNow everything should work as expected. If the map is not loaded, don't forget to add the leaflet css and js to your page and set the height for your map-container. See the official documentation for more information.
I faced the same issue using version 3.2.0 of react-leaflet. The solution above worked but I want to add a couple of details for clarification purpose:
"browserslist":
[
">0.2%",
"not dead",
"not op_mini all"
],
NOTE THAT The above package.json code need to be exact, meaning there are no { } in the above code after you have deleted:
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
from:
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]},
Separately, on your terminal, type cd follow by ls to see if there are any package.json and node_modules lying around. If they are there, rm -rf filename to delete them (as you may have added them by mistake over time when you forgot to navigate to your project and npm i or yarn them by mistake).
Finally, install react-leaflet again and it should work. (Note: see if your package.json has been updated to 3.2.0 (or the latest version) after you have reinstalled to the latest version, if not, just change the react-leaflet on your package.json to the latest installed version manually.)
This does not directly apply to the original question (the instructions are for create-react-app originated projects), but I'm still writing the answer in case some CRA user besides myself happens to stumble on this question.
yarn start just forced a refresh of the configuration)What finally did work was using the two libraries react-app-rewired and react-app-rewire-babel-loader. Steps necessary:
yarn add -D react-app-rewired react-app-rewire-babel-loaderpackage.json according to the instructions for react-app-rewired: /* package.json */
"scripts": {
- "start": "react-scripts start",
+ "start": "react-app-rewired start",
- "build": "react-scripts build",
+ "build": "react-app-rewired build",
- "test": "react-scripts test",
+ "test": "react-app-rewired test",
"eject": "react-scripts eject"
}
config-overrides.js in the project's root according to instructions for react-app-rewire-babel-loader:/* config-overrides.js */
const path = require("path");
const fs = require("fs");
const rewireBabelLoader = require("react-app-rewire-babel-loader");
const appDirectory = fs.realpathSync(process.cwd());
const resolveApp = relativePath => path.resolve(appDirectory, relativePath);
module.exports = function override(config, env) {
config = rewireBabelLoader.include(
config,
resolveApp("node_modules/@react-leaflet")
);
config = rewireBabelLoader.include(
config,
resolveApp("node_modules/react-leaflet")
);
return config;
};
And then it works. Basically, this includes react-leaflet in babel transpilation in the same way @WITO's answer does for non-CRA builds.
After installing react-leaflet the existing package.json will be like this :
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
But on running this it will show an error like this :
./node_modules/@react-leaflet/core/esm/path.js 10:41
Module parse failed: Unexpected token (10:41)
File was processed with these loaders:
* ./node_modules/babel-loader/lib/index.js
You may need an additional loader to handle the result of these loaders.
| useEffect(function updatePathOptions() {
| if (props.pathOptions !== optionsRef.current) {
> const options = props.pathOptions ?? {};
| element.instance.setStyle(options);
| optionsRef.current = options;
"browserslist": [ ">0.2%", "not dead", "not op_mini all" ],
For those that use nextjs
Create a map in a component and import with ssr:false;
Example:
Component: Map.js
const OpenMap = () => {
return (
<div className="container">
<MapContainer MapContainer style={{ height: '300px' }} center={[60.198334, 24.934541]} zoom={10}>
<TileLayer
attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
</MapContainer>
</div>
);
};
Import the map into a page or where you need it like this:
Somewhere.js
import dynamic from 'next/dynamic'; // for dynamic importing
const OpenMap = dynamic(() => import('@/features/client/location/components/OpenMap'), {
ssr: false,
});
Then you can use it...
Also, you can add a loading component if needed.
For more details of dynamic import check the link by clicking here
you need to update react-scripts to solve this problem in package.json :
"react-scripts": "^5.0.0",