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

Add style guides for TypeScript, React, and Jest #603

Merged
merged 11 commits into from
Jun 12, 2020
Merged

Conversation

WilHall
Copy link
Contributor

@WilHall WilHall commented May 22, 2020

This PR is a first attempt at creating style guides for TypeScript, React, and Jest. I added the three together (along with modifications to the JavaScript style guide) since they reference each other.

Tasks remaining:

General thoughts and questions:

WilHall added 5 commits May 22, 2020 18:40
This includes an example `tsconfig.json` (expressing how to configure TypeScript to be as strict as possible), and an `.eslintrc.json` and `.prettierrc` for auto-formatting and auto-fixing.
@WilHall WilHall requested a review from jferris May 22, 2020 22:58
@WilHall WilHall self-assigned this May 22, 2020

[Sample](sample.js)

* Use [ESlint] and [Prettier] for auto-formatting and auto-fixing
Copy link
Contributor

Choose a reason for hiding this comment

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

Do ESLint and Prettier eliminate the needs for the other guidelines here? (trailing commas, ===, etc)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

My thought was that ESLint and Prettier enforce the style guide, but that it was still worth listing the things we care most about directly in the guide. Alternately we could treat the ESLint and Prettier configs as the definitive source, but I find them to be less digestable for someone coming to the style guides and wanting to quickly read over all the guidelines.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Devil's advocate, @composerinteralia authored #606 today which removes the ruby guidelines in favor of just using and referencing standard.

I like the simplicity of that, and not having to maintain guidelines in both a configuration file and a textual guide.

Curious what others think as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Based on #606 (comment) and the discussion in #610 it looks like we might be trending towards removing guidelines that we can't automate and don't feel strongly about. Linking those from here so we can continue the conversation when we condense the guides.

@@ -0,0 +1,50 @@
# React
Copy link
Contributor

Choose a reason for hiding this comment

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

