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.2k stars 2.22k forks source link

Not able to npm install mapbox on AWS EB #4662

Closed mariokam closed 7 years ago

mariokam commented 7 years ago

Having big issue after installing mapbox versions on AWS Elastic Beanstalk. It brokes on mapbox-gl lib. I have tried v0.36.0, v0.35.1, v0.35.0, v34.0 etc... it seems the last update of package.json is broken! The problem is Error: mapbox-gl@0.34.0 postinstall: cd src/style-spec && yarn || npm install

screen shot 2017-04-29 at 15 15 26
jfirebaugh commented 7 years ago

You haven't provided enough of the log for us to diagnose the issue. But beyond that, Mapbox GL JS is a browser (client-side) module. It doesn't really make sense to install it on AWS EB.

mariokam commented 7 years ago

This is really big bullshit what you are saying, since I am using TypeScript on Angular2 and yes I definitely need to install it via npm, not via client js ;-)))

https://www.npmjs.com/package/mapbox-gl

chasebrewsky commented 7 years ago

I have to agree with @mariokam. We package our frontend files using Webpack on the system it's deployed on to prevent committing compiled code to our git repository. This is the only package that has failed to load on our AWS instance which has caused us to push deployment dates back.

I really like this library but we might replace it with something else soon because this is the second issue we've had bundling it with Webpack. This is the error log:

npm WARN deprecated point-geometry@0.0.0: This module has moved: please install @mapbox/point-geometry instead
npm WARN deprecated vector-tile@1.3.0: This module has moved: please install @mapbox/vector-tile instead
npm WARN deprecated geojson-area@0.1.0: This module is now under the @mapbox namespace: install @mapbox/geojson-area instead

> mapbox-gl@0.36.0 postinstall /opt/project/node_modules/mapbox-gl
> cd src/style-spec && yarn || npm install

/usr/lib/node_modules/yarn/node_modules/mkdirp/index.js:90
                    throw err0;
                    ^

Error: EACCES: permission denied, mkdir '/root/.cache/yarn'
    at Object.fs.mkdirSync (fs.js:895:18)
    at Function.sync (/usr/lib/node_modules/yarn/node_modules/mkdirp/index.js:71:13)
    at Object.<anonymous> (/usr/lib/node_modules/yarn/bin/yarn.js:31:8)
    at Module._compile (module.js:571:32)
    at Object.Module._extensions..js (module.js:580:10)
    at Module.load (module.js:488:32)
    at tryModuleLoad (module.js:447:12)
    at Function.Module._load (module.js:439:3)
    at Module.runMain (module.js:605:10)
    at run (bootstrap_node.js:427:7)
npm ERR! Linux 2.6.32-642.6.2.el6.x86_64
npm ERR! argv "/usr/bin/node" "/usr/bin/npm" "install"
npm ERR! node v7.10.0
npm ERR! npm  v4.2.0
npm ERR! path /root/.npm/_logs
npm ERR! code EACCES
npm ERR! errno -13
npm ERR! syscall scandir

npm ERR! Error: EACCES: permission denied, scandir '/root/.npm/_logs'
npm ERR!  { Error: EACCES: permission denied, scandir '/root/.npm/_logs'
npm ERR!   errno: -13,
npm ERR!   code: 'EACCES',
npm ERR!   syscall: 'scandir',
npm ERR!   path: '/root/.npm/_logs' }
npm ERR!
npm ERR! Please try running this command again as root/Administrator.
glob error { Error: EACCES: permission denied, scandir '/root/.npm/_logs'
  errno: -13,
  code: 'EACCES',
  syscall: 'scandir',
  path: '/root/.npm/_logs' }
npm ERR! Linux 2.6.32-642.6.2.el6.x86_64
npm ERR! argv "/usr/bin/node" "/usr/bin/npm" "install"
npm ERR! node v7.10.0
npm ERR! npm  v4.2.0
npm ERR! path /root/.npm/rw/1.3.3/package
npm ERR! code EACCES
npm ERR! errno -13
npm ERR! syscall mkdir

npm ERR! Error: EACCES: permission denied, mkdir '/root/.npm/rw/1.3.3/package'
npm ERR!  { Error: EACCES: permission denied, mkdir '/root/.npm/rw/1.3.3/package'
npm ERR!   errno: -13,
npm ERR!   code: 'EACCES',
npm ERR!   syscall: 'mkdir',
npm ERR!   path: '/root/.npm/rw/1.3.3/package',
npm ERR!   parent: '@mapbox/mapbox-gl-style-spec' }
npm ERR!
npm ERR! Please try running this command again as root/Administrator.

npm ERR! Please include the following file with any support request:
npm ERR!     /root/.npm/_logs/2017-05-25T16_29_28_305Z-debug.log
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@^1.0.0 (node_modules/chokidar/node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.1.1: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})
npm WARN react-datetime@2.8.8 requires a peer of moment@>=2.16.0 but none was installed.
npm WARN cyclops@2.0.1 No repository field.
npm ERR! Linux 2.6.32-642.6.2.el6.x86_64
npm ERR! argv "/usr/bin/node" "/usr/bin/npm" "install"
npm ERR! node v7.10.0
npm ERR! npm  v4.2.0
npm ERR! code ELIFECYCLE
npm ERR! errno 243

