visgl/react-map-gl

6.x.x production build error "x is not defined"

testower opened this issue ยท 49 comments

I upgraded to 6.0.0 (also tried 6.0.1) and everything works fine in development mode, but in the production build the background map doesn't render using. I'm using a mapbox token.

        <StaticMap
          key="map"
          width="100%"
          height="100%"
          mapStyle={MAPBOX_MAP_STYLE}
          mapboxApiAccessToken={MAPBOX_ACCESS_TOKEN}
        />

I have an IconLayer that renders just fine, but on top of a grey background :/

Do you see any error in the console? Might be caused by mapbox/mapbox-gl-js#10173

Thanks, it seems related, I will follow that issue!

In production build I've got this error. Could you help, please?
image

@Velidoss please visit the Mapbox issue I linked above. The bug is in mapbox-gl@2.0.0. There is a temporary work around by adding additional bundler settings.

sgup commented

Same issue here. As a quick workaround I downgraded to v5.2.11 of react-map-gl:

yarn upgrade react-map-gl@5.2.11 and it works.

Downgrading to v5.2.11 of react-map-gl was insufficient for my use case since I'm using Mapbox GL JS v2.x.x features (setTerrain() specifically)

For those out there in a similar spot, I was able to hack around things for the time being by adapting the suggestions in mapbox/mapbox-gl-js#10173:

Install worker-loader:

yarn add worker-loader

In your map component:

import ReactMapGL from "react-map-gl";
import mapboxgl from "mapbox-gl"; // This is a dependency of react-map-gl even if you didn't explicitly install it

// eslint-disable-next-line import/no-webpack-loader-syntax
mapboxgl.workerClass = require("worker-loader!mapbox-gl/dist/mapbox-gl-csp-worker").default;

I hope the Mapbox team can provide a long term solution soon.

Having the same issue

Having the same issue

use the above work around for mapbox worker class it works gr8 for now ๐Ÿ‘

looks like they are working on a PR to address this here - https://github.com/mapbox/mapbox-gl-js-docs/pull/461

Looks like the "right" way might be to add this code:

import mapboxgl from 'mapbox-gl/dist/mapbox-gl';
import MapboxWorker from 'mapbox-gl/dist/mapbox-gl-csp-worker';
mapboxgl.workerClass = MapboxWorker;

Could someone explain why this works?

Mapbox has now published the official solution to this issue: https://docs.mapbox.com/mapbox-gl-js/api/#transpiling-v2

JG145 commented

I am still struggling to get this to work. I am able to get Mapbox-GL to work by using:
import mapboxgl, { queryRenderedFeatures } from "!mapbox-gl";

but still getting:
Uncaught ReferenceError: _createClass is not defined

sure i am missing something obvious but any help would be appreciated

@JG145 what I had to do was the following (as a create react app and typescript user)

yarn add worker-loader

/* eslint-disable @typescript-eslint/no-var-requires */
(mapboxgl as any).workerClass = require('worker-loader!mapbox-gl/dist/mapbox-gl-csp-worker').default;
JG145 commented

Still hitting the same issue?

gone with:

import mapboxgl from "!mapbox-gl";

import { StaticMap } from "!react-map-gl";
/* eslint-disable @typescript-eslint/no-var-requires */
mapboxgl.workerClass = require("worker-loader!mapbox-gl/dist/mapbox-gl-csp-worker").default;

Changing the above to:

import mapboxgl from "mapbox-gl";

import { StaticMap } from "react-map-gl";
/* eslint-disable @typescript-eslint/no-var-requires */
mapboxgl.workerClass = require("worker-loader!mapbox-gl/dist/mapbox-gl-csp-worker").default;

elicits this error:

VM1351:63121 Uncaught DOMException: Failed to construct 'Worker': Script at 'https://app.powerbi.com/13.0.15255.54/assetsmapbox-gl-csp-worker' cannot be accessed from origin 'null'.

