Image Image Image Image Image Image Image Image Image Image

Being Brunel |

Scroll to top

Top

2 Comments

Building A Web App Part 3: Tooling Up

Building A Web App Part 3: Tooling Up

So we know what we’re going to write, what it’s going to look like, and what it needs to do before we can throw it to the wolves for comments. This post continues my weekend journey into prototyping a web app that will eventually connect built environment professionals together; if you’re coming to this new then you should probably skip back to the beginning.

Finally, it’s nearly time to write some code. However, one does not simply write code. Before we go anywhere we’re going to have to select and build the stack on top of which we’ll build our web application. Theoretically this step is optional- you could write your own language, compiler; devise your own framework and tools; come up with your own design metaphors and algorithms. Life is short, and we’re supposed to be rapidly prototyping- so instead we’re going to use a stack of languages, tools and frameworks that other people have written to save a lot of boilerplate.

We’re going to be using a react + redux + webpack stack.

This is going to be a long article. Know this- you don’t have to become an expert in every one of the technologies I’m listing out here, but you should invest a little time becoming familiar with them if you plan to do any significant coding of you own.

Node.js

Node began its life as a way of writing web servers in JavaScript. However, when it comes down to it, it’s just a very good way of executing JavaScript outside of a browser. In fact, it’s become a touch ubiquitous (see next), so while we’re not actually going to write any server code for this application, we’re still going to need to go fetch node.

npm

The Node Package Manager (npm) is the real reason why node is at the bottom of this stack. The success of node means that npm offers us access to quarter of a million libraries and frameworks (code written and maintained by someone else). It also provides us with a standardised way of describing, and managing these dependencies in our prototype application. npm comes bundled with node, so there’s no need to download anything else at this point.

Right, so now we’re going to take our first step to actually writing this app. From the terminal, make a new folder for the project and run the command npm init. The gives us a guided way of creating the package.json file that describes the project. After answering some questions we’ve generated our first file, our ./package.json:

Now that we’ve initialised our project (by creating a folder and making a default package.json file), we can start installing packages.

Babel

JavaScript is a funny language. Having nothing to do with Java, it owes much of its success to being in the right place at the right time. And that means that it’s a language with more than its fair share of flaws- typically languages thrive on being good and easy to develop specific solutions to specific problems on; rather than just being what you have to use if you want to write for a browser.

The various committees that control the language, however, are doing their best to improve the situation, leading to a language that is rapidly evolving. Unfortunately it’s evolving a touch too rapidly for your average browser to keep up- let alone your typical user who may not even be able to update Chrome on a daily basis.

Babel solves this problem by letting us write using the latest JavaScript syntax and features and then transpiling (like translating) them back into something older browsers can understand. Out of the box all babel can do is take a JavaScript file, interpret it, and then spit back out exactly the same file. Babel’s strength is in it’s plug-in system, which allows it the parse the file through multiple plugins that transform the output. This makes babel incredibly versatile, but a touch confusing for the uninitiated. So to use babel, we’ll need to install it, and several plug-ins (called presets) using npm:

npm install --save-dev babel-core babel-preset-es2015 babel-preset-stage-2 babel-preset-react

This command installs the core babel functionality, and the presets it needs to transform the latest version of Javascript (called ES2015), the second stage of the proposed future changes for JavaScript (called Stage 2; ‘draft proposals’), and the special language used by React (called JSX, discussed later). The --save-dev means that the packages will be added as development dependencies to the package.json. This is because you only need babel when you’re developing; you don’t need to give all your users the compiler, just the compiled code.

Now we’ve installed babel we need to configure it; it’s not enough just to install the presets, we have to explicitly tell babel we want it to use them. To do that we need to create a .babelrc file in our project directory specifying an array of presets to push and transform our source through (in json format):

Webpack

Using babel compounds a problem that using node modules introduces. Suddenly it’s not enough to just point our browser at a JavaScript file and say ‘run this’. The program needs to be transpiled by babel first, and then all the files it relies on that have been pulled in by npm. And while we could just manually run babel every time we wanted to run/test our app, and keep a diligent list of all the files we needed to copy in and reference- life is too short.

There’s been a whole plethora of tools created to fix this problem; so much so that they actually became a problem of their own. Even tutorials from last year will have you downloading 3 or 4 tools and chaining them together with each other. Thankfully the internet seems to have settled on using npm for module/package management and a tool called webpack for getting your program from well organised source files into a nice minimal package to send to the browser.

Once again webpack is only needed for development; the compiled files it produces are all we actually need to give the client, so we’re going to install and save this as a development dependency:

