Building an Enterprise React Application, Part 2

Let's take a look at the build tools, processes and front-end code organization for an enterprise React project.

In the first part of this article, we talked a lot about architecture. This time around we’ll be looking at the build tools, processes and front-end code organization on the project. Many of the tools we used are popular and well-tested and I can recommend using any of them without hesitation.

I’d like to begin by briefly talking about adding dependencies (libraries, packages, e.g.) to your JavaScript projects. If you’re coming from a Drupal background (as many of our readers are), then you may be quite cautious about adding dependencies to your projects. This is understandable since adding excessive modules to a Drupal site can have serious performance consequences.

With JavaScript projects, the situation is different. It’s very common to use micro-libraries, sometimes, quite a few of them. The performance concerns in doing so in a JavaScript application are not as great. Rather than the number of dependencies, the focus should be on the size of the file(s) clients need to download to run your app.

The use of small libraries is a huge asset when building JavaScript applications because you can compose a tailored solution for the project at hand, rather than relying on a monolithic solution that may include a bunch of things you’ll never use. It’s really powerful to have that versatility.

Build Tools and Processes

Let’s look at a few of the key tools that the front-end team used on the project:

Let’s talk about these one by one…

Npm

On this project we used npm to manage dependencies. Since then, however, Facebook has published yarn, which is probably the better choice if you’re starting a project today. Whether you use yarn or npm, the actual modules will still come from the npm registry.

Another thing I’d like to mention is our use of npm scripts instead of task runners like Grunt and Gulp. You can use npm scripts to do things like watch files for changes, run tests, transpile your code, add pre and post-commit hooks, and much more. You may find task runners to be redundant in most cases.

Webpack

In even a small JavaScript application, you will likely have your code distributed in a number of different files—think ES6 modules, or React components. Webpack helps gather them all together, process them (ES6 transpiling, for example) and then output a single file—or multiple files, if that’s what you specify—to include in your application.

Browserify does much the same thing as webpack. Both tools process files. They aren’t task runners like Gulp or Grunt, which, as I mentioned, were unnecessary for us. Webpack has built-in hot swapping of modules, which is very helpful with development and is one reason why it’s widely preferred over Browserify for React projects.

Babel

Babel is an indispensable part of a JavaScript build process. It allows developers to use ES6 (aka ES2015) today, even if your target browsers don’t yet support it. There are huge advantages to doing this—better variable scoping, destructuring, template literals, default parameters and on and on.

The release of new versions of JavaScript now happens annually. In fact, ES7 was finalized in June of last year, and with Babel you can use most of those features now. Unless something significant changes, transpiling looks to be a permanent feature of JavaScript development.

PostCSS

Do you use Autoprefixer to add vendor prefixes to your CSS rules? If yes, then you’re already using PostCSS. PostCSS is simply a JavaScript tool used to transform CSS. It can replicate the things Sass and Less do, but it doesn’t make assumptions about how you want to process your CSS files. For example, you can use tomorrow’s CSS syntax today, write custom plugins, find and fix syntax errors, add linting to your stylesheets, and much more. If you’re already using a tool like Autoprefixer, it may make sense to go all in and simplify your build process.

ESLint

After first using ESLint, I wondered how I ever got by without it. ESLint helps enforce consistent JavaScript code style. It’s easy to use and if you’re in a big team, it’s essential. There’s also a plugin to add specific linting rules for React. Quick note, there is a new project called prettier that you might prefer for enforcing consistent code styling. I haven’t tried it out yet, but it looks promising.

Stylelint

I alluded to stylelint above when I discussed PostCSS. It’s a linter for your CSS. As with ESLint, it provides great value in maintaining a consistent, readable codebase.

Testing tools

We used Mocha for a JavaScript testing framework and Chai for the assertion library, but there are other good ones. I also recommend using Enzyme to help with traversing your components during the testing process. We didn't use it on this project, but if we were starting again today we certainly would.

Build Tools and Processes Summary

You may have noticed a common thread between all the tools I listed above. They’re all JavaScript-centric. There are no Ruby gems or wrappers written in C or Java. Everything that is required is available through npm. If you’re a JavaScript developer (or you want to be) this is a big advantage. It greatly simplifies things. Plus, you can contribute to those projects to add functionality, or even fork them if need be.

Another thing to note, we’ve discarded tools that we could do without. PostCSS can do the job performed by Sass, so we went with PostCSS since we’re already using it for vendor prefixes. Npm scripts can do the job of Gulp and Grunt, so we used npm scripts since they are available by default. Front-end build processes are complex enough. When we can simplify, it’s a good idea to do so.

File Structure and Separation of Concerns

What is meant by the term, “separation of concerns”? From the perspective of front-end development, it’s commonly understood to mean that files that do similar things are separated out into their own directories. For example, there is commonly a folder for JavaScript files and another for CSS. Within those folders there are usually subfolders where we further categorize the files by what part of the application they apply to. It may look something like this:

JS/
  app.js
  Views/
    Header.js
CSS/
  global.css
  Header/
    Header.css

With the structure above things are being grouped by technology and then are further categorized by the part of the application in question. But isn’t the actual focus of concern something else entirely? In our example above, what if we structured things more like this?

app/
   App.js 
Header/
  Header.js
  Header.css

Now we have both the CSS and JavaScript files in a single folder. Any other file that pertains solely to the header would also go in this folder, because the focus of concern is the header, not the various technologies used to create it.

When we first started using this file structure on the project, I was uncertain how well it would work. I was used to separating my files by technology and it seemed like the right way to do it. In short order, however, I saw how grouping by component created a more intuitive file structure that made it easier to track down what was going on.

CSS in JavaScript

Taking this line of thinking to its logical conclusion, why not just include all the code for a component in one file? I think this is a really interesting idea, but I haven’t had the opportunity to do it in a real project yet and we certainly didn’t do it on this project.

However, if you’re interested, there are some good solutions that I think are worth consideration, including styled components and Aphrodite. I realize that this suggestion is a bit controversial and many of you reading this will be put off it, but after working on React projects for the last couple of years, it has started to make a lot of sense to me.

Wrapping Up…

I find it remarkable how much time is spent on the two topics we’ve addressed here. Front-end build processes can be complex. Some tools, such as webpack, can be difficult to get your head around at first and it can feel overwhelming when you’re getting started.

There are a few React starter projects I’d like to suggest that may help. The first one is from Facebook, called Create React App. It can help you get started very quickly, but there are some limits. Create React App doesn’t try to be all things to all people. It doesn’t include server rendering, for example, although you can add it yourself if needed.

Another very interesting project is Next.js. It’s a small React framework that does support server rendering, so it may be worth trying out. Server rendering of JavaScript applications is important for many projects, certainly for any public websites you want build. It’s also a fairly complex problem. There isn’t (to my knowledge) a simple, drop-in solution available at this time. Next.js may be the simplest, best supported path to getting started on a universal React app, but it may not be right for your team or project.

We’ve created our own React boilerplate that supports server rendering, so feel free to look it over and take away what’s useful. Of course, there are many other React boilerplate projects out there—too many to mention—but I encourage you to look a few of them over if your team is planning a React project. Reviewing how other teams have approached the same problems will help you decide what’s going to be the best choice for your team.

Published in:

Get in touch with us

Tell us about your project or drop us a line. We'd love to hear from you!