Gatsby: [v2] gatsby-browser.js errors at runtime: `exports is not defined`

Created on 8 Mar 2018  ·  8Comments  ·  Source: gatsbyjs/gatsby

Description

When a gatsby-browser.js file is loaded at runtime, it can throw an error under the right build circumstances. As far as I can tell, the circumstances seem to be:

  • [@babel/preset-env] is configured not to transpile modules (modules: false)
  • [@babel/plugin-transform-runtime] is being used
  • gatsby-browser.js contains some code that gets transformed by the runtime transform plugin

Steps to reproduce

  1. Add a gatsby-browser.js file to the project with some contents
    that could trigger the babel-runtime transform (see file contents below)
  2. Run gatsby build && gatsby serve
  3. Open the project in the browser to see the error in the console (see below)

Expected result

should render 'hello world!'

Actual result

Runtime error is thrown:

Uncaught ReferenceError: exports is not defined
    at Object../gatsby-browser.js (gatsby-browser.js:3)
    at __webpack_require__ (bootstrap 3868e9d1f8a80626a53e:54)
    at Object../.cache/api-runner-browser.js (api-runner-browser.js:2)
    at __webpack_require__ (bootstrap 3868e9d1f8a80626a53e:54)
    at Object../.cache/production-app.js (commons-1e491a978878eec435ee.js:777)
    at __webpack_require__ (bootstrap 3868e9d1f8a80626a53e:54)
    at webpackJsonpCallback (bootstrap 3868e9d1f8a80626a53e:25)
    at app-773b1833abbf62850cc1.js:1

Environment

  • Gatsby version (npm list gatsby): 2.0.0-alpha.10
  • Node.js version: 8.9.3
  • Operating System: OSX 10.13.3

File contents (if changed):

gatsby-browser.js:

const React = require('react');
// Object spread seems to trigger babel runtime transform
exports.replaceComponentRenderer = ({props, loader}) =>
  React.createElement('h1', {...props, loader, children: 'hello world!'});

Most helpful comment

replacing:

exports.replaceRouterComponent = ...

with

export const replaceRouterComponent = ...

as @westmark mentioned worked for me 👍 we were using import's for grabbing modules

All 8 comments

Further findings:

  • Using es6 import (import React from 'react') will also cause the runtime error
  • Using es6 export (export const replaceComponentRender = ...) causes Gatsby not to be able to find the API hook.

I point these out because i think the issue is that the module is compiled as (or authored as) a mix of CJS and ES6, which is confusing webpack.

Yeah, webpack 3+ won't accept modules with mixed CJS and ES6.

So const React = require("react") is required right now unless we add support for es6 exports to gatsby-browser.js

This seems to be fixed now(?). We can do export const replaceRouterComponent = ... in our project at least.

Any updates on this - I am getting the same error

replacing:

exports.replaceRouterComponent = ...

with

export const replaceRouterComponent = ...

as @westmark mentioned worked for me 👍 we were using import's for grabbing modules

As Kyle mentioned above, mixing ES6 Module style ( import and export) with CommonJS style (require and exports) is what causes this. So if you use import you must use export and not exports.

I'm looking into better errors for this over in #4718

@m-allanson It looks like there's also a production bug where using export results in API methods not being applied during gatsby build. I opened #6761 to track that.

I believe this issue is resolved in #6761. Closing it now 👍

Was this page helpful?
0 / 5 - 0 ratings

Related issues

totsteps picture totsteps  ·  3Comments

dustinhorton picture dustinhorton  ·  3Comments

andykais picture andykais  ·  3Comments

dustinhorton picture dustinhorton  ·  3Comments

benstr picture benstr  ·  3Comments