The Case for Front End Infrastructure

Steve Armstrong
Universal Language
Published in
7 min readMar 11, 2019

--

Photo by Joshua Sortino on Unsplash

Front End Infrastructure sounds heavy-handed. Why would we want to overcomplicate the Front End even more? Well the answer is: it’s complicated. I’ve interviewed around 20–30 developers in the past few years and what I’ve found is the following.

A lot of developers are skilled in coding but don’t dig deep into building and deploying apps.

Why? It’s a mix of reasons, but the best reason I can think of is that it’s very dry and people want to get to writing code. This is probably fine, and in many cases even desirable. However, there are tradeoffs.

Throwing your infrastructure over the wall to another team can result in redundancy and a process that is not ideal. To define the process, you need to know how it it works.

So let’s start with what this infrastructure should consist of. We can break it down in to four main areas:

  • Application Development
    - Components/Style Guide
    - Versioning
    - Bundling
    - Shared Configurations
  • Local Development
    -
    Environment Set Up
    - Web Server
    - Hot Module Reloading
  • Deployment
    - Continuous Integration
    - Shipping
  • Monitoring and Event Tracking
    - Error Monitoring
    - Key Performance Indicators

Keep in mind that I am shaping this around the stack that I use professionally which relies on React and Node. I tried to steer away from unfamiliar territory. I didn’t want this to become a conversations around “best practices” for framework “x”. With that said, you could apply this process to any set of technologies.

This is largely based off of the work I’ve done at Smartling, where I’m a Front End Lead. Our team has done a lot to improve our infrastructure over the past four years. We continue to improve our process daily.

Application Development

Components

Components are the building blocks of all Front End applications. They encourage reusability and composition. They prevent developers from reinventing the wheel.

Even if you plan on using an open source framework, you should still wrap the components. Defining your own API allows you to switch out the implementation details without breaking contracts.

Component Style Guide

Now that you got your component library, you should host it so that teams can observe and approve changes. For this, you can use a style guide like Storybook.

A style guide is a good way of formalizing a contract between Product, Design and Engineering. It allows team members to catch implementation issues before they go into active development. You can read more about this process in my article How UI Component Architecture can Solve Organizational Problems.

Versioning components

If you are going to use your components on more than one project or device, versioning components is a must.

To version your components, you are going to need a private module registry like NPM Enterprise.

At first, versioning sounds like it will slow you down. Having push button updates (monolith) for an entire platform has the appearance of being faster. Really it’s a QA nightmare. It also requires all teams to be ready to upgrade at once, which can be challenging.

Versioning has many challenges. You’ll need to solve “who can” and “when to” publish. For this you might consider using conventional commits and configure your CI server to pick up the changes.

Bundling

Bundling is the process where your source code transforms into an application you can distribute to your users. It solves many problems: allowing different module types to talk to each other, transcompliation, minification, compiling CSS Modules and more. A lot of these processes can be handled in isolation, but bundlers make it easy to tackle all these tasks in tandem.

Many bundlers promise zero-configuration, but that isn’t something I’ve experienced firsthand. At some point, you’re going to need to get your hands dirty. Having someone around who knows how it all works is priceless.

Bundlers are not the only way to accomplish some tasks. Some people prefer to use a task oriented solutions like Gulp or Grunt. Even though they are viewed as “old-school”, their simplicity should not be denied.

In many ways, bundling can be the bane of Front End development. How we build the Front End has gotten very complex and we could probably stand to step back and do some re-evaluation.

With that said, bundlers solve a lot of problems that you can’t avoid. You want to avoid manually referencing files that need concatenating and minifying? You’ll need a bundler. You want to use Hot Module Replacement? You’ll need a bundler. You want to seamlessly communicate between CJS modules and ES6 modules? You definitely need a bundler!

Shared Configurations

The developer experience is key to writing good software. Providing a consistent experience when switching projects helps ease the cognitive burden of context switching.

Sharing configurations between projects can help provide consistency. Shared configs answer certain questions like, “What version of JavaScript do we write in”, “What linting errors do we care about” or “What browser versions are we targeting”.