Also get no clue how to solve this issue in versions above 5.3.4. Downgrade to v 5.3.4 solves it for now for me. If someone got a result on versions 6.0.0 and above for React, please give some code example here.

Downgrading to v5.2.11 of react-map-gl was insufficient for my use case since I'm using Mapbox GL JS v2.x.x features (setTerrain() specifically)

For those out there in a similar spot, I was able to hack around things for the time being by adapting the suggestions in mapbox/mapbox-gl-js#10173:

Install worker-loader:

yarn add worker-loader

In your map component:

import ReactMapGL from "react-map-gl";
import mapboxgl from "mapbox-gl"; // This is a dependency of react-map-gl even if you didn't explicitly install it

// eslint-disable-next-line import/no-webpack-loader-syntax
mapboxgl.workerClass = require("worker-loader!mapbox-gl/dist/mapbox-gl-csp-worker").default;

I hope the Mapbox team can provide a long term solution soon.

If you use typescript, just add // @ts-ignore above the eslint-disable line to ignore the typescript error when compiling (Property 'workerClass' does not exist on type 'typeof mapboxgl'.). This worked for me.

How can I solve?

Adding the

import 'mapbox-gl/dist/mapbox-gl.css';
import mapboxgl from 'mapbox-gl';
mapboxgl.workerClass = require('worker-loader!mapbox-gl/dist/mapbox-gl-csp-worker').default;

image

still gives me the error, and downgrading to 5.2.11 messes up some styles

image

@Pessimistress it'd be helpful to know what your recommendation is for people using react-map-gl. (it seems like some solutions in mapbox/mapbox-gl-js#10173 don't apply to us)

Is the recommendation to do this:
mapbox/mapbox-gl-js#10173 (comment)

I'm using react-map-gl, CRA, and typescript

In create-react-app, in javascript, worked for me adding this to package.json

"browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not ie 11",
      "not chrome < 51",
      "not safari < 10",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },

In turn in create-react-app, in typescript I had to add workaround with craco @craco/craco

// craco.config.js
module.exports = {
  babel: {
    loaderOptions: {
      ignore: ['./node_modules/mapbox-gl/dist/mapbox-gl.js'],
    },
  },
}

Having the same issues. Tried the suggested solutions but still getting the same error in prod.

UPDATE: Got it to work by downgrading the version but now the styling is messed up the same way as for DavideVito.

Thank you all for trying to fix this issue!

Has anyone gotten production code to work with Next.js?

I've tried downgrading, no luck. Tried changing babel transpiling, no luck, and tried all the different code snippets.

Probably there's something stupid I'm missing, but would love to know if anyone else has gotten it to work at all...

Has anyone gotten production code to work with Next.js?

In the end I managed to get it working in Next.js by exchanging the proprietrary mapbox-gl with maplibre-gl. I'm still not sure why downgrading would not work, but at least this did! ๐ŸŽ‰

Here is how:

Install maplibre-gl

Then add an alias replacing all instances of mapbox-gl with maplibre-gl in webpack:

My next.config.js:

module.exports = {
    webpack: (config) => {
        config.module.rules.push({
            resolve:{
                alias: {
                    ...config.resolve.alias,
                    'mapbox-gl': 'maplibre-gl'
                }
            }
        })
      // Important: return the modified config
      return config
    },
  }

If anyone is using react-mapbox-gl

default webpack config after ejecting:


            {
              test: /\.(js|mjs)$/,
              exclude: /@babel(?:\/|\\{1,2})runtime/,
              loader: require.resolve('babel-loader'),
              options: {
                // https://docs.mapbox.com/mapbox-gl-js/api/#transpiling-v2
                ignore: ['./node_modules/mapbox-gl/dist/mapbox-gl.js'], <--------------------- add
                babelrc: false,
                configFile: false,
                compact: false,
                presets: [
                  [
                    require.resolve('babel-preset-react-app/dependencies'),
                    { helpers: true },
                  ],
                ],
                cacheDirectory: true,
                // See #6846 for context on why cacheCompression is disabled
                cacheCompression: false,

                // Babel sourcemaps are needed for debugging into node_modules
                // code.  Without the options below, debuggers like VSCode
                // show incorrect code and set breakpoints on the wrong lines.
                sourceMaps: shouldUseSourceMap,
                inputSourceMap: shouldUseSourceMap,
              },
            },

