mapbox / mapbox-gl-js

Interactive, thoroughly customizable maps in the browser, powered by vector tiles and WebGL
https://docs.mapbox.com/mapbox-gl-js/
Other
11.06k stars 2.21k forks source link

Uncaught ReferenceError: _createClass is not defined (after transpiling with Babel) #10173

Closed antoinealej closed 3 years ago

antoinealej commented 3 years ago

--- πŸ”΄ EDIT from a gl-js maintainer πŸ”΄ ---- We've just opened #10565 do go over some of the decisions of why we moved to ES6, and also summarizing the solutions that everyone has contributed in this thread. Would love for the discussion to be continued there. πŸ™‡πŸ½ --- πŸ”΄ END EDITπŸ”΄-----

mapbox-gl-js version: 2.0.0

browser: Google Chrome Version 87.0.4280.67 (Official Build) (x86_64)

Steps to Trigger Behaviour

I'm trying to build a library of Vue components and one component uses mapbox-gl. I created a test project to showcase the issue.

  1. Create a Vue library (vue create library)
  2. Add mapbox-gl to the library in a component
  3. Build the library
  4. Use the library in a Vue application

When I build and use it I have an error message saying:

Uncaught ReferenceError: _createClass is not defined

Link to Demonstration

https://gitlab.com/antoinealej/test-lib-mapbox-gl-build

Expected Behaviour

Display the map over a beige background

Actual Behaviour

Only displays the beige background container

mtuanp commented 3 years ago

You can exclude mapbox-gl from being transpiled with CRACO. It works with react-mapbox-gl + react + TS.

craco.config.js

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

Source: https://docs.mapbox.com/mapbox-gl-js/api/#transpiling-v2

arindam1993 commented 3 years ago

@Pessimistress even if we were to provide an ES5 bundle wouldn't there be some implementation work in react-map-gl to redirect the imports to the appropriate bundle based on build target. In that case can the import be redirected to use the mapboxgl.workerClass hook for ES5 builds?

The reason I'm pushing back against this is because with v2, GL-JS is only intended to be used with modern browsers( hence the dropping of IE11 support). So supplying an ES5 bundle just for the sake of bundler and build system compatibility instead of functionality seems very redundant.

Pessimistress commented 3 years ago

@arindam1993

can the import be redirected to use the mapboxgl.workerClass hook for ES5 builds?

A key difference between react-map-gl and mapbox-gl is that it does not distribute its own pre-built bundle. Anyone using the wrapper can choose to use it with any compatible mapbox-gl version. By hard-coding the workerClass hook, every user will be required to install worker-loader to be able to build their apps at all. How does that make the current situation better?

arindam1993 commented 3 years ago

Of course, a few extra hoops would be required for anyone who wants transpilation, but most people shouldn't (for performance reasons) and probably don't need to transpile down all the way to support IE11/chrome 49. JS and WebGL performance on those older browsers is unacceptable anyways.

Most users should be able to go in this order:

  1. Update browserlist in package.json to modern-ish levels (perf boost, smaller bundle sizes and faster load times as a bonus)
  2. If 1 doesnt work bcoz some legacy sections of the app or certain dependencies need ES5 transpilation, explicit exclusions can be configured via CRACO or webpack.config.js
  3. If 2. doesnt work bcoz the user really needs a dynamic WebGL map to work in IE11 class browsers then they can setup the workerClass hook to allow for transpilation.

Intuitively 1. should be the largest chunk of users, 2 covers few more users with older projects that may have legacy chunks, and 3 should be the smallest minority.

Again I want to reiterate that the reason I'm pushing back is that while an ES5 bundle would provide compatibility with current default bundler configs, it comes at the cost of performance, longer load times and larger bundle sizes. Most users don't need to pay those costs since they aren't really targeting those environments.

BenElferink commented 3 years ago

So in other words for create-react-app peeps, change import mapboxgl from "mapbox-gl"; to // eslint-disable-next-line import/no-webpack-loader-syntax import mapboxgl from "!mapbox-gl"; Remember to do it in all places where you import mapbox-gl or your bundle size will go up by about a meg. Note, this also solved an issue I was having with qr-scanner (https://github.com/nimiq/qr-scanner)

