Search code examples
reactjsgatsbyreact-admin

react-admin as a page in Gatsby project


expecting I wanted to include react-admin in a Gatsby project so that I could have a /admin route that will be an interface for the site data.

What happened instead: Using gatbsy new , I setup a boilerplate gatsby project. Then installing react-admin and adding a page into the gatsby project, while following react-admin tutorial, causes gatsby to fail building.

gatsby develop

seems fine and does not crash the app, however

gatbsy build

leads to

WebpackError: Invariant failed

Steps to reproduce: gatsby new _____ npm install react-admin npm install ra-data-simple-rest

  • add a minimal admin page to gatsby's pages folder

gatsby develop = OK gatsby build = Failed

terminal output https://i.sstatic.net/qNXhk.jpg

Related code: Here is a repository that can be cloned to reproduce: https://github.com/jzohdi/react-admin-gatsby-test

Environment Same result on Windows 10 and WSL Ubuntu 18.04

from package.json "gatsby": "^2.22.15", "gatsby-image": "^2.4.5", "gatsby-plugin-manifest": "^2.4.9", "gatsby-plugin-offline": "^3.2.7", "gatsby-plugin-react-helmet": "^3.3.2", "gatsby-plugin-sharp": "^2.6.9", "gatsby-source-filesystem": "^2.3.8", "gatsby-transformer-sharp": "^2.5.3", "prop-types": "^15.7.2", "react": "^16.12.0", "react-admin": "^3.5.5", "react-dom": "^16.12.0", "react-helmet": "^6.0.0"


Solution

  • From your repository, it sounds like you found the answer, but you don't like it.

    Gatsby can't do SSR for react-admin because react-admin depends on running in the browser. To integrate react-admin into Gatsby, you need to generate your admin area as client-only routes.

    I'd expect admin areas to be client-only routes anyways, since they would require authentication to view. Populating them with real data at build-time could create data security issues.

    In your example repo, you mention these ways to fix the issue. I'm going to record them here for posterity:

    1) Replace the offending module with a dummy during SSR 1

    This snippet should replace the react-admin module while running server-side rendering, and result in a successful compilation:

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

    2) Use loadable-components2

    Instead of importing react-admin components directly, wrap them in the loadable functions. This pulls them out of the HTML-build process and keeps Gatsby from choking on it.

    import loadable from '@loadable/component';
    
    const reactAdmin = loadable() => import('react-admin');
    const { Admin, Resource } = reactAdmin