Ok first, big disclaimer here, I’m arriving on the scene quite late, and I know that JS in Foreman/Katello has a long and winding history. Also, I’m fairly new to React and Redux but have been reading up and attending talks/events around it. Probably lots of these ideas are coming from Thinking in Redux. Please correct me if I’m misinformed about anything.
I noticed some concerning things about our Javascript, namely the new React and Redux parts:
- Thunk - this is a pretty big issue IMO. It goes against the design patterns Redux is based on, namely event sourcing and Command Query Responsibility Segregation (CQRS).
** In short, event sourcing means that the sequence of events are the golden record, and the state doesn’t matter (think balance = sum(transactions)
if you have an issue with your balance, your bank will look through your transaction history to see if the balance is correct).
** CQRS aims to separate completely the parts of code that write state from the things that read the state.
Thunk is redux middleware that allows redux actions to return functions, allowing actions to do ‘stuff’ other than logging their action type and triggering other actions (I know it sounds like actions should do something, but think of them more as events and that ‘something happened’). If we want to react to actions, it’s clear from the redux docs that we should be using middleware (not actions, reducers, selectors, or any other flux pattern files) (aside: Redux is based on the Flux pattern). Of course, Thunk is popular, but that doesn’t mean it’s a Good Thing ;).
- Katello doesn’t follow Foreman’s structure; it doesn’t ensure storybooks are supported, despite using the stories directory to put all the stuff.
2a. Katello doesn’t put all the actions together, heck we don’t even put all the redux stuff together. It’s just in there with all the react components, faux middleware logic (not actually registered as middleware in redux). I like how Foreman structures their react_app and redux directories because it’s similar to the way that most other projects seem to organize stuff. (i.e. actions/
, reducers/
, selectors/
, middlware/{core,feature}/
, etc.).
-
Foreman has JS tests in the same directories as their code! I actually don’t mind the tests being ‘near’ the code, but in Katello we at least put the tests in a
__test__/
directory inside each JS source directory. It’s frustrating to use Ctrl-P or IDE/GitHub fuzzy search because of this (am I the only one?). -
Where are our selectors? This is a really useful part of redux that allows you to format api responses (which are generic and shouldn’t be globally formatted in actions or reducers) for specific pages (i.e. subscriptions product content needs to get info from the subscriptions actions and the products actions).
-
Action names are strings! And they’re really only there for us, the developers. We should be using that to our advantage and put useful information, such as the resource in question. Here’s an example from Thinking in Redux.
I think I’ll stop here. These are some of my initial concerns. I’m kind of wondering a bit about how all this came to be, whether there were design discussions, agreed-upon patterns to follow, etc. and if there are any documents from back then. Javascript is a unique language in that it allows developers to do whatever they really want without widely accepted best practices (foot.shoot()
), and that makes it a difficult language IMO. There are some super old school design patterns that have stood the test of time for good reason. More frameworks isn’t a good solution to most problems versus applying a known pattern, and some frameworks are mostly a pattern more than a framework (redux! :D). Worse, using a framework outside of its designed patterns adds complexity for little to no benefit.
Ultimately, we all have to be on the same page; new contributors are mostly copying what’s currently in the project, so let’s let them have nice, thoughtfully designed code. I’d also love to hear any JS concerns you have that I didn’t touch on.