Debugging Static Builds

Because Gatsby’s static build process ultimately generates a series of HTML files that maximize the speed at which Gatsby sites load in the browser, some issues can be difficult to diagnose. In many cases, issues surrounding static builds involve inaccessible globals or Webpack bundling issues. The Gatsby documentation outlines four specific cases that are common in Gatsby sites:

  1. Undefined browser globals. Because JavaScript can be executed on the server side or the client side, if your code references the window or document object, those objects may be unavailable except when the Gatsby site is loaded in a browser. During the build process, you may run into errors such as window is not defined, as it is undefined before the site reaches the browser. There are two ways to handle this:
    1. If your code requires the use of the window or document object in the browser, perform a check to ensure window or document is defined so that the code within the check is executed only in the browser, as follows:if (typeof window !== `undefined`) { // Your window-reliant code here. }
    2. If the offending code with references to the window or document object is within the render function of a React component, you’ll need to relocate that code into a componentDidMount lifecycle method in React or, if you’re using React hooks, into a useEffect hook implementation to prevent its execution outside the browser.
  2. Improperly exported pages. Because Gatsby automatically generates pages based on the contents of the pages directory, you must ensure that all files within that directory are exporting either a React component or a string. Otherwise, Gatsby’s automatic page generation will fail.
  3. Collision of import and require in a single file. In Webpack 4, the bundler no longer permits the use of both import and require statements within the same file. Instead, Gatsby recommends using only import statements within Gatsby files, including gatsby-ssr.js and gatsby-browser.js.
  4. Improper hydration. Gatsby allows for client-side functionality to proceed by hydrating rendered HTML with React. If this hydration doesn’t happen correctly, you will run into inconsistencies between the results of the gatsby develop and gatsby build commands. If you discover inconsistencies between the build results, it’s likely that some logic in gatsby-ssr.js or gatsby-browser.js is causing a mismatch between the HTML generated by the server and that understood by the client.
AVOIDING ISSUES WITH THE WINDOW OBJECT

One edge case not enumerated in this list relates to NPM modules that are used as dependencies in Gatsby sites and refer to the window object. Because these are upstream dependencies, if you report the issue and request a check on the window object it may take some time before the maintainer responds. To avoid hacking into the module itself, which compromises dependency management, in gatsby-node.js you can customize your Webpack configuration such that during server-side rendering, the module is replaced with an empty dummy module:

// gatsby-node.js
exports.onCreateWebpackConfig = ({
  stage, loaders, actions
}) => {
  if (stage === "build-html") {
    actions.setWebpackConfig({
      module: {
        rules: [
          {
            test: /module-without-window-defined-check/,
            use: loaders.null(),
          },
        ],
      },
    })
  }
}

An alternative to this approach is to use the loadable-components package, which allows developers to use code splitting to force a module to dynamically load only in the browser and not during server-side rendering.


Posted

in

,

by

Tags:

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *