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

mapboxgl / Webpack error: self is undefined #7555

Closed
dwehrmann opened this issue Aug 22, 2018 · 6 comments
Closed

mapboxgl / Webpack error: self is undefined #7555

dwehrmann opened this issue Aug 22, 2018 · 6 comments
Labels
help wanted Issue with a clear description that the community can help with. type: question or discussion Issue discussing or asking a question about Gatsby

Comments

@dwehrmann
Copy link

Hi guys, I'm working on a site which uses the mapbox-gl module, development mode works fine but it breaks in build stages. I am aware of the "(window/whatever) is undefined at build time" issue but I am unsure how to implement the solution. Almost all solutions I found revolve around Webpack configuration which is where I struggle in combination with Gatsby.

To be specific: Here seems to be the solution:
mapbox/mapbox-gl-js#4359 (comment)

but I don't know how to implement that in Gatsby. Do I have to put this in the Gatsby-node.js file? I have tried but without success. I'd be happy if someone could advise.

Here's my Gatsby-node.js:

`
const makeRequest = (graphql, request) =>
new Promise((resolve, reject) => {
// Query for nodes to use in creating pages.
resolve(
graphql(request).then(result => {
if (result.errors) {
reject(result.errors);
}

            return result;
        })
    );
});

exports.createPages = ({ boundActionCreators, graphql }) => {
const { createPage } = boundActionCreators;

const getPage = makeRequest(
    graphql,
    `
{
  allStrapiReferenz {
    edges {
      node {
        id
        Headline
        Ref_Category
      }
    }
  },
  allStrapiArbeitsgebiete{
      edges{
          node{
            id
            Arbeitsgebiet_Titel
          }
      }
  }
}
`
).then(result => {
    result.data.allStrapiReferenz.edges.forEach(({ node }) => {
        createPage({
            path: `/referenz/${slugify(node.Ref_Category)}/${slugify(node.Headline)}`,
            component: path.resolve(`src/templates/referenz.js`),
            context: {
                id: node.id,
            },
        });
    });
    result.data.allStrapiArbeitsgebiete.edges.forEach(({ node }) => {
        createPage({
            path: `/arbeitsgebiete/${slugify(node.Arbeitsgebiet_Titel)}`,
            component: path.resolve(`src/templates/arbeitsgebiete.js`),
            context: {
                id: node.id,
            },
        });
    });



});

// Query for articles nodes to use in creating pages.
return getPage;

};`

@dwehrmann
Copy link
Author

I should add I have tried the steps here (under fixing 3rd party modules):

https://www.gatsbyjs.org/docs/debugging-html-builds/

but that also threw an error:

WebpackError: (0 , _reactMapboxGl2.default) is not a function

so I guess the solution is not to skip the module but to skip the uglification of the module ...

@porfirioribeiro
Copy link
Contributor

I had the same problem, was hard to debug and hard to solve.
End up with something like this on gatsby-node.js

exports.onCreateWebpackConfig = ({ stage, actions, getConfig }) => {
  const config = getConfig();

  let newConfig = {
    ...config,
    module: {
      ...config.module,
      noParse: /(mapbox-gl)\.js$/,
    },
  };

  if (stage === 'build-html') {
    newConfig = {
      ...newConfig,
      module: {
        ...newConfig.module,
        rules: [
          ...newConfig.module.rules,
          {
            test: /(mapbox-gl)\.js$/,
            loader: 'null-loader',
          },
        ],
      },
    };
  }

  actions.replaceWebpackConfig(newConfig);
};

@Chuloo Chuloo added help wanted Issue with a clear description that the community can help with. type: question or discussion Issue discussing or asking a question about Gatsby labels Aug 23, 2018
@dwehrmann
Copy link
Author

dwehrmann commented Aug 29, 2018

@porfirioribeiro Thank you and sorry for the late reply. Unfortunately it did not work. Do I have to adjust anything in the Webpack config you pasted?

@stemmlerjs
Copy link

stemmlerjs commented Sep 26, 2018

Hey @dwehrmann. I hope you found a solution to this. I was able to get mine working with some logic inside the component to create a mock Map instance when it's in build. I'm also using react-mapbox-gl.

let mapboxgl
let ReactMapboxGl = {}