That did not work for me.

Below is what worked for me :

import ReactMapGL, {Marker} from 'react-map-gl' import 'mapbox-gl/dist/mapbox-gl.css'; import mapboxgl from 'mapbox-gl';

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

....

Also , remember to npm install worker-loader

This worked for me. USING the newest versions of react-map-gl && mapbox-gl. I must mention this worked for a production build on AWS Amplify.

dhruv10 commented 3 years ago

None of the above solutions are working when the app runs locally!

I’m using react-map-gl in Fuse.js (wrapper based on CRA) and we want to include three different map styles. If the map style is set to satellite then it gets rendered properly otherwise in any other style like light, landscape, etc. only the background color of the map is shown and I get Uncaught ReferenceError: _createClass is not defined error in console.

I get this error when I run the app locally. The solutions given here are for production builds but I still tried them all. However, nothing worked for me. I tried @arindam1993's solution, @mtuanp's solution and @belferink1996's solution. Can someone please guide me?

I’m using Mac OS v10.15.7 and relevant package versions are: react-map-gl: 6.1.10 mapbox-gl: 1.8.1 node: >=10.19.0

image

bmg817 commented 3 years ago

@dhruv10 it looks like you tried a subset of solutions from the ones you've listed. Try this one (which is just a variation of this solution by @zacharyliu). See if it works for you.

mtuanp commented 3 years ago

Hi @dhruv10, Have tried downgrade react-map-gl to the latest 5 version https://github.com/visgl/react-map-gl/releases/tag/v5.3.10. Because the version 6 is only supported with mapbox-gl >=2, as I know.

dhruv10 commented 3 years ago

Aha, the main issue was the version incompatibility between react-map-gl and mapbox-gl as pointed out by @mtuanp in

Hi @dhruv10, Have tried downgrade react-map-gl to the latest 5 version https://github.com/visgl/react-map-gl/releases/tag/v5.3.10. Because the version 6 is only supported with mapbox-gl >=2, as I know.

After doing this, both the solutions (given by @bmg817 and @arindam1993) were working. I even tried after upgrading both dependencies to the latest version. Finally, this is what I'm using now:

"react-map-gl": "6.1.10"
"mapbox-gl": "2.1.1"
"node": ">=10.19.0"

Thank you all :)

Sillyvan commented 3 years ago

After a bunch of digging into various options, including providing a ES5 build here

It seems all it serves to do is revive an old error #3422, most create-react-app users never saw this error because it has an explicit exclusion in its Babel presets for that particular transform. https://github.com/facebook/create-react-app/blob/3c02ca74f9eb099e4d5eed3f646bfad118da635b/packages/babel-preset-react-app/create.js#L87

So I think the easiest, also most performant solution for create-react-app users would be to update browserlists in package.json to exclude older browsers

browserslist: [
      ">0.2%",
      "not ie 11",
      "not dead",
      "not chrome 49"
    ]

And if you really need transpilation for your project to force support for IE11 and old versions of chrome then the using the workerClass hook as @bmg817 pointed out is the way to go.

this one is sadly not working for me. not sure why tho. Im using CRA and just the vanilla mapbox-gl not the react wrapper,

any idea where the problem could be? my application seems to be the same after chaning the browserslist but the map still dosent work. is there anything else i would've to do for this to work?

the other 2 solutions worked for me. but i wouldnt mind cleaner fix

brdv commented 3 years ago

Hi everyone, After I ran into this issue a couple of months ago, we've decided to keep mapbox-gl at 1.13.0 for now (this worked fine, except tests). I've been trying for a couple of hours now to get it working (build without reference-error and working tests), but haven't been able to. Our problem is that when we are able to build the tests are complaining about the workaround > "Cannot find module worker-loader!..." and when we comment this out, we get the map.on is not a function. (Yes, we've tried this fix).

So I'm wondering if the Mapbox team has an idea how to solve these issues, but even more, I'm curious to whether there will be an actual fix that's not a workaround?

If anyone got mapbox' latest version working combined with CRA, without rewired, meaning that both build and testing succeeds I would be very interested in an example repo they might want to share?

Please let me know as I'm very curious what I'm doing wrong!