npm install --save-dev webpack babel-loader html-webpack-plugin webpack-dev-server

As with babel, webpack is extensible; it uses plugins to make its functionality. In the language of webpack we are going to use a babel loader. That just means that when it reads our source code, it’ll load it by putting it through the babel transformation for us. We’re also going to use the html-webpack plugin, which will handle generating and injecting the lines of code that tell the browser to load in our JavaScript into our web page for us. Finally, I’ve included the webpack development server, which provides us with a quick and easy way to continuously compile our code and serve it up to the browser as we’re making changes to it.

And just like babel, webpack won’t do anything unless we’ve put together a configuration file, so in webpack.config.js we need to put the following:

There’s a fair bit to take in here. Working from top to bottom, first we say that the starting point of all of our app will be the ./app/index.js file (when we write it). We then specify that we want webpack to compile everything to a dist folder. Because webpack (and babel) transform files, we then need to specify that we want to generate source-maps that can be use to relate transformed lines of code back to the original for debugging.

The next section configures webpack to only look for .js (JavaScript) files, and to run any that it finds in our source code (which will be in the ./app folder) through the babel loader so that it can be transformed back to something an average browser can understand. We then configure the two plugins/tools- telling the HTML Webpack Plugin to use the ./app/index.html file as a template and the dev server to use port 3000 and automatically update the web page inline when the underlying code changes.

ESLint

Losing the will to live yet? JavaScript is a language of tools and frameworks, and learning to craft your stack is important- so keep at it.

Next on our stack we have eslint. Whilst JavaScript has nothing to do with Java, it is definitely a scripting language. And that means that you only find out whether or not you’ve typed your code correctly when the interpreter gets to that specific line. This is annoying and dangerous, as it’s fairly easy to make a trivial mistake that will run, until suddenly it doesn’t.

To overcome this, JavaScript developers use something called linters. These are automated tools that essentially look over your shoulder constantly and go “oh, you missed a semi-colon there”, or “didn’t we agree that you were going to name all your variables with a lower case letter?”. Linters are opinionated- they all have various configurations and extensions that determine how they think the perfect JavaScript code looks. Personally, I use the following:

npm install --save-dev eslint eslint-plugin-import eslint-plugin-react eslint-plugin-jsx-a11y eslint-config-airbnb babel-eslint

Hopefully you’re beginning to get the gist of reading these. Once again a linter is just something to help the developer. ESLint (the linter I use) needs help to read React language add ons (also called jsx; React is coming later), and to cope with the latest JavaScript features enabled by babel. I’ve also been lazy and imported in the AirBnB configuration- as, by and large, I agree with them about what makes a well written piece of JavaScript.

To configure ESLint we need to do two things, firstly we need to create an .eslintrc file. Normally this would include all the rules you want to follow, and such. But in our case all we need to do is say we’re happy following AirBnB’s rules, that we’re using babel, and that we’ll be using a testing framework called Jasmine (more on that later).

Secondly we need to train our code editor to use ESLint. For Visual Studio Code, which I personally recommend, this just means installing the ESLint plugin.

Jasmine

In the last post, if you can remember that far back, I talked about how we’d be using Behaviour Driven Development. To enable this, we need to add something to our stack that can take our tests and verify that our code fulfils those behaviours we’ve defined. As is the mantra with JavaScript, there’s a dozen ways of doing this. I like Jasmine, which I think has the most beautiful documentation in the world, and is fluently simple to use.

You should know the pattern by now, first step- install:

npm install --save-dev jasmine jasmine-core karma karma-chrome-launcher karma-jasmine karma-mocha-reporter karma-sourcemap-loader karma-webpack

This needs a bit more explanation than the rest. You see, jasmine is simply a language for describing tests, we need to throw in a few more tools to make it useful. We’ll be using karma to actually discover and run our tests (in this case it’ll be using Chrome to run the tests in), Mocha to report the results in a readable way, and integrations for webpack and source code maps.

Step two- configure. Karma will configure everything else in the test stack, so let’s create karma.conf.js:

This configuration outlines what I said, that we’ll be testing using Chrome as our browser, with the jasmine framework and mocha to display the results. We’ll be following a fairly standard convention of naming our tests [test].spec.js (spec, for specification). The configuration then tells Karma that our files need to be compiled through webpack before testing. Finally we’re going to opt to capture console output, which is good practice for debugging our tests as it means we can put console.log() messages in them to work out where things are failing.

npm (again)

