Web builder & frontend developer

Building a project - workflow, development stack.

30 December 2016

Sometimes, I need to calculate the aspect ratio of an image to make sure I resizes it correctly and because I'm to lazy to actually do the math (but I ended up doing it anyway!) or use something found on the web, I decided to build an aspect ratio calculator, because why not.

I built this project in the course of a few weekend hours, and during this time I've cemented my own basic workflow and deploy process.

For the rest of this article I'm going to talk more about the stack and the deploy process I've used rather then the actual project, since, well it's an aspect ratio calculator, there's not much to talk about it anyway.

Build stack

For the actual build process I'm using and will continue using GruntJS. Now, I know there are a lot of debates at the moment on what one should use when building an app. Whether it's Grunt, Gulp or npm scripts, people seem to forget the most important thing, it doesn't matter what you use as long as it gets the job done.

I prefer Grunt because it's much more easy to set up and to understand, when for example, someone else comes along and tries to understand the logic behind your project.

By passing a .json file into the data parameter, I can easily configure anything I want.

Another thing that I found useful was to add the option to build the project while I issue a grunt watch command. I did this like so:

watch: {
options: {
atBegin: true
},
...
[rest of the config]
...
}

I'm not going to go through the whole Grunt configuration file, that's another article for some other time.

Now on to the language part of things.

Language stack

I try to keep the language stack as small as possible. I don't like to mix and match too many languages when working on a project. Bellow are the languages I use on a general basis when starting a new project. In the future I may introduce new ones but for now I'm sticking to these ones.

CoffeScript

As you're already aware, from what I've written above, I'm using CoffeScript instead of regular, good old vanilla JS. The main reason behind this approach is that the code is much more readable than regular JS. At least that's how I perceive it. And using GruntJS allows me to easily compile that CoffeScript into regular JS.

Sass

I won't start a debate why Sass is better than LESS. I use Sass because it's easier to handle, there are a lot of mixins out there or frameworks that already have support for Sass and the community behind it is amazing. Probably in the near future when the support for CSS variables will be improved I'll switch, but until then I like my nesting, variables and mixins.

Jade

Or Pug, as it's now called. I prefer using a templating system because it offers me the ability to modularise each section of the application into more manageable pieces. For example I want to have a mixin for a certain component.

Pug allows me to use logic inside HTML and thus minimizing the JS code that I write. It also gives me the ability to pass certain constant values to the actual code. I usually generate a settings.json file that will help me use a name, a description, a color in multiple places without having to copy/paste that value everywhere.

PHP

When I started working on uptimey I was still developing a lot of WordPress websites and eCommerce platforms so naturally I went with something I already knew and could easily handle and maintain. So for server side scripting I generally used PHP to handle anything that I might need.

PHP is a vary versatile language and I enjoy writing code in it, but if I were to start a new project now, I would probably use something else.

Dependencies

The dependency list isn't that long either. A must have for me is require.js, so bellow I'll explain how I normally use it.

require.js

Because require.js gives the ability to load scripts based on their dependencies, it's a real life saver when it comes to speed and loading times. Bellow you'll notice the actual configuration file that I normally use when starting a blank project. The main script file will, usually, require jQuery and because of that, jQuery is the first thing loaded before the actual app.

moment.js

Another example from the uptimey project is moment.js. Moment allows anyone to easily work with dates. We all know dates and formatting them can be a hassle, that's why moment.js is a must have if you're planning on working with dates.

Segment.com analytics

Instead of using good old fashion Google Analytics or GoSquared, I'm using the services provided by segment.com because they allow me to integrate almost any tracking service by adding just a single script. Using only a single script and sending all the params through that, I can hook up things like Pingdom and Mixpanel, that allow me to visualise how things are going.

Structuring

I spent a lot of time thinking about a projects structure and how to best implement it. I finally came to the bellow formula after many hours of trail and error.

Jade (Pug) structuring

In terms of structuring the templates, I usually use this type of structure:

footer.pug
head.pug
index.pug
layout.pug
meta.pug

The footer file contains the analytics, require.js scripts and sometimes the copyright info. The head file has all the CSS references. The index files ties everything together. The layout file is the most important one, because it's the actual structure of the whole project. Sometimes the layout file might be the basis for other pages, if the project requires it. And last but not least the meta file has all the meta tags that the project I'm working on needs.

All these files receive constant values from the settings.json file while they're compiled via Grunt.

Folder structuring

The basic folder structure that I use, is as follows:

- bin # the destination folder when things are compiled
-- css
-- img
-- js
index.html
- lib # the source folder contains all the files that will be compiled
-- controllers # files that define what the app can do
-- helpers # files that contain functions that I use in multiple places
-- models # all the files for server side scripting
-- style # all the Sass files
-- views # all the Pug files
settings.json

Deploy

The deploy part of this workflow I've only just finished perfecting. When I discovered how useful Travis CI can be, I stopped searching for an alternative. I was able, using a single configuration file, like the example bellow, to test and deploy in a matter of minutes.

The above configuration is just an example that I've used on multiple occasions. You should try modifying the above params and see how they best work for you.

You'll notice that after the build is finished I run a script for deploy. That script will deploy the project, in this case to Github pages, if all tests have passed successfully. You can find an example of a deploy.shhere. Basically what it does is, it will clone the repo into the Travis CI VM and then replace the files in the gh-pages branch with the ones from the bin folder and then push the updated files to Github without me having to intervene. You can add anything you want to the deploy.sh file so you can deploy to your choice of environment.

If you want a more in-depth look on how that script works, have a look here, at this brilliant tutorial, where the whole process is explained.

Conclusion

I hope this article will be the basis for a discussion that we can all contribute to. I'm saying this because, many beginners, when starting in our field don't have the slightest idea where to start. So with this article I'm hoping to get people to share there own workflows and development stacks so that we can all benefit and improve. If you've written an article that describes your flow, hit me up @stefanbc, I would love to read it.

In a future article I'll describe my hardware stack and the way I set up my code editor. but until then code long and prosper!