I think maybe this should be in best-practices instead (it's not about formatting) but the different between those is fuzzy. I wonder if they should be merged at this point.

Copy link
Contributor Author

@WilHall WilHall Jun 5, 2020

Choose a reason for hiding this comment

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

I agree, almost everything that came to mind for React was a best-practices thing (since style is already covered by the TypeScript guide).

I would be in favor of merging style and best practices guides. It might be worth calling out style guidelines vs best practices where both exist, but it also allows for guidelines which might be in more of a gray area.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have opened an issue to discuss combining them: #610

@jferris
Copy link
Contributor

jferris commented May 29, 2020

This is great! Thank you for putting it together. It would be good to get some feedback from folks who have worked more on React/TypeScript projects.

Copy link
Contributor

@stevehanson stevehanson left a comment

Choose a reason for hiding this comment

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

This is amazing!! I don't have much time today to work through this, but I took a quick look. I agree with most everything I've read, including the React best practices.

I'm interested in comparing the ESLint, Prettier, and tsconfig setup to what we're using in React Reference App.

style/testing-jest/README.md Outdated Show resolved Hide resolved
* Use [React Hooks Testing Library] for testing [React Hooks]
* Use [User Event] for simulating DOM events on React components under test
* Use [Fishery] for building factories
* Prefer placing test suite files alongside source files (e.g. `Thing.tsx`
Copy link
Contributor

@stevehanson stevehanson May 29, 2020

Choose a reason for hiding this comment

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

A pattern I've seen more often is to put tests in ./__tests__/Thing.test.tsx. I like that pattern since it keeps tests a bit out of the way but also almost colocated, but I've also seen this and don't feel too strongly.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I really like having the test files as siblings of the component they test, though that may be a result of how I'm used to searching for them.

One benefit of the __tests__ folder is that it does reduce noise in a directory where there are a lot of components. But I have also found it makes it a little harder to, at a glance, see if a component has a test suite.

I'm also open to either way - curious to hear others' thoughts on this!

Copy link
Contributor

Choose a reason for hiding this comment

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

I too prefer the tests as siblings! I find that the specs are better maintained when they arent hidden off in a folder. It seems to elevate the tests to more of a first class concern, which imo they should be.

Copy link
Contributor

Choose a reason for hiding this comment

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

I am of a third opinion that tests should not be alongside components at all and instead be in their own root level directory that mirrors the components directory. Basically how most Rails projects (along with many other languages and frameworks) treat tests.

Although the entire community seems to be more in favor of tests near components and we'd be against almost every project we're likely to work with. I also see John's point about tests being a first-class citizen and I agree, but I have not found them to be more or less maintained because they are near or far in the file system. That feels like it's been more of a cultural problem than a test placement one.

If these are the options, I would at least prefer they are out of the way a little in a sibling folder. I think it makes them easier to work with which could decrease the friction of maintain them.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have created #613 to continue this discussion

* Use [React Hooks]
* Use pre-built hooks when possible (e.g. [streamich/react-use])
* Use [custom hooks] to encapsulate stateful logic outside a component
* Avoid [Forwarding Refs]
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this saying to prefer passing a ref as a custom prop like inputRef instead of using forwardRef or to avoid passing refs altogether?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

My thought here is probably better summarized as Avoid nesting Forward Refs.

The guideline I'd like to include here is less about how you should pass a ref, and more around when their use might point to an overly complex design.

I have seen some cases where there are multiple levels of components forwarding a ref, and it becomes increasingly difficult to trace the ref from its assignment to its usage. Furthermore a ref forwarded multiple layers and used by some far-off component creates a coupling between the two components and also pollutes the component tree when debugging with the React dev tools.

These have just been my observations, curious to hear others' thoughts too.

style/typescript/.eslintrc.json Outdated Show resolved Hide resolved
style/typescript/.prettierrc Outdated Show resolved Hide resolved
* Prefer the `children` prop over [render props]
* Prefer using [TypeScript prop interfaces] over [PropTypes]
* Prefer the [short syntax] when using [Fragments]
* Prefer [React Contexts] over [Redux]
Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Contributor

@edwardloveall edwardloveall left a comment

Choose a reason for hiding this comment

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

Thanks for writing all this up!

style/react/README.md Outdated Show resolved Hide resolved
* Use [Jest](../testing-jest/README.md) for unit testing
* Use [styled-components] for CSS-in-JS
* Use [Apollo] with [code generation] when working with [GraphQL]
* Use [React Router] for routing in SPAs
Copy link
Contributor

Choose a reason for hiding this comment

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

There's something tricky here. I think SPAs are often not called for. Many SPAs (including the one you and I are working on now) do not need to be SPAs. If they must be SPAs, then I think encouraging React Router makes sense. I'm only worried that this feels to me like there's some implicit encouragement of SPAs. Does that make sense?

On the other hand, if someone made the mistake of picking an SPA, maybe we

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is similar to the css-in-js discussion above. I didn't mean to imply that we should build SPAs, just that if we are the routing solution of choice would be React Router.

But looking at this from the perspective of someone reading these guides for perhaps the first time without that context, it does feel like a recommendation towards SPAs as a default which shouldn't be our stance.

https://github.com/thoughtbot/react-suspenders/pull/1 handles the SPA case right now since it is based off create-react-app. Maybe that, too, should have an option for bootstrapping a non-SPA variant, perhaps using rails suspenders. Though I don't have the expertise using those two together 🙂

style/react/README.md Outdated Show resolved Hide resolved
[styled-components]: https://styled-components.com/
[React Hooks]: https://reactjs.org/docs/hooks-overview.html
[custom hooks]: https://reactjs.org/docs/hooks-overview.html#building-your-own-hooks
[streamich/react-use]: https://github.com/streamich/react-use
Copy link
Contributor

Choose a reason for hiding this comment

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

Ooo thanks for this! I didn't know it existed.

style/react/README.md Outdated Show resolved Hide resolved
style/react/README.md Outdated Show resolved Hide resolved
style/react/README.md Outdated Show resolved Hide resolved
style/testing-jest/README.md Outdated Show resolved Hide resolved
* Use [React Hooks Testing Library] for testing [React Hooks]
* Use [User Event] for simulating DOM events on React components under test
* Use [Fishery] for building factories
* Prefer placing test suite files alongside source files (e.g. `Thing.tsx`
Copy link
Contributor

Choose a reason for hiding this comment

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

I am of a third opinion that tests should not be alongside components at all and instead be in their own root level directory that mirrors the components directory. Basically how most Rails projects (along with many other languages and frameworks) treat tests.

Although the entire community seems to be more in favor of tests near components and we'd be against almost every project we're likely to work with. I also see John's point about tests being a first-class citizen and I agree, but I have not found them to be more or less maintained because they are near or far in the file system. That feels like it's been more of a cultural problem than a test placement one.

If these are the options, I would at least prefer they are out of the way a little in a sibling folder. I think it makes them easier to work with which could decrease the friction of maintain them.

style/typescript/README.md Show resolved Hide resolved
@WilHall WilHall marked this pull request as ready for review June 12, 2020 19:27
@WilHall WilHall merged commit e6e46a2 into master Jun 12, 2020
@WilHall WilHall deleted the feature/react-stack branch June 12, 2020 19:31
ericwbailey added a commit that referenced this pull request Jun 15, 2020
* master:
  Add style guides for TypeScript, React, and Jest (#603)
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

Successfully merging this pull request may close these issues.

5 participants