In this article, I am going to describe 16 steps that front-end developers should go through when planning a front-end web application. These steps aim to cover the entire life-cycle of a front-end application. However, before diving in, I need to clarify a few front-end terms that remain unsettled in the industry.
Third, crafting a web application with just the right parts is a skill likened to building a race car. A professional race car is not bought off the lot at the local car dealer and neither should an entire front-end application solution. Thus, the developer I’m speaking about is, more than likely not, a fan of all-in-one integrated development environments, full-stack development tools, or heavy handed frameworks in general.
I also need to clarify that the front-end developer I’m speaking about works on a large team of developers and would rarely be responsible for developing the entire app front-to-back, the data api, or any back-end services consumed by the front-end team. Thus, tools that offer integrated full stack features are avoided by this type of front-end developer.
The last clarification I need to make is that I don’t presuppose that building an enterprise grade app requires a monolithic integrated framework from a single vendor and that it’s completeness alone makes it an enterprise-worthy solution. This, I believe, is a dying concept from the early years of software development. Modern, front-end engineers favor loosely coupled systems that avoid vendor lock-in (i.e. hard to change systems) and lock down (systems that don’t play well with others). These modern systems are not only viable for the enterprise, they can elevate a lot of the downfalls associated with enterprise software. In my opinion, these styles of tools which were once considered helpful to developers, are now considered harmful.
An example of a more modern stack of loosely coupled tools for building enterprise applications is Kendo UI. It provides enterprise grade tools, but it won’t lock you in or lock you out of being able to change, evolve, or use it with other third party solutions.
With that all said, let’s begin.
In a nutshell, API first development means you document, build, and test your API first. This means you have a relatively stable API before you write any application code.
Note that during API construction, front-end developers should be prototyping minimal viable features using the API and providing feedback to the API engineers.
The main reason to follow API first development is to reduce the possible deficiencies in the API from being amplified in the data layer and causing ten-fold pain and misery. I’ve found the following quote, from @julio_ody in the Pragmatic Guide to Backbone.js Apps book to be painfully true:
“data layer will absorb your API’s ugliness and amplify it by one hundred” – @julio_ody
You want to do everything in your power up front to avoid having to make up for your API’s deficiencies in your application logic. Not having a documented and mostly solidified data API before a line of application code is written, is asking for pain and misery in the future. Build your API first. Document it, test it, and then be ready to evolve it as you build out the applications that use it.
It’s worth noting that it may be assumed that security and authentication details will accompany the API. It is also assumed that the API developers will provide a development API to be used for development. Using the same data API for both development and production should never be an option.
To manage the development of the front-end application, you’ll minimally need to select the following software management tools to manage code, assets, and team members’ tasks:
|software management tools||examples|
|ticketing system (i.e. bugs)||github|
|version control system||github|
|document/asset storage||slack & conceptboard|
|team communication||slack & conceptboard|
Pick these up front and make everyone use them. If you have a team member who won’t get on board with the tools, then you have an enemy within. Please don’t take my last statement and use it as a tool to force development tools on developers. Development tools and development management tools are not the same thing. Developers should never be forced into something like an IDE, text editor, or command like text editor.
Each project is going to be different and will, of course, have its own specification relevant to the problem being solved. However, a foundational specification can be created before you spec out the actual application. These specifications are important to establish upfront and should remain unchanged during development. All decisions made after the foundation spec will depend on the decisions made in the foundational specification.
Make sure you carefully consider each specification mentioned below.
|devices & min. resolutions||laptop/desktop & 1024×768|
|OS/browsers||OS X & Win 8 on ie9+, FF, Safari & Chrome, latest|
|languages (i.e. localization)||English & Bulgarian language|
|cultures (i.e. globalization)||English & Bulgarian culture|
|accessibility||section 508 & WAI-ARIA 1.0|
|SEO||none (done on product site)|
Note: What I’m about to say is contentious. You might just skip this part if you are easily offend by a differing opinion.
I do not mention responsive design or mobile first when creating a foundational specification for front-end applications. I did this because I assume no one who builds user-centered web application interfaces would do this for an application. In general, you should build applications (user heavy data interactions) specifically to the needs of the user and the device they are using. Constructing a single code base that can meet the needs of users on multiple devices is simply too problematic on too many fronts. Mission critical interactions are too diverse across devices and thus the code is extremely diverse. This much diversity in the code is unnecessary complexity. A RWD web app is a concept that seeds complexity. I’d avoid it. With that said, and before you send me textual hate, I do believe responsive design has its place among websites. My main point is that it loses its value and purpose quickly when you shove its patterns and practices into application development. For example, facebook would never build an application from a single code base that runs on all platforms/devices. They build platform/device specific applications because that is what is best for the user.
In my experience, picking a process and making sure everyone follows it is more important than the actual type of process one chooses. I’ve tried several software development methodologies. Most have left me feeling like that moment when you recognize the gap between what you are sold and what you actually get.
The more recent agile-minded software development processes feel like the sweet spot for building applications. I’ve tried very strict agile processes and very loose agile processes. The processes I’ve found to be ideal are the custom, loosely enforced, agile-like processes that can be wrapped around the uniqueness of the project and team members. Roughly, the process I’d choose to start with looks something like this:
|development||Node.js running locally|
|staging & production host||Node.JS running on modulus.io|
Managing third party code and their dependencies should not be a manual task performed by a human. Package managers should perform this duty. As of today, I believe it still makes good sense to select a separate package manager for your application code and your code that is parsed by a browser engine. Below are some choices for front-end developers.
|Node.js package manager||NPM|
|browser package manager||bower|
A lot of developers wait until the end of a project to integrate analytics, but one should not wait for development to end to select, plan, and integrate analytic tools. The reason not to wait is that these tools often have tentacles (especially user analytic tools) into the application code and its organization. Select analytic tools up front, plan accordingly, and consider their usage during development. It’s fairly common to have a separate tool for site analytics and one to help facilitate the type of user analytics you require.
When working on a team, the goal should be that each file is written as if it were coded from a single developer’s mind in regards to error prevention, formating, and style. Three main types of tools (i.e. code linters/hinters, code style checker, and a code editor config file) aid this process and should be properly implement and configured before coding begins.
|error, quality, and style enforcement code tools||example|
|linters/hinters||CSSLint, HTMLhint, JShint|
|code editor configuration file||.editorconfig|
It’s fairly common that these tools will run every time a developer saves a file in their code editor and/or commits code to a revision system like Git. I’ve even implemented a Git hook that would double check the enforcements and reject a code push if any of the code failed to pass. However, the most common implementation of these tools is found in a the application building process.
Whatever you do, just don’t assume humans will manually perform tasks or that you can afford the expense of human-driven processes.
This step is where the majority of those doing front-end application development give their time and attention. I believe this is a mistake. If you are still with me by this point, you see that I believe that this is only one step of many in planning a front-end application.
In this step, you have to pick a set of tools that will fit your team and the organization when architecting and structuring application code. The solutions might not always be what you personally think is best, but instead what is pragmatically best for the problem you are trying to solve and the types of developers who are solving it.
A possible stack of solutions you might consider which is rather popular today could be:
|templates||MVVM from AngularJS|
|module communication||AngularJS $rootScope.$broadcast and $scope.$on for a PubSub communication.|
|data abstraction||Kendo UI dataSource|
|app structure||NG seed|
|dependency management||AngularJS Dependency Injection|
|widgets/components||Kendo UI (using built-in directives)|
|css UI frameworks||Material Design for Angular|
I hope after you examine the stack above you will concern yourself less with the actual examples given, and more with the how I labeled the parts. What I want you to realize is that your application needs:
The specific solutions chosen to architect and structure an application is less important than making sure you understand the role and purpose of each part, and that you make the proper use of each when your application requires it. If what am saying is cryptic, simply take the bulleted list above and make sure you completely grok each list item and its role in application development.
The last thing I want to say about this step is that while most solutions will get the job done, ideally you want to use the simplest solution available given the context of the problem you are solving. Don’t use a sledgehammer (e.g. AngularJS) when a regular hammer (e.g. vue.js) will do.
How you test and what you test is less important than the fact that you test something. It’s likely the case that you’ll want to test each module or unit of code by writing unit tests. When all of the units of code unite to form a running application, you’ll want to do functional testing. Below I detail the tools required (tasking tool facilitate all this) to do cross-browser unit and functional testing.
|test runner (for unit testing)||karma|
|unit testing framework||mocha|
|unit testing assertions||chai|
|unit testing mocking||sinon.js|
|unit testing coverage||blanketjs|
|browser testing platform (for unit & functional testing)||browserstack|
|browser automation framework (for functional testing)||nightwatch.js|
If code analysis tools are a new concept for you, make sure you check out the analysis of the jQuery library. Plato’s visual analysis makes it fairly obvious as to the value of analyzing code and how you might work it into an application life cycle.
You need a plan to get your local code to staging and production (i.e. deploy local code to public servers). After all, not everyone can always see your locally running application, even if you use some magic to make it happen. A continuous integration server is an ideal solution for crafting deployments regardless of whether you intend to deploy to production on every code push.
Let me step back for a moment from CI concepts and talk about local development. Ideally, anything you do during CI, you should be able to do locally. That means, building and testing your application should be crafted first to run locally. In fact, I will often run a second server locally that serves staging code on my local machine (i.e. what gets outputted during CI process). It’s this local testing and build process that becomes automated once you set up your CI integration. I’ve loosely mapped out below what this might look like.
|continuous integration||use codeship to deploy to modulus hosted staging and production|
Package managers alleviate manually managing dependencies but don’t offer automated insight into upgrade paths for each package. Package monitoring tools can alleviate manually having to monitor packages for updates by notifying you about available updates or a potential security vulnerability. It can even auto-magically update packages for you based on semver configurations. At the very least, a package monitoring solution can help you speed up the process of updating dependencies by simply keeping you informed.
A tool like gemnasium can monitor both your npm package.json file as well as your bower.json file. Below is an example gemnasium dashboard for the package.json file used on the kendo-ui-core GitHub project.
Lastly, the monitoring and measurement of the uptime and performance of your application should consistently be on your mind. Use something like Pingdom to capture uptime and performance stats. I particularly like the alerting and reporting capabilities of these types of tools. It’s like having a team of robots monitoring your uptime and performance every second of the day, then providing detailed reports as often as you’d like.
In conclusion, I want to ask and answer the question, “Why follow any of these steps when planning a front-end application?”.
The entire goal of writing software should be to create something that can last. We plan out applications so that they are properly documented, tested, scalable, and monitored. This leads to software systems that are resistant to the effects of overwhelming code debt, spaghetti code, and consistently having to be burned down and built back up.
By providing these steps I am not suggesting that you should dogmatically follow each step or use each tool/solution/example I showcased in the step. The tools/solutions/examples (e.g. AngularJS) found in each step are given so that you can get the general context of the decision made in the step. If you take away anything from this article, it should be the category of decisions made in the step, not a specific tool/solution/example present in the step.
If you think I’ve missed anything major (like maybe code reviews), let me know in the comments.
Building JS Apps: