Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Redux integration failed during build #2963

Closed
habibridho opened this issue Nov 19, 2017 · 10 comments
Closed

Redux integration failed during build #2963

habibridho opened this issue Nov 19, 2017 · 10 comments

Comments

@habibridho
Copy link

Hi, I tried implementing gatsby and redux. I follow this example and it works in dev. However, when I try to build it, I got a webpack error:
WebpackError: Could not find "store" in either the context or props of "Connect(Template)". Either wrap the root component in a <Provider>, or explicitly pass "store" as a prop to "Connect(Template)".

Here is my gatsby-browser.js

import React from 'react'
import { Router } from 'react-router-dom'
import { Provider } from 'react-redux'
import { createStore, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk'
import {persistStore, autoRehydrate} from 'redux-persist'
import reducers from "./src/redux/reducers/"
import localForage from 'localforage'

exports.replaceRouterComponent = ({ history }) => {
  const enhancer = compose(
    applyMiddleware(thunk),
    autoRehydrate()
  )

  let store = createStore(reducers, enhancer)

  persistStore(store, {storage: localForage}, () => {
    
  })

  if (process.env.NODE_ENV === 'production') {
    console.log = () => {}
  }

  const ConnectedRouterWrapper = ({ children }) => (
    <Provider store={store}>
      <Router history={history}>{children}</Router>
    </Provider>
  )

  return ConnectedRouterWrapper
}
@m-allanson
Copy link
Contributor

m-allanson commented Nov 19, 2017

Are you missing the Provider component in gatsby-ssr.js?

Normally when I see errors that only happen at build time, it's something to do with server side rendering. Things like code that expect window to exist, or not adding something into gatsby-ssr.js that I've added into gatsby-browser.js

@habibridho
Copy link
Author

Well, I don't have gatsby-ssr.js in my project. I started my project using this starter. At first, I also didn't have gatsby-browser.js, I added it after reading the redux integration.

Where can I find the documentation about these gatsby-*.js files? I'm sorry, this is my first time using gatsby, still having difficulty on how it works.

@m-allanson
Copy link
Contributor

m-allanson commented Nov 19, 2017

Huh, I actually can't find any docs that specifically mention the gatsby-ssr.js and gatsby-browser.js filenames. They're hinted at by the structure of the docs and used in a lot of the example sites.

In that redux example gatsby-ssr.js is implementing Gatsby's replaceRenderer API to add redux to the JS code that's run in NodeJS.

Gatsby uses this to render each of your pages to a string, then write those strings to plain HTML files. This only happens during gatsby build, not during gatsby develop which I think is why your error only happens at build time.

Also in that example you've seen gatsby-browser.js, which is implementing Gatsby's replaceRouterComponent API. However, this only adds redux to the JS bundle that gets run in the browser after the page has downloaded.

Does that help?

@KyleAMathews
Copy link
Contributor

Huh yeah — they do need better intros. The browser API docs neglect to say that these APIs are implemented in gatsby-browser.js

https://www.gatsbyjs.org/docs/browser-apis/

@habibridho
Copy link
Author

@m-allanson That helps to shed a light. I've added gatsby-ssr.js to my project with the following:

import React from 'react'
import { Provider } from 'react-redux'
import { renderToString } from 'react-dom/server'
import {persistStore} from 'redux-persist'
import initStore from "./src/redux/store"

exports.replaceRenderer = ({ bodyComponent, replaceBodyHTMLString }) => {

  const store = initStore()

  const ConnectedBody = () => (
      <Provider store={store}>
          {bodyComponent}
      </Provider>
  )
  replaceBodyHTMLString(renderToString(<ConnectedBody/>))
}

And my initStore implementation:

import { createStore, applyMiddleware, compose } from 'redux'
import thunk from 'redux-thunk'
import {persistStore, autoRehydrate} from 'redux-persist'
import reducers from './reducers/'

const enhancer = compose(
  applyMiddleware(thunk),
  autoRehydrate()
)

const initStore = () => createStore(reducers, enhancer)

export default initStore

After that, I got TypeError: Cannot read property 'initial' of undefined when doing gatsby build. So, I follow this recommendation and now I got this error:
WebpackError: Minified React error #130; visit http://facebook.github.io/react/docs/error-decoder.html?invariant=130&args[]=object&args[]=%20Check%20the%20render%20method%20of%20%60Template%60. for the full message or use the non-minified dev environment for full errors and additional helpful warnings.

I think that has something to do with PropTypes, but I'm not sure since my project still works fine in gatsby develop.

@rppld
Copy link

rppld commented Nov 20, 2017

Ran into this same issue yesterday when trying to integrate Redux based on this example. In develop everything works fine, but when running the build task I get the error:

WebpackError: Could not find "store" in either the context or props of "Connect(Cart)". Either wrap the root component in a <Provider>, or explicitly pass "store" as a prop to "Connect(Cart)".

I've added gatsby-ssr.js like so:

import React from "react"
import { Provider } from "react-redux"
import { renderToString } from "react-dom/server"
import configureStore from "./src/state/configureStore"

exports.replaceRenderer = ({ bodyComponent, replaceBodyHTMLString }) => {
  const store = configureStore()
  const ConnectedBody = () => <Provider store={store}>{bodyComponent}</Provider>
  replaceBodyHTMLString(renderToString(<ConnectedBody />))
}

and gatsby-browser.js like:

import React from "react"
import { Router } from "react-router-dom"
import { Provider } from "react-redux"
import configureStore from "./src/state/configureStore"

exports.replaceRouterComponent = ({ history }) => {
  const store = configureStore()

  const ConnectedRouterWrapper = ({ children }) => (
    <Provider store={store}>
      <Router history={history}>{children}</Router>
    </Provider>
  )

  return ConnectedRouterWrapper
}

Both reference the configureStore function in ./src/state/configureStore.js:

import { createStore } from "redux"

const reducer = (state, action) => {
  // Actions removed for clarity
}

const initialState = {
  // Contents removed for clarity
}

const configureStore = () => createStore(reducer, initialState)

export default configureStore

I think the only difference to the example is that I left out ./src/html.js, though I tried adding it and I still get that same error from above.

Anyone got an idea what might cause the hiccup?

Here's a link to the whole repository, if that helps.

@m-allanson
Copy link
Contributor

m-allanson commented Nov 20, 2017

@rppld the whole repo link helps a lot, thanks. It looks like you're running into #2005. I was able to get your build to run by removing the styled components plugin from gatsby-config.js and then updating gatsby-ssr.js to use @akadop's example code

@habibridho I'm not sure what your new error is, if you're able to create a minimal repo i can try and take a closer look. Based on the link in the error message, maybe something is not being imported correctly in your Template component?

@rppld
Copy link

rppld commented Nov 20, 2017

@m-allanson Ah dangggg!! In a previous approach I had already tried to remove all components that were using styled-components to see if this solves it, but to no avail. Removing the actual plugin like you suggested did the trick! Thanks a lot for this!

@habibridho
Copy link
Author

I'm trying to create a minimal repo but I still could not reproduce the error (the project build well without error). I will try moving my components one by one in the morning and hopefully something will break and give us clue of what went wrong. I'll keep you posted.

Thanks for the response anyway!

@habibridho
Copy link
Author

It turns out that in my case, this lib cause the WebpackError. The lib can be built using pure react project though, so I guess it just doesn't go well with gatsby configuration for now.

I think this is not gatsby's issue, so I'll close it. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants