What is the proper way to specify gatsby, react dependencies for a theme?February 14, 2019 at 12:19pm
Should we define them as peer dependencies? If yes, then with what ranges (this blog post recommends to use "lenient" peer dependencies)?
In the recent Build a Gatsby Theme With John Otander — Learn Stuff With Jason screencast they, chose to define the gatsby and react as peer dependencies (and duplicate them as dev dependencies), and in the gatsby-theme-examples we have:
- for gatsby-theme-blog-core as a dev dependency
- for gatsby-theme-blog they are specified in regular dependencies.
February 19, 2019 at 4:34pm
I am also confused by this – I admit I don't clearly understand John's and Jason's choices. I respect there's probably no "one right approach" so I'm trying various options -- but a blog article on this topic would be immensely valuable for the community.
I suggest the article could be about:
- Dependencies, all the subtle decisions, and 'why' or 'why not' do it this way or that
- And working with multiple repos - like, a theme as a workspace? or a theme as a submodule? or a theme as a submodule in a workspace? or how to use a theme you've published yourself versus how to use a theme that someone else published?
The trouble is, I'm not the right guy to write the article!
February 21, 2019 at 8:44pm
This is a great question that unfortunately doesn't have the most straightforward answer. It boils down to "it depends". I believe Chris will be writing a more in depth post on the topic so I'll give my 2c and keep things short.
Peer dependency - Bring your own React
Having users install their own React versions is by far the most flexible, and helps to ensure that other versions of conflicting React don't end up in the same site. This bloats bundle sizes, and more importantly can cause unexpected behavior (especially with Hooks). This also allows for users to update React on their own terms, like if they want to install an alpha version.
This approach results in a theme that is more composable with other themes as well because no assumption is made about how/which React is installed. npm or yarn will also warn on conflicting versions which is nice.
Dependency - All in one
If you're building a more monolithic theme, or a collection of interoperable themes it might make sense to include React dependencies. This keeps things simpler for end users because all they have to do is install your theme and Gatsby
npm install --save gatsby gatsby-theme-awesome. This is a great end user experience! However it also comes with other issues because it's more difficult to use with another theme that also includes React as a dependency (if their versions conflict). If a user wants to install a different version they'll also have to mess around with resolutions which isn't always desirable.
This is method is useful if your theme is intended to abstract away even React itself (this is possible with themes!) because they will only be doing something like writing Markdown.
Also, if you want to build a "white-labeled" version of a theme that includes its own CLI, including React ensures it's seamless.
Additionally, in most contexts
gatsby should be included as a
peerDependency to ensure that there is a warning if a theme is installed without
gatsby being installed. Gatsby will error out when it isn't specified in the
package.json when the build is run.
February 22, 2019 at 9:02am
Thank you @johno good points. Initially I thought that React is already a required dependency of Gatsby, but after checking it I found out that it is a peer dependency, interesting.
March 3, 2019 at 5:43am
I was just building a theme & had the exact problem. So what did you guys come up with? I would love to know since there are different answers everywhere..I'd love to go with something simple like
- Where to install it as
- Where to install it as a
dependencyas I'm too confused right now
March 15, 2019 at 5:31pm
@johno great explanation, thanks a lot! 🧡
I got the general concept, now talking about specific cases: say I add Typescript to a theme - which adds 3 packages (babel transform, typescript and gatsby-plugin-typescript) - but the user can flag an option to disable TS... asking the user to bring their own packages can be a lot to ask of newbies, causing anxiety and confusion; however, including it as a dependency will increase the installation cost and can incur in conflicts later on...
Where would you draw the line between peer and dependency for cases like this?
March 18, 2019 at 7:11pm
AFAICT these can be direct dependencies of you Theme because themes themselves can specify their own compilation with the
onCreateWebpackConfig hook: https://github.com/johno/gatsby-themes/blob/efb510f5e037605c2318166d0eb37f43d0454a71/packages/gatsby-theme-blog-base/gatsby-node.js#L160-L172
Also, these are build time dependencies so won't cause issues like multiple Reacts bootstrapping on the client.