back to blogs
deploying forkbum.com, part 1

I ran into two blockers attempting to deploy my website for the first time. The first blocker related to build errors with gatsby/react. This post details what I did to turn my code into a compiled build prior to deploying my wesite. (You can jump tomy second blocker here.)

> the problem

Whenever the site was ran in the build environment, either of these two error messages were thrown:

WebpackError: ReferenceError: window is not defined

WebpackError: Invariant Violation: Minified React error #130.

From these error types, I first suspected webpack is complaining either about the "window" browser property not being able to be found and/or dependency issues when trying to create the minified production build.

> the research

Further research showed that either of these errors were thrown at path "/" - which is essentially my home page. In particular, it was at my unnecessarily fancy animation the home page leverages that the errors were thrown.

I built this animation using react-p5, a React wrapper for the p5.js library. p5.js is basically JavaScript's answer to Java's Processing, providing the programmer tools to build simulations and graphics in their projects.

Because p5.js is a visual library, it utilizes the browser window; many of the library's variables, such as windowWidth, map to browser properties. windowWidth, for instance, maps to window.innerWidth, which is width of the browser window's content area in pixels.

When running the site in the development server, these errors are not thrown because those browser properties (i.e. window) work well in the development environment, thus making them available to gatsby. When running the site in the build environment, however, files are bundled using webpack in node runtime, and it freaks out when those browser properties can't be found. This situation becomes more probable when using third-party libraries like react-p5.

> the solution

To fix these issues, I attempted two things.... First, I followed guidance from gatsby documentation itself and added the following code to my gatsby-node.js file - making sure to replace "bad-module" with "react-p5":

exports.onCreateWebpackConfig = ({ stage, loaders, actions }) => {
  if (stage === "build-html" || stage === "develop-html") {
    actions.setWebpackConfig({
      module: {
        rules: [
          {
            test: /bad-module/,
            use: loaders.null(),
          },
        ],
      },
    })
  }
}

In this code, we are customizing our webpack configuration by writing a rule to find the "bad module" (written as the regular expression literal) and replacing it with a null loader during server-side rendering.

Welp... for whatever reason this fixed the "window" ReferenceError but introduced a new error, the Invariant Violation error. Apparently this was happening because webpack was trying to minify those relevant files, but the imports were pointing to null because of the code we had just added to gatsby-node.js.

The second solution was then to re-write my component to utilize dynamic loading of react-p5.

Programmatically, my home page calls a component which contains my react-p5 code. To implement this second solution, I basically re-wrote this component as a class-based component instead of as a functional component to make use of lifecycle methods - specifically render() during component mounting into the DOM.

I also installed @loadable/component, which helps to render that dynamic loading. Then, I stuck all my original code in a truth check to check if the window browser property is defined.

By the end, I had basically re-written my code to something like this:

import loadable from '@loadable/component'

class myComponent extends React.Component {
    render() {
        if (typeof window !== 'undefined') {
            const myComponent = loadable(() => import('bad-module'));
            //my code
        } else {
            return null;
        }
    }
}

After making these changes, my errors were resolved, and I no longer had any build errors pertaining to my third-party libraries and the window property.

© 2022