react-map-gl icon indicating copy to clipboard operation
react-map-gl copied to clipboard

mapbox-gl production build error "x is not defined"

Open testower opened this issue 4 years ago • 50 comments
trafficstars

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 :/

testower avatar Dec 18 '20 09:12 testower

Do you see any error in the console? Might be caused by https://github.com/mapbox/mapbox-gl-js/issues/10173

Pessimistress avatar Dec 18 '20 15:12 Pessimistress

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

testower avatar Dec 21 '20 09:12 testower

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

Velidoss avatar Dec 24 '20 07:12 Velidoss

@Velidoss please visit the Mapbox issue I linked above. The bug is in [email protected]. There is a temporary work around by adding additional bundler settings.

Pessimistress avatar Dec 24 '20 08:12 Pessimistress

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

yarn upgrade [email protected] and it works.

sgup avatar Dec 24 '20 23:12 sgup

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.

zanemountcastle avatar Jan 03 '21 22:01 zanemountcastle

Having the same issue

robinjhuang avatar Jan 08 '21 05:01 robinjhuang

Having the same issue

use the above work around for mapbox worker class it works gr8 for now 👍

aditbharadwaj avatar Jan 08 '21 05:01 aditbharadwaj

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;

marc-slingshot avatar Jan 11 '21 18:01 marc-slingshot

Could someone explain why this works?

jiaranda avatar Jan 15 '21 14:01 jiaranda

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

Pessimistress avatar Jan 29 '21 20:01 Pessimistress

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 avatar Feb 01 '21 20:02 JG145

@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;

kentongray avatar Feb 01 '21 20:02 kentongray

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'.

JG145 avatar Feb 01 '21 20:02 JG145

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.

vehere-ccuMaksym avatar Feb 06 '21 16:02 vehere-ccuMaksym

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.

Antje3 avatar Feb 11 '21 08:02 Antje3

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

DavideVito avatar Feb 28 '21 19:02 DavideVito

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

Is the recommendation to do this: https://github.com/mapbox/mapbox-gl-js/issues/10173#issuecomment-792053551

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

achen187 avatar May 07 '21 18:05 achen187

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'],
    },
  },
}

Kontenty avatar May 10 '21 14:05 Kontenty

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.

Fredrikwide avatar May 13 '21 11:05 Fredrikwide

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...

DanielJackson-Oslo avatar May 22 '21 20:05 DanielJackson-Oslo

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
    },
  }

DanielJackson-Oslo avatar May 23 '21 05:05 DanielJackson-Oslo

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,
              },
            },

kg-currenxie avatar May 29 '21 10:05 kg-currenxie

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']
    }
  }
};

dhruvikn avatar Jul 03 '21 19:07 dhruvikn

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

yarn upgrade [email protected] and it works.

this works for me

horix7 avatar Aug 21 '21 09:08 horix7

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!

Jayanth9710 avatar Sep 08 '21 06:09 Jayanth9710

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

sandesh-08 avatar Sep 13 '21 06:09 sandesh-08

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 avatar Sep 23 '21 15:09 e11en

@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.

Pessimistress avatar Sep 23 '21 17:09 Pessimistress

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")
}

sloev avatar Sep 24 '21 06:09 sloev