if (typeof window !== `undefined`) {
  mapboxgl = require('mapbox-gl')
  ReactMapboxGl = require('react-mapbox-gl')
} else {
  ReactMapboxGl.Map = () => {
    return class Mock extends React.Component {
      constructor() {
        super()
      }
      render() {
        return <div />
      }
    }
  }
}

const Map = ReactMapboxGl.Map({
  accessToken:  '[your-token-here]',
})

class DirectoryMap extends React.Component {
  constructor(props) {
    super(props)
  }

  render() {
    return (
      <div className="directory-map">
        <Map
          ref={e => {
            this.map = e
          }}
          zoom={[11]}
          speed={[0.6]}
        >
        </Map>
      </div>
    )
  }
}

@dwehrmann
Copy link
Author

dwehrmann commented Sep 26, 2018

Hi @stemmlerjs – thank you! Similar to your solution, I was able to solve this by using class extends like that:

class RefMap extends React.Component {
  createMap() {
    const iconSize = 1
    const map = new mapboxgl.Map({
      center: this.props.center,
      container: 'map',
      style: 'mapbox://styles/mapbox/light-v9',
      trackResize: 'true',
      zoom: this.props.zoom,
      pitch: 50,
      detectRetina: 'true'
    })
    var el = document.createElement('div');
    el.className = 'marker';
    el.style.backgroundImage = 'url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMTIwMCIgaGVpZ2h0PSIxMjAwIiB2aWV3Qm94PSIwIDAgMTIwMCAxMjAwIj48Zz48cmVjdCB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjZmZmZmZmIj48L3JlY3Q+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNjAwIDYwMCkgc2NhbGUoMC42OSAwLjY5KSByb3RhdGUoMCkgdHJhbnNsYXRlKC02MDAgLTYwMCkiIHN0eWxlPSJmaWxsOiNmNDdmMjQ7Ij48c3ZnIGZpbGw9IiNmNDdmMjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHZlcnNpb249IjEuMSIgeD0iMHB4IiB5PSIwcHgiIHZpZXdCb3g9IjAgMCAxMDAgMTAwIiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCAxMDAgMTAwIiB4bWw6c3BhY2U9InByZXNlcnZlIj48cGF0aCBkPSJNNTAsMjVjNi44OTYsMCwxMi41LDUuNjA0LDEyLjUsMTIuNVM1Ni44OTYsNTAsNTAsNTBzLTEyLjUtNS42MDQtMTIuNS0xMi41UzQzLjEwNCwyNSw1MCwyNXogTTUwLDAgIEMyOS4xNjcsMCwxMi41LDE2LjY2NywxMi41LDM3LjVTMjkuMTY3LDc1LDUwLDEwMGMyMC44MzMtMjUsMzcuNS00MS42NjcsMzcuNS02Mi41UzcwLjgzMywwLDUwLDB6Ij48L3BhdGg+PC9zdmc+PC9nPjwvZz48L3N2Zz4=);)'

    map.on('load', () => {

      new mapboxgl.Marker(el)
        .setLngLat(this.props.center)
        .addTo(map);

      (map) => { map.resize() }

    })
  }

  componentDidMount() {
    mapboxgl.accessToken = '[TOKEN]'
    this.createMap()
  }

  render() {
    return (

      <div id={'map'} style={{ width: '100%', height: '100%' }} />

    )
  }

And in my gatsby-node.js:

exports.modifyWebpackConfig = ({ config, stage }) => {
    if (stage === "build-html") {
        config.loader("null", 
        {
            test: /isotope\-|fizzy\-ui\-utils|desandro\-|masonry|outlayer|get\-size|doc\-ready|eventie|eventemitter|react-mapbox-gl|react-mapbox-gl|react-map-gl|(mapbox-gl)\.js$/,
            loader: "null-loader",
        },
    );
    }
};

note that I had to exclude isotope.js as well.

Things are working now, thank you everyone! Hopefully this thread will be useful for somebody else as well.

@dev-chr
Copy link

dev-chr commented Feb 9, 2019

I know this issue is closed, but @porfirioribeiro's solution worked for me. Just pasted his code in gatsby-node.js

Thank you very much!

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Issue with a clear description that the community can help with. type: question or discussion Issue discussing or asking a question about Gatsby
Projects
None yet
Development

No branches or pull requests

6 participants
@porfirioribeiro @dwehrmann @stemmlerjs @dev-chr @Chuloo and others