Search code examples
buildgatsbyreact-three-fiber

npm run build gatsby: "Page data from page-data.json for the failed page "/404/"..."


When npm building my gatsby project, I get the following:

Page data from page-data.json for the failed page "/404/": {
  "componentChunkName": "component---src-pages-404-js",
  "path": "/404/",
  "result": {
    "pageContext": {}
  },
  "staticQueryHashes": []
}

failed Building static HTML for pages - 3.357s

 ERROR #95313 

Building static HTML failed for path "/404/"

See our docs page for more info on this error: https://gatsby.dev/debug-html


  21 |     };
  22 |     this.defaultAttributeTypes = {
> 23 |       position: 'Float32Array',
     | ^
  24 |       normal: 'Float32Array',
  25 |       color: 'Float32Array',
  26 |       uv: 'Float32Array'

I don't know what it means, by searching the internet, I found this question Page data from page-data.json for the failed page "/", I learned that this error could be caused by using the window object, so I tried to check for the window use in my code, the problem was that I use react three fiber, and it may be using this document object,

Then, the same answer showed that one could bypass this error by adding a code to the gatsby-node.js (it doesn't say by I guess), basically exporting onCreateWebpackConfig (in this file I'm exporting sourceNodes and onCreateWebpackConfig, hope this doesn't cause any error)

The problem persists.

I also have a 404 page

import React from "react";

const NotFoundPage = () => {
    return <div>Sorry, the page you requested was not found</div>;
};

export default NotFoundPage;

Any hints please, I really don't know how to fix it

****** EDIT ******

Ferran asked me for my onCreateWebpackConfig, here it is:

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

I typed "test: /react-three-fiber/,", but I'm not sure of it, I'm supposed to type the "bad module", I don't know, I only know my components


Solution

  • As you pointed out when you deal with third-party modules that use window or other global objects you need to add a null loader to webpack configuration to bypass the server-side compilation using onCreateWebpackConfig. In your case, since the package name is @react-three/fiber, try something like:

    exports.onCreateWebpackConfig = ({ stage, loaders, actions }) => {
      actions.setWebpackConfig({
        module: {
          rules: [
            {
              test: /@react-three\/fiber/,
              use: loaders.null(),
            },
          ],
        },
      });
    };
    

    Keep in mind that test is a regular expression (that's why is between slashes, /) and it matches the folder name under node_modules. Be sure that the folder name matches the regular expression.

    Answering the duplicity of configuring gatsby webpack to don't check base objects like window when compiling a component

    But I also use canvas, window.innerWidth, and whatnot, in a component

    How do I set another rule to indicate webpack to not throw that error when checking a component?

    For third-party dependencies you just need to keep adding libraries to the previous null-loader configuration:

    exports.onCreateWebpackConfig = ({ stage, loaders, actions }) => {
      actions.setWebpackConfig({
        module: {
          rules: [
            {
              test: /@react-three\/fiber/,
              use: loaders.null(),
            },
            {
              test: /other-library/,
              use: loaders.null(),
            },
          ],
        },
      });
    };
    

    Keeping in mind what I said, /other-library/ stands for a folder name inside node_modules.

    For the internal use of window object, you just need to add the following condition in before using it:

    if(typeof window !== "undefined"){
      //your window calculation
    }
    

    Depending on when and how you are using window, you may not need to wrap it in this condition (i.e: if you use window in a useEffect that is not triggered until the DOM is loaded where window will be always set).

    All these approaches can be found at Gatsby docs: https://www.gatsbyjs.com/docs/debugging-html-builds/


    By the way, I'm having two exports in gatsby-node.js: exports.sourceNodes = async ({... for a data that I use with a graphql, and exports.onCreateWebpackConfig =... described here, is there any problem with that?

    Of course not, is just a file exporting functions. It's how it is supposed to work and that's the reason why you have a bunch of APIs available.