This comment by @mtuanp worked for me.

Please don't try multiple solutions in one go (changing browserslist, configuring web worker to load and transpile separately, etc.).

Installing Craco and setting up craco.config.js worked for me.

module.exports = {
  babel: {
    loaderOptions: {
      ignore: ['./node_modules/mapbox-gl/dist/mapbox-gl.js']
    }
  }
};

Same issue here. As a quick workaround I downgraded to v5.2.11 of react-map-gl:

yarn upgrade react-map-gl@5.2.11 and it works.

this works for me

Downgrading to v5.2.11 of react-map-gl was insufficient for my use case since I'm using Mapbox GL JS v2.x.x features (setTerrain() specifically)

For those out there in a similar spot, I was able to hack around things for the time being by adapting the suggestions in mapbox/mapbox-gl-js#10173:

Install worker-loader:

yarn add worker-loader

In your map component:

import ReactMapGL from "react-map-gl";
import mapboxgl from "mapbox-gl"; // This is a dependency of react-map-gl even if you didn't explicitly install it

// eslint-disable-next-line import/no-webpack-loader-syntax
mapboxgl.workerClass = require("worker-loader!mapbox-gl/dist/mapbox-gl-csp-worker").default;

I hope the Mapbox team can provide a long term solution soon.

This mapboxgl.workerClasss line should be added in which file ... am getting confused please help

Edited ... Figured it out and Thanks a ton for this solution and yeah Really Hope Mapbox comes with a permanent solution for this ... Again Thanks alot bro!

Took hours to find this but finally
downgrading react-mp-gl to version: 5.2.11
and installing worker-loader helped me .

import mapboxgl from "mapbox-gl"; // This is a dependency of react-map-gl even if you didn't explicitly install it
// eslint-disable-next-line import/no-webpack-loader-syntax
mapboxgl.workerClass = require("worker-loader!mapbox-gl/dist/mapbox-gl-csp-worker").default;

Thanks everyone

e11en commented

Is there an actual fix available yet? I really want to use the 6.x.x version but none of the solutions are working in my app.

@e11en In case it is not clear from the above comments, this is not something we can fix in react-map-gl. It is a decision made by the upstream mapbox-gl, and despite our pushback, they think the current solutions are sufficient. If you do not like where this has landed, I encourage you to have a discussion with Mapbox in their repo.

sloev commented

Is there an actual fix available yet? I really want to use the 6.x.x version but none of the solutions are working in my app.

@e11en i am running "react-map-gl": "^6.1.16" and got it working after ejecting my react app (after hundreds of fruitless attempts at not ejecting and fixing)

here is what i did:

  1. add these to dependencies:
    "worker-loader": "^3.0.8",
    "react-map-gl": "^6.1.16",
  1. eject react app: $ npm run eject
  2. edit /config/webpack.config.js like so: (about line 206 or something...)