IvanDreamer commented 3 years ago

You can exclude mapbox-gl from being transpiled with CRACO. It works with react-mapbox-gl + react + TS.

craco.config.js

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

Source: https://docs.mapbox.com/mapbox-gl-js/api/#transpiling-v2

I have Rails 6 + webpack + mapbox-gl. I had same issue and simple code solution from docs helped to exclude the lib.

import mapboxgl from '!mapbox-gl';

ghost commented 3 years ago

@IvanDreamer Thanks, this is the easier solution if you're working with Weback. https://docs.mapbox.com/mapbox-gl-js/api/#transpiling-v2

zacharyliu commented 3 years ago

The browserslist approach works well for me in create-react-app with some tweaks.

  1. Add these two lines to the browserslist section in package.json:

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

    (The full section might look different depending on your config and create-react-app version.)

  2. rm -rf node_modules/.cache to clear the Babel cache (mentioned in https://create-react-app.dev/docs/supported-browsers-features/)

According to caniuse, Chrome 51 and Safari 10 were the first versions of those browsers to have full ES6 support. Different versions of the caniuse-lite db include different versions of these browsers as having >0.2% usage, which is why https://github.com/mapbox/mapbox-gl-js/issues/10173#issuecomment-793179698 may not always work. This config should cover all the cases.

arindam1993 commented 3 years ago

@zacharyliu Thanks thats very helpful πŸ™‡πŸ½ , we'll update our docs to reflect that

OleksandrYatsiuk commented 3 years ago

Got this problem with Angular v.11 project.

  "mapbox-gl": "^2.2.0"

Change target from es5 to es2015 helps for me.

file: tsconfig.json

compilerOptions: {
   ...
   target: "es2015"
   ...
}
arindam1993 commented 3 years ago

Hey everyone, since this issue is getting a bit noisy we just opened a new one https://github.com/mapbox/mapbox-gl-js/issues/10565

We've gone into a bit more detail on the why's of deciding to move to ES6. We also wanted to be able use that issue to coalesce the more detailed solutions that many of you all have contributed in this thread. Closing this one, and hoping we can use that thread to gather up the some of the solutions πŸ™‡πŸ½

cigzigwon commented 3 years ago

@mtuanp exclude !== ignore and there are some issues getting this to work in Gatsby. Anybody using it yet?

nicowernli commented 3 years ago

After a bunch of digging into various options, including providing a ES5 build here It seems all it serves to do is revive an old error #3422, most create-react-app users never saw this error because it has an explicit exclusion in its Babel presets for that particular transform. https://github.com/facebook/create-react-app/blob/3c02ca74f9eb099e4d5eed3f646bfad118da635b/packages/babel-preset-react-app/create.js#L87 So I think the easiest, also most performant solution for create-react-app users would be to update browserlists in package.json to exclude older browsers

browserslist: [
      ">0.2%",
      "not ie 11",
      "not dead",
      "not chrome 49"
    ]

And if you really need transpilation for your project to force support for IE11 and old versions of chrome then the using the workerClass hook as @bmg817 pointed out is the way to go.

this one is sadly not working for me. not sure why tho. Im using CRA and just the vanilla mapbox-gl not the react wrapper,

any idea where the problem could be? my application seems to be the same after chaning the browserslist but the map still dosent work. is there anything else i would've to do for this to work?

the other 2 solutions worked for me. but i wouldnt mind cleaner fix

You should follow this solution https://github.com/mapbox/mapbox-gl-js/issues/10173#issuecomment-793462984

cigzigwon commented 3 years ago

@nicowernli Go here instead as I've outlined everything as a consumer of the lib. Browserlists isn't a solution. see here

tatendabakozw commented 3 years ago

babel: { loaderOptions: { ignore: ['./node_modules/mapbox-gl/dist/mapbox-gl.js'], }, },

this worked for me. thank you

booherbg commented 2 years ago

I have a project that I haven't touched in months. Now when I open the project, I get this error (even though I haven't upgraded or changed anything). I can't figure out why -- maybe because my browser has updated? So far none of the fixes have helped me resolve this issue which is pretty frustrating since this project had a working map but now it does not, even though the project and project dependencies haven't changed.

mychips commented 2 years ago

