Lessons Learned from 2nd Round of Large-Scale ReactJS Development
- Protect your time by keeping your project simple.
Just because you know how to use the latest, flashy techniques doesn’t mean it won’t eat your time.
- Protect your time by knowing the project objectives.
It’s fun to dream about (and tell clients that you can make) amazing things, but consider purposefully refining your list of new adventures (aka “features”).
- Protect client satisfaction (and yours) by keeping clear expectations throughout the project.
Not just in your kickoff meeting, but as things shift and move, make sure to communicate the implications before you end up with a Leaning Tower of Pisa when you initially agreed to deliver an Eiffel Tower.
- Figure out API integration plan before getting started.
Or else it might come back to bite you and you’ll end up rewriting a bunch of code. GraphQL may be a viable solution for you.
How I Got Here
Part I: My Backstory
I’ve been a frontend developer since 2006. (My obligatory “I’ve-been-developing-a-long-time” reference is, “My first web dev job was on Joomla!”) My other claim to fame is, in 2014, I worked for InVision when there were maybe only 10 or 12 team members—but only for two months 😢. (They’re an amazing team, but I was young in my experience still and couldn’t quite keep up with the pace they had set. Clark and Ben are so hard-working and super nice guys! I highly recommend them.) Losing my job at InVision almost convinced me to jump ship and quit development altogether, so I tried a (very) short career in furniture-making, but quickly realized two things:
- The hourly rate of development is WAY better than my $0.05/hr making furniture—which is nice if I want to feed my wife and 4 boys!
- Also, I can make a significant difference in this world as a developer who loves doing good, which is very fulfilling—even though I’d rather be hiking a mountain than staring at a screen all day.
Part II: The Crash & Burn of My First Large-Scale ReactJS Project
- Single-page-apps (SPAs) have lots of complexities.
Can you build a custom frontend SPA for $50k? Maybe… but to think we could do a custom frontend AND custom backend for $50k was madness (at least in hindsight).
- It’s easy to get way too complex, ruhl fast.
We got really complicated really fast by being “smart” and “cool” or “cutting-edge”. For example, we used release-candidate versions; non-spec JS methods like class decorators to avoid the
.bind(this)typing; private and public npm packages with multiple npm registries; lerna packages to pull in similar parts to different parts of the app; our own React abstractions for class names and Redux store functions, etc.; and so on, and so forth…
- Scope creep is real.
Everything is possible in the development world, but the time to implement it is the big question mark. You cannot say, “Yes” to every idea that pops in your head and expect to stay on budget.
My Approach for Large-Scale React Project #2
- Be realistic.
I was very upfront about the time and cost of this project. Having a good picture of what it took me to make my first project helped me communicate realistic expectations for this second project.
- Keep it simple, sir (for real though).
I didn’t want any “magic” added this time. My thought throughout the project was, “If I pass this off to one of their developers, will they have a clue what’s going on?”
- Set boundaries and expectations.
Easier said than done. But if you care about your bottom line, this is critical. Don’t let them think that any change is easy. If you’re desperate for the work, you’re more likely to make concessions you wish you didn’t make later on in the project.
What Worked Well
Using create-react-app (and not ejecting it)
This helped keep things simple. There’s plenty you can do with create-react-app without having eject and make custom configurations. If I started thinking about trying some bleeding-edge technique and it required me to eject create-react-app, it was an easy decision—no.
Naming Convention + File Structure
I know options are nearly endless for this, but I really liked what I ended up with. I put all my actions, components, constants, reducers, and utils in
/src/scripts/ so I had
/src/styles/ for anything not related to one component. This structure helped me find files quickly and find their related files easily.
By the way, this setup was inspired by “The 100% correct way to structure a React app (or why there’s no such thing).”
│ ├── actions
│ │ └── moduleActions.js
│ ├── components
│ │ ├── App
│ │ │ ├── App.css
│ │ │ ├── App.js
│ │ │ ├── App.scss
│ │ │ ├── App.test.js
│ │ ├── buttons
│ │ │ ├── SomeButton
│ │ │ │ ├── SomeButton.css
│ │ │ │ ├── SomeButton.js
│ │ │ │ ├── SomeButton.scss
│ │ │ │ ├── SomeButton.test.js
│ │ └── ...
│ ├── constants
│ │ └── ...
│ ├── reducers
│ │ └── ...
│ ├── store.js
│ └── utils
│ └── ...
Mocking Data With json-server
It was really easy to mock data for my react frontend with json-server. Even though I had to do a more advanced setup with it this time (e.g. use a server.js file and get into lowdb), it was really nice to have a lot of the DB functionality out-of-the-box.
What Didn’t Work So Well
API Integration Failings
Despite my best efforts to fully document in Postman the API I created with json-server, the off-shore API team seemed to ignore it. As a result, our API’s were out of sync in many ways which resulted in days (if not weeks) of reworking code (on my side AND their side).
Set the Budget and Shorten the Timeline
I originally estimated the project taking 6–10 weeks and specifically said, “I don’t think it will take any less than 6 weeks.” But due to budget constraints, we decided we would try to figure out what we could accomplish in 5 weeks. As it turned out, at 6 weeks we had a decent beta version, but due to API integration, there were still days (if not weeks) worth of work left to do.
Getting Ready for Round 3
So how will I do it differently for Round 3?
I’ve not heard of the value in GraphQL until talking with a colleague about this blog post. He mentioned how well it has worked for their frontend and backend team. Basically, it’s an API definition and your work is not done until it matches that definition. This allows frontend and backend to work separately at their own pace but have a common place to meet in the middle.
Since GraphQL allows to grab all the data you need from multiple resources in a single request, it should make things easier on the frontend and backend teams.
Be More Intentional About Deliverables
I prefer to work (and get paid) in weekly sprints. At the beginning of each week, you clearly lay out the deliverables for that week. By the end of the week, you should have completed and sent all the deliverables. This allows everyone to stay flexible (and “agile”), but it also gives your client the security of a “fixed-bid” setup—they know what they will have in-hand at the end of that week.
In project #1, this was non-existent. Project #2 had daily standup meetings, but we never talked about our weekly deliverables. As a result, urgent items overruled and stole time from the more important (but forgotten) objectives.
For round 3, I would like to just have one meeting per week with the sole objective to clearly define the deliverables for the week. This needs to be a requirement in my mind to have a truly successful project.
- Stay simple.
- Keep clear expectations throughout the project.
- Have a plan when change requests come.
- Find solutions for any integration ahead of time if applicable.