npm ERR! mapbox-gl@0.36.0 postinstall: `cd src/style-spec && yarn || npm install`
npm ERR! Exit status 243
npm ERR!
npm ERR! Failed at the mapbox-gl@0.36.0 postinstall script 'cd src/style-spec && yarn || npm install'.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the mapbox-gl package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     cd src/style-spec && yarn || npm install
npm ERR! You can get information on how to open an issue for this project with:
npm ERR!     npm bugs mapbox-gl
npm ERR! Or if that isn't available, you can get their info via:
npm ERR!     npm owner ls mapbox-gl
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR!     /root/.npm/_logs/2017-05-25T16_29_31_021Z-debug.log

I'm sudoing the install command already, which possibly means I would have to run the entire install process as the root user. This would explain why it works on our local machines and not on our server. Our sysadmins would not allow us to login as root whenever we need to recompile or deploy, so this wouldn't be a solution.

mariokam commented 7 years ago

I had to hack this doing the following - putting in my package.json the only latest version which works on aws npm install -> mapbox-gl@0.32. Then manually in my webpack bundle I am running npm install mapbox-gl@0.36 and all works fine, since the webpack bundler takes the 0.36 version, but the npm uses 0.32 just to pass further. Its workaround. Hope it will help to someone

chasebrewsky commented 7 years ago

That fix doesn't work anymore because they deprecated/moved a couple of packages from 0.32. I can't even install it onto my local machine anymore using npm.

I also just talked to our sysadmin who let me run the install without any restrictions, and it still failed. I don't know what else to do because I would have to essentially chmod all these different folders to make them less secure just so this postinstall script will run.

chasebrewsky commented 7 years ago

Alright, so I found a fix for those who have stumbled upon this bug and wish for their hair to stay in their heads!

I loaded mapbox through the CDN in the parent HTML template as explained here and then labeled it as an external variable in the webpack configuration. Externals are explained here and your configuration will look a little something like this.

module.exports = {
  ...
  externals: {
    mapboxgl: 'mapboxgl',
  }
};

After that you can reference the variable a couple of different ways:

import mapboxgl from 'mapboxgl'; // ES6 imports
const mapboxgl = require('mapboxgl'); // CommonJS imports
mapboxgl // Global variable 

Hopefully that helps a few people if the proposed solution above does not work for you.

phoenisx commented 7 years ago

@chasepbrewer How are you using Externals, as when I try your method, Webpack gives me an Error: Cannot find module 'mapboxgl', as the actual NPM package name is mapbox-gl.

I have installed the package in npm-module, but externals is taking 'mapboxgl' as library name, how does it check for the library to add as a CDN Link

chasebrewsky commented 7 years ago

@Shub1427 Sorry this took me a couple of days to notice. Luckily I was looking for the post because someone asked me about this and wanted a reference.

When using webpack externals, you don't download the dependency through npm. You inject it into your bundle using the HTML template that uses your bundle. I'll clarify exactly what I did by showing you the pieces of code where I inject and access the variable. I'll also modify the webpack configuration to make it clear what's going on.

Here is the parent template to our web application, where I inject the dependency into the template via CDN:

<!DOCTYPE html>
<html>
    <head>

        ... header content ...

        <script src='https://api.mapbox.com/mapbox-gl-js/v0.38.0/mapbox-gl.js'></script>
        <link href='https://api.mapbox.com/mapbox-gl-js/v0.38.0/mapbox-gl.css' rel='stylesheet' />

        ... header content ...

    </head>
    <body>

        ... body content ...

        <script src="webpack-bundle.js">
    </body>
</html>

This places the variable mapboxgl into the global namespace, so when I configure webpack to do this:

module.exports = {
  ...
  externals: {
    MAPBOXGL: 'mapboxgl',
  }
};

I'm essentially saying "Hey webpack, there is a global variable named mapboxgl that lives outside the webpack bundle. Please use that variable whenever you see me import MAPBOXGL in my code instead of trying to retrieve that dependency in the bundled assets."

Now I can use it in my code like this:

// Vendor
import assign from 'lodash/assign';
import mapbox from 'MAPBOXGL';

/**
 * Default options for creating mapbox maps.
 * @type {Object}
 */
const DEFAULT_MAP_OPTIONS = {
  style: 'mapbox://styles/mapbox/dark-v9',
};

/**
 * Creates a mapbox map.
 * @param container ID of element that will contain the map.
 * @param options Mapbox options.
 * @returns {mapboxgl.Map}
 */
export function createMapboxMap(container, options) {
  return new mapbox.Map(
    assign({}, DEFAULT_MAP_OPTIONS, options, { container }),
  );
}

Technically you can also just use mapboxgl in your code without doing the import. Webpack is smart enough to realize when the code is accessing a global variable and skips minimizing it for production builds. It's just not clear where the variable is coming from.

Hopefully that helped. The webpack documentation on externals might explain it a bit better.