Skip to content
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

Unable to use react-map-gl in create-react-app #176

Closed
goatyeahh opened this issue Jan 10, 2017 · 21 comments
Closed

Unable to use react-map-gl in create-react-app #176

goatyeahh opened this issue Jan 10, 2017 · 21 comments

Comments

@goatyeahh
Copy link

Did someone manage to make it work in create-react-app ?

I got this error:

index.js:9Uncaught TypeError: Cannot convert undefined or null to object
    at Function.keys (<anonymous>)
    at new module.exports (index.js:9)
    at Object.<anonymous> (web_worker.js:5)
    at __webpack_require__ (bootstrap 6c4040e…:555)
    at fn (bootstrap 6c4040e…:86)
    at Object.<anonymous> (worker_pool.js:4)
    at __webpack_require__ (bootstrap 6c4040e…:555)
    at fn (bootstrap 6c4040e…:86)
    at Object.<anonymous> (global_worker_pool.js:2)
    at __webpack_require__ (bootstrap 6c4040e…:555)

My component is quite simple

import React from 'react';
import MapGL from 'react-map-gl';
#
const MAPBOX_TOKEN = 'xxxx';

export function Map() {
  return (
    <div>
      <MapGL
        width={400}
        height={400}
        latitude={37.7577}
        longitude={-122.4376}
        zoom={8}
        mapboxApiAccessToken={MAPBOX_TOKEN}
        onChangeViewport={ (viewport) => {
          const { latitude, longitude, zoom } = viewport;
          // Optionally call `setState` and use the state to update the map.
        }}
      />
    </div>
  );
}

Thank you in advance for taking interest in this issue.

@ibgreen
Copy link
Contributor

ibgreen commented Jan 10, 2017

Looks like a webpack config issue. Take a look at the instructions in our README

@goatyeahh
Copy link
Author

Yes indeed and I was wondering if there was a way to import react-map-gl without editing webpack config since create-react-app does the webpack dirty work for you but it seems that there aren't any other way than running npm run eject and follow deck.gl webpack example.

I think the issue comes from the fact that mapbox-gl is not directly compatible with webpack. I managed to make your code work in create-react-app without ejecting by doing a small hack described here:

import mapboxgl from 'mapbox-gl/dist/mapbox-gl'

but I don't think it is a good solution...

Anyway, thank you for your quick reply!

@ghost
Copy link

ghost commented Feb 12, 2017

@gauthierrodaro which files did you patch?

@goatyeahh
Copy link
Author

@fb-owen-vandijk, Here is a zip of the patch I did.

As you can see it was patched from an older version of the repo. It was only intended for testing purposes and I would not recommend this.

map-gl.zip

@ghost
Copy link

ghost commented Feb 16, 2017

@gauthierrodaro thanks! very helpful.

In the end I decided to go with https://github.com/alex3165/react-mapbox-gl which I believe has the same workaround implemented.

@stereobooster
Copy link

stereobooster commented Apr 30, 2017

From other issue

The issue about create-app can't be done without adding what's necessary in the webpack configuration and that have been documented. The error is coming from our mapbox dependency anyway, so there isn't much we can do at this level.
@apercu

I created empty project with create-react-app. When I do

import MapGL from 'react-map-gl'

I see in browser console Uncaught SyntaxError: Unexpected token import. But when I do:

import mapboxgl from 'mapbox-gl';

I see warning Critical dependencies: 1:481-488 This seems to be a pre-built javascript file. Though this is possible, it's not recommended. Try to require the original source to get better results. @ ./~/mapbox-gl/dist/mapbox-gl.js 1:481-488, but no errors

Related: mapbox/mapbox-gl-js#1649

@stereobooster
Copy link

Realised that current master is 3.0.0.alpha5. While npm version is 1.8... something. Hate when this happens.

Installed github versions with:

yarn add https://github.com/uber/react-map-gl.git
cd node_modules/react-map-gl
yarn
npm run build-es5
npm run build-es6

Now if I do import MapGL from 'react-map-gl/dist/index.js' I get Uncaught SyntaxError: Identifier 'Buffer' has already been declared

If I do import MapGL from 'react-map-gl/dist-es6/index.js' I get Uncaught SyntaxError: Unexpected token export.

@ibgreen
Copy link
Contributor

ibgreen commented May 1, 2017

@stereobooster

Realised that current master is 3.0.0.alpha5. While npm version is 1.8... something. Hate when this happens.