Shared configurations are also a good way to streamline fixes for development bottlenecks. They eliminate the redundancy of individuals solving the same build issues on different projects.

Local Development

Environment Set Up

Your first goal should be to create a local development process that takes as little installation as possible. The whole set up should take around 10–15 minutes.

Web Server

The web server boot up should be a one word npm script. yarn start or npm start. The script itself might have a chain of commands like: yarn webpack-dev-server && yarn etc.

Apps can be served by something as simple as webpack-dev-server. However, unless you are writing a stateless UI library, you’re going to need some data. For this, you’ll need some kind of proxy. For me, the golden rule is that hitting this proxy should be seamless. Developers shouldn’t need to edit config files to get it working.

What you absolutely want to avoid is forcing developers to build environments that they don’t own. This will only cause headaches for your Front End team, and increase their ramp-up. I worked hard to ensure at Smartling that our ramp up for new developers from “git pull” to active coding was a few hours.

Hot Module Reloading

On top of the set-up and start-up being fast, you want actual development to be fast as well. This is where Hot Module Reloading comes in.

Hot Module Reloading lets you reload parts of the application without having to do a page refresh. Sometime, it takes extra effort to setup depending on the complexity of your application. This extra effort will pay off dividends by increasing the pleasure and overall speed of development.

Deployment

Continuous Integration

Once a developer has merged to master, they need to get their code to users. It’s not as simple uploading everything to an S3 bucket. You’ll need to build and verify your changes before deploying. That’s where a CI server comes in.

CI servers come in all flavors. Some require lots of developer configuration like Jenkins. Some are going to be more turnkey, like Travis CI or Codeship.

Regardless of what you use, you are going to need to know how they work and how to set up plans for developers. For the Front End, this usually requires bundling code, running unit and integration tests, localizing assets, deploying to staging and then promotion to production.

At Smartling, we have three types of assets we deploy. NPM modules, web components and applications. Each has it’s own requirements. For instance, npm modules require us to publish.

Web components on the other hand don’t need publishing. Instead, we need a way to point our applications to the latest versions. For this, we built our own internal registry that keep our applications in sync.

Shipping

Next, you need to get your app in the hands of the users. There is a myriad of ways you can serve your app, but a typical set up will look something like this:

Unfortunately, this is where a lot of Front End developers drop out and kick everything over the wall to devops. If you are doing this, you are doing it wrong.

Even if the Front End does not directly own the web infrastructure, the team should intimately understand it. They should be making sure that assets have the correct headers or that content is gzipped.

They should be paying attention to bundle size and measuring its impact on the end user. You should align your bundle caching strategy so that how your assets are deployed has the most minimal impact on how they are downloaded by the end user.

Monitoring and Event Tracking

Error Monitoring

Once your stellar app is available for millions of people, you want to make sure nothing goes wrong. That’s why you’ll need monitoring to let you know what is happening. There are plenty of solutions and many of which like Sentry, Rollbar or TrackJS require very little configuration

Key Performance Indicators (KPI)

Error monitoring only captures the negative, what about the positive? You want to be able to show all those fancy trends that demonstrate how your app is being used. Does it solve real world problems?

For this, you’ll need something that can crunch and aggregate events across millions of records. Some tools to consider are New Relic Insights or even Google Analytics.

Conclusion

Well that’s it. It sounds like a lot, but the goal should be to reduce friction between writing code and deploying applications. If you don’t approach it holistically, you are going to end up with a lot of redundancy.

Even if you decide against streamlining infrastructure, you aren’t going to avoid the requirements. Sure, you can cut corners here or there, but it’s going to put you at a disadvantage. Not using a component library, there goes consistency. Not using a CI server, there goes stability and wasted time on manual processes.

My advice, find the most elegant solutions so you can reduce complexity. Prioritize maintenance (upgrades, bugs, etc.) even when it’s inconvenient (because it’s always inconvenient). Upstream work will build downstream momentum. Most importantly, don’t take this stuff for granted. You’ll regret it.

--

--