It’s OK. This is the only tool we’re going to return to. However, not only does npm make a good way of managing you stack and dependencies; it’s also a pretty solid task runner. Now we’ve established how we serve our application (webpack), and test it (karma), we should update our package.json file to reflect this. So take out the main entry (as we’re not using node to serve), and add/update the test and start commands. Once we’ve done this we can run npm start to start our server, and npm test to test our code (although we don’t have any code yet…):

React

Finally, the promised ‘React’. React is a library for building user interfaces. It was made by Facebook and is one of the fastest growing frameworks out there. As frameworks goes its amazingly light weight, which makes it easy to get your head round fairly quickly. It also lends itself to writing very tight code (code that is small, reusable, and easy to change). It does have an interesting quirk, though, in that it extends the JavaScript language with a syntax for describing HTML called JSX, which is why we’ve had to tell all of our tools about our decision.

Unlike everything before it, React is part of our application and must be given to the end user. It is therefore a straight-up dependency so we only need to use --save. It also doesn’t need a configuration file because it’s a library, not a tool, so all we need do for now is load it in:

npm install --save react react-dom

Enzyme

Because React is a UI library, it can be a bit difficult to test. To make life easier, the people at AirBnB have created Enzyme. It’s a library that allows you to virtually render and manipulate your components and then query them about the condition they’re in. Annoyingly, however, it needs a bit of configuration due to the way it loads in its own dependencies. So first we install:

npm install --save-dev enzyme react-addons-test-utils

And then you need at add the following to your webpack.config.js to enable it to correctly load in the libraries Enzyme depends upon:

Redux

Did you spot that I specifically called React a user interface library? That’s because when Facebook first released React they did so with an outline discussion on how they thought the architecture behind the scenes should work; they called it Flux. The problem was, they didn’t actually provide any code that implemented the Flux pattern, and instead left the community to sort it out themselves.

After a few iterations Redux emerged, which actually develops what Flux started and takes it one step further. Redux is what we’ll be using to wire in our React interface so that when you click on a button, something actually happens!

npm install --save redux react-redux redux-actions

Redux provides the basic functionality for the Redux pattern. React-Redux provides us with a well thought out way of connecting Redux to React, and Redux-Actions is a library for reducing the boilerplate code required to implement interaction in Redux. You’ll see all of these in action in the next article where we finally start writing some code.

Material UI

My last library is simply an aesthetic one. The whole purpose of React is to render an interface. That means that if you want to draw a nice button, or a well designed list, etc. you have to write your own. To save time and ensure we end up with something that looks nice, I’m going to use the Material UI component library. This is a project that provides React versions of most of the Material Design controls specified by Google for use on their Android platform.

npm install --save material-ui react-tap-event-plugin

Note that the react-tap-event-plugin is just a dependency of Material-UI’s; it adds the notion of ‘tapping’ on bits of the interface to allow the library to work with phones just as well as a it works on desktop computers.

Git

Last, but so incredibly not least, is a touch of version control. Sure, you could just sit there and work on files on a directory on your computer. But you’d be missing out on a lot of useful functionality. Initially git gets sold to people on the ‘you can use git so that anyone can collaborate with you on writing code’. And that’s true, if you want to contribute to pretty much any of these tools I’ve built my stack on, you can fork, clone, patch and make a pull request back using git.

What’s often undersold, however, is the usefulness of git’ing on your own. You see, git provides three amazingly helpful tools. The first is that you can ‘commit’ at any time. This can be thought of as saving a snapshot of your code. If you commit often (I normally commit on every unit of functionality- that works out as something like five times an hour), then you have a rich history that you can roll back on (if you make a mistake), or check back to see how you used to do something before you changed your mind.

Critically, for a prototyping scenario, it allows you to branch and merge your code. That means that you can get your code to a working point and then branch off, leaving your working code intact, and try something new. You can have as many branches as you like, so you can be simultaneously giving a few things a go, and then merge in the bits that worked into the main code.


And that’s it. We’ve crafted our stack. I think that one of the hardest things for developers new to writing web applications is understanding that there’s not just one tool that you download, type your code into and then press ‘compile’. A lot of my effort, when I’m developing, goes into following and learning about the developments in JavaScript tooling, libraries and frameworks so that I know what to pick whenever I start a project.

This post is part of a five post mini-series on building a web app: Part 1Part 2Part 3Part 4Part 5.

Submit a Comment

Leave a Reply

Trackbacks

  1. […] June 21, 2016 thomasmichaelwallace Software 0 PreviousNext […]

  2. […] post is part of a five post mini-series on building a web app: Part 1, Part 2, Part 3, Part 4, Part […]