output: {
      // The build folder.
      path: isEnvProduction ? paths.appBuild : undefined,
      // Add /* filename */ comments to generated require()s in the output.
      pathinfo: isEnvDevelopment,
      // There will be one main bundle, and one file per asynchronous chunk.
      // In development, it does not produce real files.
      filename: isEnvProduction
        ? 'static/js/[name].[contenthash:8].js'
-        : isEnvDevelopment && 'static/js/bundle.js',
+       : isEnvDevelopment && 'static/js/[name].bundle.js',

      // TODO: remove this when upgrading to webpack 5
      futureEmitAssets: true,
      // There are also additional JS chunk files if you use code splitting.
      chunkFilename: isEnvProduction
        ? 'static/js/[name].[contenthash:8].chunk.js'
        : isEnvDevelopment && 'static/js/[name].chunk.js',
  1. add to top of index.js
import ReactMapGL from 'react-map-gl';
ReactMapGL;
import mapboxgl from 'mapbox-gl'; // This is a dependency of react-map-gl even if you didn't explicitly install it
mapboxgl.workerClass =
  require('worker-loader!mapbox-gl/dist/mapbox-gl-csp-worker').default;
  import 'mapbox-gl/dist/mapbox-gl.css';
  1. (optional) everywhere else you need to create a new webworker use this:
import Worker from 'worker-loader!./_main.worker';

with exmple worker _main.worker.js being allowed to use modules for example

import db from '../db';
onmessage = function (event) {
  postMessage("lol")
}

If anyone is still having issues with this, I was able to make it work by following the guide here https://docs.mapbox.com/mapbox-gl-js/guides/install/#transpiling. Simply add a line to your package.json file under browserlist and you're good to go.

"browserslist": {
"production": [
">0.2%, not dead, not ie 11, not chrome < 51, not safari < 10",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},

// eslint-disable-next-line import/no-webpack-loader-syntax
mapboxgl.workerClass = require("worker-loader!mapbox-gl/dist/mapbox-gl-csp-worker").default;

Thanks so much for this. I'd tried a few other solutions and wasn't sure what do try next!

mapbox-gl

Is it for production fixes also because i tried and it is working fine on development mode..

Can we use this version on prod as well..

Update: There was a fix on Nextjs, but still in canary branch.


vercel/next.js#30237 (comment)

Is there any elegant solution for that (react-scripts)?

downgrade to version @5.2.11 and it will be ok

Hi there, I'm writing from 2022 and downgrading did the trick for me.

sloev commented

hi, i still recommend ejecting from create-react-app and specifying the webpack config like in my previous comment, it means i can upload as i find fit.
(#1266 (comment))

Had the same problem using react-map-gl together with maplibre. I could manage to fix it by using craco (https://github.com/gsoft-inc/craco). Here is my craco.config.js:

const CracoWorkboxPlugin = require('craco-workbox');

module.exports = {
  babel: {
    loaderOptions: {
      // this option lets us display the map-pin marker layer - without this it does not work: https://github.com/visgl/react-map-gl/issues/1266
      ignore: ['./node_modules/maplibre-gl/dist/maplibre-gl.js']
    }
  },
  plugins: [{
    plugin: CracoWorkboxPlugin
  }],
  webpack: {
    alias: {
      'mapbox-gl': 'maplibre-gl',
    },

  },
};

Hope this helps someone.

Speaking from 2022 as well - after trying many things, this is the comment to follow for a direct few line fix on a create react-app without having to eject

#1266 (comment)

does this still not work, tried #1266 (comment) but i get an error with typescript and does not work, feels mega hacky -

update this did work just had to add the // @ts-ignore

// @ts-ignore
import mapboxgl from "mapbox-gl";
// @ts-ignore
// eslint-disable-next-line import/no-webpack-loader-syntax
mapboxgl.workerClass =
  require("worker-loader!mapbox-gl/dist/mapbox-gl-csp-worker").default; /* eslint import/no-webpack-loader-syntax: off */

thanks everyone for figuring it out

December 2022 I am facing this issue in production only.

Throws this error
errro

 "Mapbox-gl": "^2.9.2",
 "react-map-gl": "^7.0.19",
 "react": "^18.2.0",
 "react-dom": "^18.2.0",

The map is blank
map error

can someone please help, it's killing me.

// eslint-disable-next-line import/no-webpack-loader-syntax
mapboxgl.workerClass = require("worker-loader!mapbox-gl/dist/mapbox-gl-csp-worker").default;

throws Do not use import syntax to configure webpack loaders in react

December 2022 I am facing this issue in production only.

Throws this error errro

 "Mapbox-gl": "^2.9.2",
 "react-map-gl": "^7.0.19",
 "react": "^18.2.0",
 "react-dom": "^18.2.0",

The map is blank map error

can someone please help, it's killing me.

can anyone please help?

@emekaokoli, I have similar issue with maplibregl after building production build.
Map does not display any vector layer (except hill-shading raster layer which displays OK).
I found out that changing browserlist in package.json from

[">0.2%", "not dead", "not op_mini all"]

to

["last 1 firefox version", "last 1 chrome version"]

solves the issue, but obviously it's not suitable for production.
I did not find a "golden mean" yet for browserslist, if anyone knows, please share.

December 2022 I am facing this issue in production only.
Throws this error errro

 "Mapbox-gl": "^2.9.2",
 "react-map-gl": "^7.0.19",
 "react": "^18.2.0",
 "react-dom": "^18.2.0",

The map is blank map error
can someone please help, it's killing me.

can anyone please help?

solved: https://docs.mapbox.com/mapbox-gl-js/guides/install/#transpiling

While i could fix the initial error by using the worker-loader solution provided and the map tiles now loading, i still get errors.

The Map and tiles are loading, but city names f.e. will not show up. It works locally, so only on a production build this fails.

Javascript console error from the mapbox worker file is Error: "a" is read-only.

Any ideas how to fix this?

Edit:

I've digged a little deeper. So while this works

// @ts-ignore
import mapboxgl from 'mapbox-gl/dist/mapbox-gl-csp'
// @ts-ignore
// eslint-disable-next-line import/no-webpack-loader-syntax, import/no-unresolved
import MapboxWorker from 'worker-loader!mapbox-gl/dist/mapbox-gl-csp-worker'
mapboxgl.workerClass = MapboxWorker

As soon as i use any mapboxgl related import it fails again. For example i'm doing some pan and zooming depending on boundaries and calculate them using LngLatBounds.

But when using the above technic it fails, both locally and in production

// @ts-ignore
import mapboxgl, { LngLatBounds } from 'mapbox-gl/dist/mapbox-gl-csp'
// @ts-ignore
// eslint-disable-next-line import/no-webpack-loader-syntax, import/no-unresolved
import MapboxWorker from 'worker-loader!mapbox-gl/dist/mapbox-gl-csp-worker'
mapboxgl.workerClass = MapboxWorker

While developing locally everything worked, using default imports.

import { LngLatBounds } from 'mapbox-gl'

// pseudo Code for reference

const fitMap = () => {
	// ...
	const bounds = new LngLatBounds(
		{
			lng: points[0][0],
			lat: points[0][1],
		},
		{
			lng: points[0][0],
			lat: points[0][1],
		},
	)
	for (const point of points) {
		bounds.extend([point[0], point[1]])
	}
	map.fitBounds(bounds, { padding: 30, maxZoom: 9 })
}

any ideas what causes this?

downgrade to version @5.2.11 and it will be ok

INSANE WOKS ! THANKS , THIS MAN IS SO GOOD

Hey! I hosted my app on Netlify and was getting similar problems. The below steps fixed my issues:

  1. Exclude Mapbox GL JS from transpilation: You can exclude Mapbox GL JS from transpilation by adding an .env file in the root of your project with the following line:
    SKIP_PREFLIGHT_CHECK=true

  2. Target transpilation to ES6 with browserslist: You can target transpilation to ES6 by adding the following browserslist configuration to your package.json file:

"browserslist": {
  "production": [
    ">0.2%",
    "not dead",
    "not op_mini all",
    "not safari < 10",
    "not chrome < 51",
    "not android < 5",
    "not ie < 12"
  ],
  "development": [
    "last 1 chrome version",
    "last 1 firefox version",
    "last 1 safari version"
  ]
}