Per npm info latest official version is 2.0.2. There was however a patch to v1 (1.8.2) published after that. Sounds like you did a yarn or npm install and it picked the 1.8.2 (because it was the latest release non-beta-tagged release, even though it doesn't have the highest version number?).

Apologies for this, not quite sure why this happens (but not totally surprised, have seen similar surprises from npm and yarn in the past). Maybe the easiest thing is just to publish a dummy 2.0.3 (@abmai).

     $ npm info react-map-gl
     ...
     '1.8.0': '2017-01-14T00:01:03.780Z',
     '2.0.0': '2017-01-17T21:56:53.658Z',
     '1.8.1': '2017-01-24T18:24:20.770Z',
     '2.0.1': '2017-01-24T19:59:16.514Z',
     '2.0.2': '2017-02-10T02:00:00.595Z',
     '3.0.0-alpha.1': '2017-03-10T00:53:59.320Z',
     '1.8.2': '2017-03-15T21:40:42.492Z',
     '3.0.0-alpha.2': '2017-03-23T20:15:08.730Z',
     '3.0.0-alpha.3': '2017-03-27T23:01:30.344Z',
     '3.0.0-alpha.4': '2017-03-27T23:38:17.188Z',
     '3.0.0-alpha.5': '2017-03-29T23:56:32.428Z' },

@ibgreen
Copy link
Contributor

ibgreen commented May 1, 2017

@stereobooster

Now if I do import MapGL from 'react-map-gl/dist/index.js' I get Uncaught SyntaxError: Identifier 'Buffer' has already been declared

This sounds strange, never saw this. does this happen if react-map-gl is the only thing you include? Can you inspect your generated bundle and search for Buffer and see if you can find anything?

If I do import MapGL from 'react-map-gl/dist-es6/index.js' I get Uncaught SyntaxError: Unexpected token export.

That's expected. In react-map-gl v3, the dist-es6 folder has been added to support "tree-shaking" (removal of unused code from the final bundle). It should only be used by tree shaking bundlers, e.g. webpack2 and rollup. There are separate entry points specified in package.json to support autodetection of dist folder, you should not need to import a specific dist folder like this.

@stereobooster
Copy link

stereobooster commented May 1, 2017

This sounds strange, never saw this. does this happen if react-map-gl is the only thing you include? Can you inspect your generated bundle and search for Buffer and see if you can find anything?

Yes react-map-gl is the only thing that I include. Here is example code https://github.com/stereobooster/create-react-app-map-gl (change import MapGL from 'react-map-gl/dist-es6/index.js' to dist/index.js)

It should only be used by tree shaking bundlers, e.g. webpack2 and rollup

I switched to webpack 2. Here is example code https://github.com/stereobooster/create-react-app-map-gl/tree/webpack-2

Now I get:

Uncaught TypeError: Cannot convert undefined or null to object
    at Function.keys (<anonymous>)
    at new module.exports (index.js:9) // node_modules/react-map-gl/node_modules/webworkify/index.js

Which is:

var bundleFn = arguments[3];
var sources = arguments[4];
var cache = arguments[5];

var stringify = JSON.stringify;

