Develop works, but Build Doesn't. WebpackError: Invariant failed
See original GitHub issueDescription
I have a Gatsby project that I started with this starter template.. I have since added a custom form that is inserted on the home page, and spans across 3 component “pages” (2 form pages, and a result page). Here’s how the components are called on the index page.
I used the react-hook-form api for my form validation and functionality, and to achieve the multi-page “wizard form” effect, I followed the example code on this page to the letter.
Everything works flawlessly in the “gatsby develop” environment, but, when I execute “npm run build” and/or “npm run deploy”, I get the same exact in my terminal:
failed Building static HTML for pages - 5.356s
ERROR #95313
Building static HTML failed for path "/"
See our docs page for more info on this error: https://gatsby.dev/debug-html
7 |
8 | if (isProduction) {
> 9 | throw new Error(prefix);
| ^
10 | } else {
11 | throw new Error(prefix + ": " + (message || ''));
12 | }
WebpackError: Invariant failed
- tiny-invariant.esm.js:9 invariant
node_modules/tiny-invariant/dist/tiny-invariant.esm.js:9:1
- history.js:250 createBrowserHistory
node_modules/history/esm/history.js:250:115
- react-router-dom.js:29 new BrowserRouter
node_modules/react-router-dom/esm/react-router-dom.js:29:41
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! gatsby-strapi-starter@0.1.0 build: `gatsby build --prefix-paths`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the gatsby-strapi-starter@0.1.0 build script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! /home/bc/.npm/_logs/2020-01-14T20_54_02_925Z-debug.log
[1] 1189 exit 1 npm run build
And the aforementioned error log reads as follows:
0 info it worked if it ends with ok
1 verbose cli [ '/home/bc/.nvm/versions/node/v10.18.0/bin/node',
1 verbose cli '/home/bc/.nvm/versions/node/v10.18.0/bin/npm',
1 verbose cli 'run',
1 verbose cli 'build' ]
2 info using npm@6.13.6
3 info using node@v10.18.0
4 verbose run-script [ 'prebuild', 'build', 'postbuild' ]
5 info lifecycle gatsby-strapi-starter@0.1.0~prebuild: gatsby-strapi-starter@0.1.0
6 info lifecycle gatsby-strapi-starter@0.1.0~build: gatsby-strapi-starter@0.1.0
7 verbose lifecycle gatsby-strapi-starter@0.1.0~build: unsafe-perm in lifecycle true
8 verbose lifecycle gatsby-strapi-starter@0.1.0~build: PATH: /home/bc/.nvm/versions/node/v10.18.0/lib/node_modules/npm/node_modules/npm-lifecycle/node-gyp-bin:/home/bc/Projects/WeLoveNevada4/node_modules/.bin:/home/bc/.nvm/versions/node/v10.18.0/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/bc/.nvm/versions/node/v12.14.0/bin:/home/bc/.nvm/versions/node/v10.18.0/bin:
9 verbose lifecycle gatsby-strapi-starter@0.1.0~build: CWD: /home/bc/Projects/WeLoveNevada4
10 silly lifecycle gatsby-strapi-starter@0.1.0~build: Args: [ '-c', 'gatsby build --prefix-paths' ]
11 silly lifecycle gatsby-strapi-starter@0.1.0~build: Returned: code: 1 signal: null
12 info lifecycle gatsby-strapi-starter@0.1.0~build: Failed to exec build script
13 verbose stack Error: gatsby-strapi-starter@0.1.0 build: `gatsby build --prefix-paths`
13 verbose stack Exit status 1
13 verbose stack at EventEmitter.<anonymous> (/home/bc/.nvm/versions/node/v10.18.0/lib/node_modules/npm/node_modules/npm-lifecycle/index.js:332:16)
13 verbose stack at EventEmitter.emit (events.js:198:13)
13 verbose stack at ChildProcess.<anonymous> (/home/bc/.nvm/versions/node/v10.18.0/lib/node_modules/npm/node_modules/npm-lifecycle/lib/spawn.js:55:14)
13 verbose stack at ChildProcess.emit (events.js:198:13)
13 verbose stack at maybeClose (internal/child_process.js:982:16)
13 verbose stack at Process.ChildProcess._handle.onexit (internal/child_process.js:259:5)
14 verbose pkgid gatsby-strapi-starter@0.1.0
15 verbose cwd /home/bc/Projects/WeLoveNevada4
16 verbose Linux 5.0.0-37-generic
17 verbose argv "/home/bc/.nvm/versions/node/v10.18.0/bin/node" "/home/bc/.nvm/versions/node/v10.18.0/bin/npm" "run" "build"
18 verbose node v10.18.0
19 verbose npm v6.13.6
20 error code ELIFECYCLE
21 error errno 1
22 error gatsby-strapi-starter@0.1.0 build: `gatsby build --prefix-paths`
22 error Exit status 1
23 error Failed at the gatsby-strapi-starter@0.1.0 build script.
23 error This is probably not a problem with npm. There is likely additional logging output above.
24 verbose exit [ 1, true ]
If you’d like to see the full source code of everything, here’s the repository.
My research into the error has me guessing that these errors have something to do with conflicting “routers” I’m using, but I don’t even know where to begin with regard to how to address this. This is my first React, and my first gatsby project…so consider me a dum dum in all things react/gatsby.
EDIT: I would like to add, since this site is really only two pages, if “de-gatsby-fying” the site is the easiest solution, I’m happy to do that if there’s a relatively clear path to doing so…
Steps to reproduce
if I run npm run build
I get the same error.
Expected result
I’d like the static version of the site to be created successfully after running npm run build
.
Actual result
Please see “Description” above
Environment
System:
OS: Linux 5.0 Ubuntu 18.04.3 LTS (Bionic Beaver)
CPU: (2) x64 Intel(R) Core(TM) i7-6700K CPU @ 4.00GHz
Shell: 5.4.2 - /bin/zsh
Binaries:
Node: 10.18.0 - ~/.nvm/versions/node/v10.18.0/bin/node
Yarn: 1.21.1 - /usr/bin/yarn
npm: 6.13.6 - ~/.nvm/versions/node/v10.18.0/bin/npm
Languages:
Python: 2.7.17 - /usr/bin/python
Browsers:
Chrome: 79.0.3945.117
Firefox: 72.0.1
npmPackages:
gatsby: ^2.18.17 => 2.18.17
gatsby-image: ^2.2.30 => 2.2.37
gatsby-plugin-favicon: ^3.1.6 => 3.1.6
gatsby-plugin-google-analytics: ^2.1.31 => 2.1.31
gatsby-plugin-google-tagmanager: ^2.1.15 => 2.1.20
gatsby-plugin-manifest: ^2.2.25 => 2.2.34
gatsby-plugin-netlify: ^2.1.23 => 2.1.30
gatsby-plugin-netlify-cache: ^1.2.0 => 1.2.0
gatsby-plugin-offline: ^3.0.17 => 3.0.30
gatsby-plugin-react-helmet: ^3.1.13 => 3.1.18
gatsby-plugin-robots-txt: ^1.5.0 => 1.5.0
gatsby-plugin-sass: ^2.1.20 => 2.1.26
gatsby-plugin-sharp: 2.2.2 => 2.2.2
gatsby-plugin-sitemap: ^2.2.19 => 2.2.24
gatsby-plugin-styled-components: ^3.1.16 => 3.1.16
gatsby-source-filesystem: ^2.1.35 => 2.1.43
gatsby-source-strapi: 0.0.10 => 0.0.10
gatsby-transformer-sharp: 2.2.2 => 2.2.2
npmGlobalPackages:
gatsby-cli: 2.8.26
Issue Analytics
- State:
- Created 4 years ago
- Comments:6
Top GitHub Comments
@Doomd i’ve tested what i had to test and i’m going to detail the steps i took to triage your issue.
yarn develop
(i’m using yarn, so if you use npm adjust accordingly the commands to that) and i saw the issue.pages
folder Gatsby treats it as a page that will be built and later shown. Also the reason it’s working in development mode and not in production mode is basically that Gatsby is more “permissive” in development to allow you a solid development experience without much hassle, allowing you to get away with some stuff. It’s when you move to the production mode that Gatsby becomes more strict and originates this type of errors.src\pages\index
to the following:What is happening here, as you have seen i removed the
little-state-machine
package initialization from here and removed the any references to the router. Also as you can see i’m importing theStep1
component in here. Basically the page becomes smaller, functional and simple to read.src\components\bcform1
(Step 1 component) i made some changes to test it around. Starting with changing the imports, by removing the references to thereact-router-dom
and adding inimport { navigate } from "gatsby"
, this import takes care of the programatic navigation with Gatsby. You’ll see how i used it shortly. You can read it more about it in here.onSubmit
function to the following:As you can see i removed the fetch call to avoid “hammering” any service you could be using in you project. Also you may have noticed that i have the
setsubmitBut
here, why i did that, reason being that adding the click handler in the submit button was preventing the form submit function to be triggered and i was stuck.Leaving in the button implementation in the form just like this:
success
function to the following:export default withRouter(Step1);
i now have a normal exportexport default Step1
.So far, we’ve covered the index, the Step1, moving onto the the Step2(or bcform2).
src\components\bcform2.js
tosrc\pages\bcform2.js
, which means that this will be a page aswell. Replaced theimport { withRouter } from 'react-router-dom';
toimport { navigate } from "gatsby"
onSubmit
function to the following:success
function to the following:Once again when the function is triggered after the timeout executes it will call the
navigate
function from Gatsby and load the result page. Also as you may or may not have noticed i changed thesetsubmitBut
call to and removed theonClick
handler from the form for the exact same reason as above.export default withRouter(Step1);
( also you had the same 2 components using the same export, that could lead to some weird errors with React not knowing what to use) toexport default Step2
We have the pages/components done. Time to move onto the
little-state-machine
implementation.Gatsby has some api hooks and some files that can be used for this sort of package. And they are
gatsby-ssr
andgatsby-browser
, as you may or may not know Gatsby “operates” on one spectrum, what this means that Gatsby is a Server Side Rendering(ssr) Framework and that means that it will compile and generate your site in node and this particular file and the API hooks that are used in here will picked up Gatsby and added to your site, the second onegatsby-browser
and it’s APIs is related to everything that will affect the browser. Which in this particular case both files will be used to add thelittle-state-machine
initialization. So that when you issue a development build withyarn develop
or a production build withyarn build
the data will be ready when you visit the page. As opposed to wait for it to initialize in thesrc\pages\index
file.To achieve this you’ll have to modify the contents of the files.
gatsby-ssr.js
, i added the following:gatsby-browser.js
i added the following:What is happening here, in both files is that i’m using the
wrapRootElement
to tell Gatsby to “inject” thelittle-state-machine
StateProvider element in the top node of the component’s tree. And with that when you need to add/updated/remove any data down the line it will be picked up.Also one thing the ternary operator:
What i’m doing here is the following, i’m checking if either i’m in production mode or not and also i’m implementing a “safe guard” by checking if the
window
object is defined. This safeguard is due to the fact that like i mentioned before Gatsby operates in one side of the spectrum, it will generate the build using node, and with that certain apis likewindow
,document
and some more do not exist and by using this i’m preventing any build failures.As some package developers tend to write their own packages without any consideration for Server Side Rendering, making developers that use Gatsby or any other Server Side Rendering Framework having to do the extra work sometimes unnecessarily…
Moving on.
After all of this if i issue
gatsby build && gatsby serve
the build will go through and if i openhttp://localhost:9000
i’m presented with the following:After filling the form and clicking thebutton, and waiting a bit i’m presented with:
And repeating the process here will display the end result.
Before i forget i moved
src\components\Result.js
tosrc\pages\result.js
and made it into a page.Like i said in the begining, i forked your repo and i’m going to make a pull request a bit later as i’m pressed for time today. I would like for you to go over the changes i made in more detail and adjust accordingly.
Now for some closing remarks if you’ll allow me.
As you said you’re a bit of a newcomer to the React ecosystem, it would be a good thing if you check out the freecodecamp they have a really good curriculum for not only React but other things related to the web development ecosystem. Also frontendmasters has some excelent content( but paid), wes bos has some good things aswell and also go through the React tutorial so you get acquainted with some code you might stumble upon while your doing some research.
Also it would be best you avoid function calling like this:
And also, this is a personal quirk of mine, when i’m using React for development i tend to use a rule of thumb, if a component has more than 150 lines of code, i tend to split it into several and use component composition. Making the components smaller leaner, more understandable to the reader. As you get your “React legs”(pardon the bad pun) you’ll see what i mean.
One final thing. Sorry for the really long post, but it was required to go over in more detail to try and explain to you in more detail what is the issue and how to solve it.
Feel free to provide feedback so that we can close this issue or continue to work on it until we find a suitable solution
@Doomd no need to thank, glad that i was able to solve your issue, or at least give you some insights.
I hear you…i hear you and fully understand why you originally used it.
Svelte, like React, Vue or *shrugs Angular are all excelent frameworks, built by awesome people. And i wouldn’t discard React just yet, my rule of thought when picking up a project is to implement it is to choose the right tool for the right job. Svelte is great and all, i like it alot, i’ve thinkered with it and wrote a tutorial on how you can use it with another framework and some concepts/options you have at your disposal are indeed good. But there’s still some stuff that needs to be addressed, i won’t go into more details as they are not relevant to this discussion. But it will needs to mature a bit more to be a contender…
Glad that you’re willing to go through the tutorial on freecodecamp and when you’re ready and more confortable with React give Gatsby another chance, just my humble opinion.
And for native…that’s a discussion i’m not willing to go into…but if given the chance, i would rather implement a pwa with Gatsby than dive right into React Native, or if i need to use some specific device apis then sure something like flutter.