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

Conversation

benjamn
Copy link
Member

@benjamn benjamn commented Nov 16, 2018

After #2533, getDataFromTree is now implemented in terms of renderToStaticMarkup, which comes from react-dom/server, but the presence of the react-dom dependency was not enforced, as was revealed by #2592.

If react-apollo depends directly on react-dom, and tries to be even a little bit strict about the version, we run the risk of duplicating the entire react-dom package, which is often one of the largest npm dependencies in React-based apps.

A peer dependency won't automatically solve #2592, but it will provide an important clue to the solution, if my comment #2592 (comment) is accurate.

@benjamn benjamn self-assigned this Nov 16, 2018
We should just remove walkTree altogether, since it already doesn't work
with the latest react and react-dom versions, and getDataFromTree no
longer uses it.
@benjamn benjamn force-pushed the depend-on-react-dom branch from 33fcb00 to 000f8a3 Compare November 16, 2018 23:55
If react-apollo depends directly on react-dom, and tries to be even a
little bit strict about the version, we run the risk of duplicating the
entire react-dom package, which is often one of the largest npm
dependencies in React-based apps.

A peer dependency won't automatically solve #2592, but it will provide an
important clue to the solution.
@benjamn benjamn changed the title Move react-dom from devDependencies to dependencies. Make react-dom a peer dependency, like react. Nov 17, 2018
@benjamn benjamn requested a review from hwillson November 17, 2018 00:22
@@ -88,7 +88,8 @@
},
"peerDependencies": {
"apollo-client": "^2.3.8",
"react": "0.14.x || 15.* || ^15.0.0 || ^16.0.0",
Copy link
Member Author

@benjamn benjamn Nov 17, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hwillson @jbaxleyiii Is it reasonable to stop advertising support for [email protected] at this point? That version line was last published two years ago (0.14.9). Also, this is just a peer dependency, not actually a guarantee that react-apollo works with [email protected], which we probably don't anymore…

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@benjamn Quite reasonable!

@benjamn benjamn force-pushed the depend-on-react-dom branch from f3d7b74 to e6eb08c Compare November 17, 2018 15:43
React Native is obviously not Node.js, but it also doesn't identify itself
as a browser-like environment, so importing `react-dom/server` fails due
to the transitive dependency on Node's built-in `stream` module:
#2592 (comment)

To fix this problem, we need to avoid automatically importing
`react-dom/server` in React Native (especially since `getDataFromTree` is
unlikely to be used in RN apps). Since module dependencies are effectively
static, detecting React Native at runtime is not an option, so we need
help from the React Native bundler. Specifically, if we import the render
function from `react-dom/server` in a small wrapper module, we should be
able to override that module in React Native.

According to the documentation of "Platform-specific extensions," it
appears we can make this work using the `.native.js` file extension.
Specifically, React Native is supposed to prefer `lib/*.native.js` modules
to their `lib/*.js` counterparts:
https://facebook.github.io/react-native/docs/platform-specific-code#platform-specific-extensions

The `src/defaultRenderFunction.native.ts` module exports a default
function that throws an exception, which makes `getDataFromTree` fail with
a helpful error message in React Native. Calling `getMarkupFromTree` with
a custom `renderFunction` may be a little more work for React Native apps,
but that seems acceptable because server-side rendering is not a common
use case in React Native, compared to client/server web applications.
@benjamn benjamn changed the title Make react-dom a peer dependency, like react. Fix problems with importing react-dom/server in React Native. Nov 17, 2018
Copy link
Member

@hwillson hwillson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes look great @benjamn! Just one small optional comment. Thanks!

@@ -186,7 +186,7 @@ describe('SSR', () => {
expect(elementCount).toEqual(2);
});

it('function stateless components with React 16.3 context', () => {
xit('function stateless components with React 16.3 context', () => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we just remove these?

@benjamn
Copy link
Member Author

benjamn commented Nov 17, 2018

To be completely transparent, none of these techniques for pandering to React Native's special needs seems to be working. I'm at a loss for how to fix this without splitting the SSR-related functionality into a separate package (e.g. react-apollo-ssr) so that React Native can use react-apollo without getting confused by the dependency on react-dom/server.

benjamn added a commit that referenced this pull request Nov 27, 2018
Supersedes #2593.
Should fix #2592.

By pushing the react-dom/server import down into the relevant functions
that need it, we can avoid unconditionally importing that dependency tree,
which helps in environments like React Native where react-dom/server
either doesn't work or seems undesirable (see discussion in #2592).

Since the React Native bundler will still try to traverse the
require("react-dom/server") dependencies, it's important to prune that
dependency with a

  "react-native": {
    "react-dom/server": false
  }

section in react-apollo/package.json. Note that this does not prevent
React Native apps from using getMarkupFromTree with an appropriate
renderFunction; it simply prevents React Native's bundler from bundling
the react-dom/server dependency just because react-apollo is imported.

Tested with both [email protected] and @0.57.7 (Expo SDKs 30 and 31).
@benjamn
Copy link
Member Author

benjamn commented Nov 27, 2018

Closing in favor of #2627.

@benjamn benjamn closed this Nov 27, 2018
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 this pull request may close these issues.

2 participants