I had the same problem and I solved using // @ts-ignore before import line, like this: // @ts-ignore import mapboxgl from '!mapbox-gl';

and vuala the map appears.

I hope this works for you

nadun-malinda commented 2 years ago

I'm working on a React project using DeckGL, react-map-gl, and react-vis. Had the same issue and after downgrading react-map-gl to version ^5.3.17, my problem has been solved.

Heshiyu1996 commented 2 years ago

I had the same problem and I solved using // @ts-ignore before import line, like this: // @ts-ignore import mapboxgl from '!mapbox-gl';

and vuala the map appears.

I hope this works for you

It works for me, Thanks!!!

By the way, The above setting which changes the workerClass is not working well for me, and the console display:

UnhandledPromiseRejectionWarning: TypeError: The 'compilation' argument must be an instance of Compilation

I guess it is related to the version of webpack.

saifali-95 commented 2 years ago

Hi @dhruv10, Have tried downgrade react-map-gl to the latest 5 version https://github.com/visgl/react-map-gl/releases/tag/v5.3.10. Because the version 6 is only supported with mapbox-gl >=2, as I know.

Downgrading react-map-gl to version 5.3.10 solved my problem. Thanks

emekaokoli commented 1 year ago

Heads up that so far we've landed #10219 to make it easier to fix (will be included in the v2.0.1 patch release), and are also adding a docs section on transpilation issues: https://github.com/mapbox/mapbox-gl-js-docs/pull/461

this link appears to be dead, can you share a working link please?

emekaokoli commented 1 year ago

Please is there any fix on this for create react app? none of the suggestions above worked for me, I am way behind in my project because of this. I am very frustrated about this.

sypyyy commented 1 year ago

For anyone who is still struggling with this in a create-react-app environment. My solution was to fix all the warnings related to maplibre thrown by npm start. I tried with all the solutions above and none of them works for me. And just when all hope seem lost, I tried to fix the compile warnings thrown and it worked!!!!!!!!!!!!!!!!!!!!!!

emekaokoli commented 1 year ago

Please can you share how you went about that? Because in my case the map goes blank.

On Wed, 14 Dec 2022 at 2:38 PM, sypyyy @.***> wrote:

For anyone who is still struggling with this in a create-react-app environment. My solution was to fix all the warnings related to maplibre thrown by npm start. I tried with all the solutions above and none of them works for me. And just when all hope seem lost, I tried to fix the compile warnings thrown and it worked!!!!!!!!!!!!!!!!!!!!!!

matthew-mcdermott commented 1 year ago

For anyone who arrives here like I did, I will share what worked for me. I am using DeckGL, maplibregl, CRA, and react-map-gl. This is what worked for me: https://github.com/visgl/react-map-gl/issues/1284 .

Specifically, I added the following to my browserlists configuration in package.json: ">0.2%, not dead, not ie 11, not chrome < 51, not safari < 10, not android < 51"

MoradAbed commented 1 year ago

Solution for this issue that worked for me without changing the browserlists:

In Map.js component:

import { workerClass } from 'mapbox-gl';
import workerLoader from 'worker-loader!mapbox-gl/dist/mapbox-gl-csp-worker';

workerClass = workerLoader;

in eslintrc: "import/no-webpack-loader-syntax": "off", "import/no-unresolved": "off" ,

Hongdeshuai commented 1 year ago

import { workerClass } from 'mapbox-gl'; mapbox-gl@2.13.0 doesn't export workClass

Oli-G33 commented 1 year ago

For anyone who is still struggling with this in a create-react-app environment. My solution was to fix all the warnings related to maplibre thrown by npm start. I tried with all the solutions above and none of them works for me. And just when all hope seem lost, I tried to fix the compile warnings thrown and it worked!!!!!!!!!!!!!!!!!!!!!!

Could you please explain what you mean by this exactly? I'm having the same issue.

emekaokoli commented 1 year ago

Wait, so this is still an issue using Mapbox's current build?

Oli-G33 commented 1 year ago

Solution is here:

https://github.com/maplibre/maplibre-gl-js/discussions/675

This part of your package.json file should look like this:

"browserslist": { "production": [ "defaults", "not ie 11" ],