module.exports = function (fn, options) {
    var wkey;
    var cacheKeys = Object.keys(cache);

@stereobooster
Copy link

stereobooster commented May 1, 2017

For webpack 2 and react-map-gl 2: https://github.com/stereobooster/create-react-app-map-gl/tree/react-map-gl-2

Uncaught Error: Module parse failed: node_modules/react-map-gl/node_modules/mapbox-gl/js/util/util.js Unexpected token (15:35)
You may need an appropriate loader to handle this file type.
|  * @private
|  */
| exports.easeCubicInOut = function(t: number): number {
|     if (t <= 0) return 0;
|     if (t >= 1) return 1;

And this is bug from Mapbox GL JS, which does not provide ES6 modules with flow-types stripped. Created ticket mapbox/mapbox-gl-js#4664

@ibgreen
Copy link
Contributor

ibgreen commented May 1, 2017

@stereobooster

And this is bug from Mapbox GL JS, which does not provide ES6 modules with flow-types stripped. Created ticket mapbox/mapbox-gl-js#4664

Correct, this has been a big headache for react-map-gl from mapbox ~0.26 forward. In fairness to mapbox, this is mainly a problem because react-map-gl v2 uses the internal mapbox Transform class (which is not exported in mapbox's pre-built file for non-browserify bundlers).

There is a postinstall script in react-map-gl v2 to remove flow-types from the mapbox installation, it is slightly sensitive to the relative path of mapbox in node-modules. If this doesn't get run automatically in your install scenario you can always go into node_module/react-map-gl and try to run it manually.

In react-map-gl v3 we were finally able to remove dependencies on internal mapbox files so mapbox's provided pre-built is now sufficient. (Unfortunately it still requires special webpack configuration since mapbox's package.json doesn't set the "main" entry to their pre-built).

Sorry you have to get exposed to all this, one of our goals with react-map-gl v3 is to minimize these complications for new users.

@ibgreen
Copy link
Contributor

ibgreen commented May 1, 2017

@stereobooster

I switched to webpack 2. Here is example code https://github.com/stereobooster/create-react-app-map-gl/tree/webpack-2

Where are you using webpack 2 here? I see no mention of webpack. Did you push your changes?

  • Are you able to run our stand-alone examples in examples/? They contain the necessary webpack settings you need.

  • You will need to be able to inject the mapbox alias to their pre-built into the webpack config. I checked your app and you do not have any such webpack settings.

  • I took a quick look at create-react-app. Looks nice, but unfortunately, I can't see a way to get at the webpack config. I do find this ominous statement... "You don’t need to install or configure tools like Webpack or Babel. They are preconfigured and hidden so that you can focus on the code."

  • Interestingly, mapbox no longer seems to mention webpack or their prebuilt in their README. We should check their latest version to see if anything has changed in their webpack support (couldn't see anything significant in their CHANGELOG).

@abmai @apercu.

@stereobooster
Copy link

stereobooster commented May 1, 2017

Where are you using webpack 2 here? I see no mention of webpack. Did you push your changes?

From yarn.lock

webpack "2.2.1"

I took a quick look at create-react-app. Looks nice, but unfortunately, I can't see a way to get at the webpack config.

Exactly. This is the best part about create-react-app. It just works. And I do not believe, that there is no way to publish packages that are compatible with CRA. CRA is so good that I use it for projects without React (simply delete React dependencies). This is a breath of fresh air since Rails with it's "convention over configuration"

@stereobooster
Copy link

stereobooster commented May 1, 2017

Connecting dots: mapbox-gl-js will not provide ES6 module until it will not be able to switch to rollup, and it can not switch to rollup because there is no alternative for webworkify. rollup/rollup#1029. See also rollup/rollup#1320

UPD: Other way to do this would be to switch from inline-blob workers to separate file, but this is not supported by CRA at the moment facebook/create-react-app#1277

UPD2: URL.createObjectURL not implemented in jsdom which prevents mapbox-gl to be rendered on server side with react-snapshot. This bug affects even alex3165/react-mapbox-gl/, which works with CRA out of the box.

@gaving
Copy link

gaving commented Nov 22, 2017

@stereobooster Thanks for that interesting analysis!

I've came back to looking at using react-map-gl a year on, back when I had all sorts of issues with webpack. I was semi-hopeful that this would have played nice with create-react-app by now but see it's a lot more complicated than that! 🤕 🔫

@stereobooster
Copy link

stereobooster commented Mar 12, 2018

Update: MapboxGL now uses ES6 modules mapbox/mapbox-gl-js#6196

@rlueder
Copy link

rlueder commented Apr 28, 2018

For those tracking this issue for the past few months like me, @stereobooster 's comment means react-map-gl now works with CRA without the need to eject. I just tested it with a basic CRA app and one of the examples for react-map-gl 👍 💯

@linonetwo
Copy link

linonetwo commented Jun 22, 2018

I've added this to config-overrides.js

  config.resolve = {
    alias: {
      'mapbox-gl$': path.join(resolveApp('node_modules'), '/mapbox-gl/dist/mapbox-gl.js'),
    },
  };

It works in development elements all show up properly. But after build, there still being Uncaught ReferenceError: s is not defined or Uncaught ReferenceError: u is not defined.
And elements in the map won't show up, see console of my site.

@zackhsi
Copy link
Contributor

zackhsi commented Jul 10, 2018

I have opened a PR documenting a working integration with a Typescript CRA.

@dalipkumar703
Copy link

For those tracking this issue for the past few months like me, @stereobooster 's comment means react-map-gl now works with CRA without the need to eject. I just tested it with a basic CRA app and one of the examples for react-map-gl 👍 💯

Can you share example with CRA ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants