Nothing Special   »   [go: up one dir, main page]

Architecting Frontend Projects To Scale

Download as pdf or txt
Download as pdf or txt
You are on page 1of 7

Architecting Frontend Projects To Scale

dev.to/mmcshinsky/why-frontend-architecture-matters-1ldj

I, like any other web developers and engineers, prefer to make my work life as sane as
possible. Having structure not only keeps life a little more pleasant, but is critical to
scaling and even allows creativity to flourish! Having a clear structure and consistent
plan in my code keeps me performant, allows me to better plan for scaling, avoid
unnecessary refactoring code sessions, and understand the app hierarchy without
having to re-learn each component or service every time I need to change or upgrade
features.

Pretty much most developers who start out with most JavaScript frameworks use a
built-in CLI (command line interface) that another team has built for the said
framework in order to jumpstart the development process with minimal effort. Nothing
is inherently wrong with this approach and this saves developers a lot of time from the
first wave of configuration bugs. The next step after setup is to build out your code
structure. Everyone, without a doubt, has opinions on this and will strongly defend
their approach. I too have molded my own architecture that fits my projects as they
grow.

In this article we'll use the create-react-app starter structure as a base configuration that
anyone can start with when following along with this article and not get lost.

What this is and isn't


This is a dive into project structure and package opinions. This is not a comprehensive
study into the "musts" and "must nots" of what libraries and packages to use and avoid.
Your project is a living structure! My views and opinions apply to the issues you face
may or may not have merit depending on the needs of your end users or development
team. Hopefully, this article will provide another valuable perspective into keeping
yourself and teams organized when working on small and large projects.
1/7
Basic Configuration
So you don't have to dig through links and websites, here is the create-react-app
document structure you will see when starting out.

my-app
├── node_modules
├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── manifest.json
│ └── robots.txt
├── src
│ ├── App.css
│ ├── App.js
│ ├── App.test.js
│ ├── index.css
│ ├── index.js
│ ├── logo.svg
│ ├── serviceWorker.js
│ └── setupTests.js
├── .gitignore
├── package.json
├── README.md
└── yarn.lock

I have a decently strong opinion about the src and components folder. Do not use the
src or components folder for everything! This doesn't scale for larger applications and it
is super annoying to dig through giant flat lists of .js files when you want to find a
particular piece of code.

Uppercase versus Lowercase


Let's get this one out of the way quickly. React developers likes to define component
specific files as uppercase based on said conventions from popular developers in this
space. If you are on someone else's project that is uppercase, don't go changing all
the file names. A standard has been set and there is a right time and a wrong time to
approach changing an individual project's standards.

On the other hand, if you are going to be working on my project, lowercase file names is
the standard we'll be living by. It makes sense, easy to read, and pretty much all other
project types and frameworks use this approach. Also, hyphens between words is a
must even if it makes it a tad bit longer than you are normally comfortable looking at.

Google's File Naming Standard

New Frontend Architecture


If you are just looking for an example for this article of how to structure your next
project, I will link a simplified version of it to you right here. If you want to keep
2/7
reading about why it is structured this way and understand the purpose of this
architecture is, please, continue reading. We are going to adopt a MVVM architecture to
manage our project.

Most of your projects starting out are probably going to be 100% frontend based
working with an internal or external api or a separate data source that isn't bound
tightly to the frontend code. Our architecture may alter, for example, if we were to
structure our project with server side rending in mind. Let's take a birds eye view of
what we have in our new app's folder.

my-app
├── assets
│ ├── images
│ ├── scripts
│ └── styles
└── src
├── components
├── constants
├── models
├── routes
├── services
├── views
├── utilities
├── index.css
├── index.js
└── serviceWorker.js

index.js
In the provided example, index.js is used heavily to export multiple components or
represent the parent components (container) of a view or shared element.

Assets
Let's break assets down a bit and understand what is going on:

assets
├── images
├── scripts
└── vendors
└── styles
└── vendors

The assets folder within the src folder is usually located here to represent internal only
resources that should not be readily available to the public as a stand alone, linkable, or
downloadable resource. Pdfs, downloads, blog post images, etc... could be stored
instead in the public folder for mass distribution.

3/7
I'm not going to recommend a specific sub structure for images. I don't even have an
defined opinion except probably keeping images grouped by pages, features, layouts,
and specific use cases. Scripts will usually be third party libraries that don't have
natural integration (import/require) into your project and you are okay with them living
in the start or end of the body of your html document. The same goes for the styles
folder.

The reason there is a vendors folder is because it is much easier to handle internally
written files that live in the scripts and styles folders in the base folder while
external/third party libraries will live in the vendors folder. This will make it much
easier to reference visually for team members and even add associated overrides (if
your can't modify the main libraries file due to possible future updates), e.g.
bootstrap.min.css, bootstrap-overrides.min.css. Not ideal for some... but it is organized
and easy to refer to. Remember, scripts and styles are primarily meant for third party
libraries that will not be living within your main projects JavaScript documents and
stylesheets.

Components
We are going to keep the components folder because I still believe that it is important.
It's use should not be to hold your project but rather to hold components that will be
shared throughout your project. This includes: layouts, private, public, templates,
sidebar, header, etc... What ever you want that will be used more than once by multiple
modules or views.

components
├── buttons
├── forms
├── layouts
├── partials
├── private
│ ├── header
│ ├── sidebar
│ ├── card
│ └── modal
├── public
│ ├── header
│ ├── pricing-tables
│ └── footer
└── shared

Note that I like to divide components that whose sole purpose belongs to the customer
facing website or the user facing app by public and private. They could also be names
website and app or you could keep all components folders on the same level under
components. All that matters is giving a home or primary location to reusable
components for your project. When it comes to the plurality of folder names, I am still
undecided due to the high variable use cases of component naming.

4/7
Models and Services
Let's bundle these together. Using a MVVM approach as inspiration, models will hold
constructors that will mold incoming and outgoing server data into repeatable and
scalable objects. Services will hold the generalized and specialized functions that send
this data back and forth between the client and the server. Services will also hold state
based solutions like redux configurations or global context.

├── models
│ ├── client.js
│ ├── product.js
│ └── task.js
└── services
├── context
├── redux
└── api
├── clients.js
├── products.js
└── tasks.js

Constants
Anything that will be referenced globally in the app should be stored here. This can
include:

1. Unique IDs from a database (id or guid).


2. Config values for difference api services that aren't part of an .env file.

Note that this folder could be substituted for .env file(s) holding all information if it is
considered dynamic based on how your hosting is configured or company policy is
enforced.

Utilities
Utilities can be one or many files that define small utility functions that your app will
utilize. This may be things like specialized dates, formatters, or one use functions that
are needed often but don't belong to any one component or module in your project.

Routes and Views


Most likely, most of your day will live between here and components, putting together
the finalized code passed from designers to you for implementation. You have already
written models and services to consume the data from the server, and now you need to
utilize it. A basic view structure may look like the example below.

Putting routes into their own folder has been something newer for myself. Keeping
routes together and importing the views for the routes has made it easier to manage
how my more recent apps change as business requirements evolve. This is more of a
5/7
personal preference than an insisted pattern for others to use.

routes
├── components
│ ├── private.js
│ ├── public.js
│ └── index.js
├── index.js
views
├── private
│ ├── clients
│ ├── dashboard
│ ├── products
│ ├── tasks
│ └── index.js
├── public
│ ├── about
│ ├── auth
│ ├── home
│ └── index.js
└── shared

Once again, I like to make sense of how my projects is structured visually by separating
the public facing website and customer facing internal app. Each of these view
component folders is where the view for a route is defined.

client
├── index.js
├── client-redux.js
├── client.scss
├── client-styles.js
├── tests
├── components
│ ├── modal
│ └── // unique components for view
clients
├── clients-redux.js
├── clients.scss
├── clients-styles.js
├── index.js
├── tests
└── components
├── modal
├── list-item
| ├── list-item.scss
| ├── list-item-styles.js
| └── index.js
└── // unique components for view

This example contains a range of possible files you may be using in your project. We
also break out unique child components to the view that wouldn't make sense to have in
our shared component folder by keeping them inside the view's component folder. By
adopting a heavy view approach that contains just about everything related to the view,
6/7
we can utilize maintaining new and old code as it is implemented and deprecated. This
allows us to be lean and agile in our development cycle. We also avoid developer code
and pull request overlap as different developers work on different features.

Conclusion
With that, we have defined the general outline of a more scalable and maintainable
architecture. To an extent, this architecture is agnostic to your frontend libraries and is
meant to be modified to the needs of your team. As projects are living and ever
changing organisms, and I am fallible, please let me know if I am missing anything.
What are your favorite or preferred approaches to frontend structure? Let me know in
the comments below. I would love to hear from you!

If you want a starter version of this, a link has been provided here: React-Starter

If you found this helpful or useful, please share a , Ƅ, or . Thanks!

7/7

You might also like