Skip to content
This repository has been archived by the owner on Apr 13, 2023. It is now read-only.

SSR fails with NODE_ENV=production #237

Closed
rewop opened this issue Sep 28, 2016 · 4 comments
Closed

SSR fails with NODE_ENV=production #237

rewop opened this issue Sep 28, 2016 · 4 comments

Comments

@rewop
Copy link

rewop commented Sep 28, 2016

I am doing SSR with [email protected] and node v6.5.0 and.

  • When NODE_ENV=development server side works correctly.
  • When NODE_ENV=production, SSR fails with the following error:
Invariant Violation: Minified React error #23; visit http://facebook.github.io/react/docs/error-decoder.html?invariant=23 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.
    at reactProdInvariant (myapp/node_modules/react/lib/reactProdInvariant.js:32:15)
    at Object.onlyChild [as only] (myapp/node_modules/react/lib/onlyChild.js:34:166)
    at ApolloProvider.render (myapp/node_modules/react-apollo/ApolloProvider.js:33:31)
    at getChildFromComponent (myapp/node_modules/react-apollo/server.js:16:26)
    at getQueriesFromTree (myapp/node_modules/react-apollo/server.js:54:24)
    at getQueriesFromTree (myapp/node_modules/react-apollo/server.js:53:9)
    at getDataFromTree (myapp/node_modules/react-apollo/server.js:72:14)

The error can be decoded at http://facebook.github.io/react/docs/error-decoder.html?invariant=23, and is referred to the fact that the prop children of ApolloProvider is undefined.

How to reproduce

This is my code, a bit simplified:
Root.js

const Root = ({
    history: _history,
    routes,
    routerState,
    client,
    store
}) => {
    let component;
    if (__SERVER__)
        component = <RouterContext history={_history} {...routerState} />;
    else
        component = <Router history={_history} routes={routes} render={scrollHandlingMiddleware} />;
    return (
        <ApolloProvider client={client} store={store}>
                {component}
        </ApolloProvider>
    );
};

server.js (snippet)

const Root = require("../client/containers/Root").default;
const client = createClient();
const store = createStore({
    client
});
const routes = getRoutes();
const history = createMemoryHistory(req.path);

match({ history, routes, location: req.originalUrl }, (err, redirectLocation, routerState) => {
    if (err) return next(err);
    else if (redirectLocation)
        return res.redirect(302, redirectLocation.pathname + redirectLocation.search);
    else if (!routerState)
        return res.status(404).send("Not Found");
    const rootContainer = React.createElement(Root, {
        history,
        routerState,
        routes,
        client,
        store
    });

    return getDataFromTree(rootContainer)
    .then(context => {
        hydrateOnClient({
            state: context.store.getState(),
            markup: renderToString(rootContainer)
        });
    });
});

Just run the server with NODE_ENV=production node server.js

Debug

In my scenario only in production ApolloProvider is being rendered with the property given to the Root component, which makes the application crash.

I reduced the problem to this piece of code.

I added console.log(e) in the empty catch block, and I noticed to following:

  • in production the try block doesn't throw.
  • in development the try block throws with the error caught error TypeError: Can't add property props, object is not extensible

If I remove the block my application works again.

So apparently in production Component.props is set to the property of the parent component. This is not correct, because Component is given to the next iteration, but it has the wrong props and context.

So I wonder, why the try catch blog to overwrite Component if it is frozen?

The bug is introduced in version 0.5.5 by #205.

Workaround

Use [email protected] instead

Version

@rewop rewop changed the title SSR fails in with NODE_ENV=production SSR fails with NODE_ENV=production Sep 28, 2016
@acorcutt
Copy link

acorcutt commented Oct 7, 2016

I'm also seeing something similar, my code is similar to above but without the router match wrapper.
Non-minified but in production error is reported at https://github.com/apollostack/react-apollo/blob/master/src/server.ts#L59 as:
Invariant Violation: <Subscriber channel="location"> must be rendered in the context of a <Broadcast channel="location">

@rewop
Copy link
Author

rewop commented Oct 10, 2016

I have created a PR to show how the problem would be fixed in my case. I would like feedback on this one from @jbaxleyiii as he worked on #205

@jbaxleyiii
Copy link
Contributor

@rewop, @tmeasday is working on this over the next couple of days!

@tmeasday tmeasday mentioned this issue Nov 7, 2016
@tmeasday
Copy link
Contributor

I assume this is fixed in 0.6.0

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

Successfully merging a pull request may close this issue.

4 participants