Day 0 - Goals and technology
Day 0 - Goals and technology
Goals
There is a lot of stuff to learn when it comes to modern JavaScript stacks. Here I am going to document my experiences in pulling together a NodeJS-based stack for serving a small single page app, integrating it with a BDD-based setup, writing an API to serve JSON data, writing the UI in possibly Backbone or React and having it all interface together. When done it should also leverage newer JS constructs such as those from ES2015. To top it off, I want to also consider dependency graph management, possibly using WebPack, if that’s justified… we’ll see.
The app itself will be a favourites list. A series of card items will be presented to the user, they can favourite an item to add it to a separate favourites list, and they can remove any favourited items. This project started life as a simpler project, written in Backbone. However but I wanted to break it down, start over, and work back up with a more full-featured technology stack.
So I’m going to make mistakes. I’m going to break things. I’m going to write about it as I go along. I’m going to misunderstand / misuse things. But hopefully, at the end, I’ll have something that’s helped teach me (and maybe you?) a lot.
Technology
So much is changing in the JS world, it can be hard to keep up. Let’s break down the technology into what’s being considered, at this initial stage.
Let’s also be cognisant of being too much a magpie developer, because whilst new things are great and shiny, at some point you have to release. Real artists ship.
API
To keep things manageable, the API is not going to be backed by a database, instead relying on JSON data kept only in temporary memory. Each time the server restarts, it will reset and changes will be lost.
My expectation is to use ExpressJS. I’m going to pass on its spiritual sibling Koa because Express is what gets talked about more for now.
Behaviour Driven Testing
Test / behaviour driven development will encompass both unit tests and feature tests. This is probably where I’ll make the most mistakes as it’s something that I know about but haven’t much used beyond simple unit testing. I want to test code. I want to make sure things work well end-to-end. Let’s keep in mind that humans should still be involved in testing and that you won’t necessarily cover every single use case.
By describing things from a user’s perspective, this hopefully will give us a clear goal of what to do, and then we can worry about the implementation details.
This is such a confusing as heck place to start though. Let’s see what we have, and by no means an exhaustive list:
- Jasmine does unit tests, and is fairly “self contained”.
- Mocha is popular, but only does a little. It’s usually paired with Chai, maybe Chai-as-Promised, and SinonJS. But not necessarily! It’s so extensible you can plug other things in if you want! Do we want to? I don’t know. I haven’t seen people often stray from the “standard combo”.
- If you pick Mocha/Chai, which one of the three test writing styles would you like to use? Assert (TDD), expect (BDD), should (BDD)?
- Istanbul reports on how much of your code is covered by units tests. Definitely useful, but not the be all and end all.
- Cucumber lets you describe feature tests.
- What about Karma? It’s often paired with Angular, and it includes its own webserver to run tests in too (from what I can tell).
- There’s Jest, which seems to be React’s preferred way of testing things. But then you can probably also plug Mocha in to React with a bit of package glue as well.
- And then we have supporting things like Selenium, also used in such projects as WebdriverIO, NightwatchJS etc. etc.
- Online continuous integration services such as TravisCI also exist, but I’m going to pass them by for now.
Selenium, used to control a “live” browser (such as Chrome or Firefox, or a headless one like PhantomJS) is a bit of a pain as it runs using Java. I’ve found in my research it can be quite flaky, but let’s hope we can step past it. WebdriverIO seems like a nicer wrapper around Selenium that makes it a bit friendlier to use.
For unit tests, I’m going to lean towards Mocha/Chai.
For feature tests, I did find one setup which looks really promising: https://github.com/xolvio/chimp. It combines Mocha/Chai and Cucumber together, giving you the option of either (Mocha can be used to run feature tests? That’s news to me), and serves using WebdriverIO.
…I might also just mention Supertest here as well, which seems to be good for testing API calls. Do we need to use it?
Framework
I have the most familiarity with Backbone/Marionette which are (at least in the former case) pretty “hands off” from telling you exactly how to structure. Marionette adds a bit more opinionated design to its systems, and adds some useful helpers. Plus Backbone Radio is kinda nice for talking between things.
I am tempted to look at using React though. I’ve been starting out in a separate project with it, and whilst it does things quite differently in places (JSX takes some getting used to!), it seems quite useful for what we’re going to build.
This can be decided later for now.
Build system
For a long time I used Grunt, but its development seems stalled, and it’s relatively slow (but at the time, amazingly useful). Thus I’m tossing up between Gulp and Webpack. In typical “plug everything into everything!” fashion, you can also use Webpack with Gulp. And Webpack can run its own server too, instead of Express?
I could just keep things simple and rely on ES2015’s structure but reading about it, seems like it has some shortcomings. I’m not sure about going down an AMD/UMD route, probably instead going with CommonJS. It’s synchronous, but I don’t feel that’s a big concern here. When HTTP/2 becomes commonplace, that might change best practice for packaging things.
UI
This is easy. Sass (using libsass for speed), and all my standard front end stuff. Autoprefixer, CSSnano, etc., I’m not really worried about this part of the setup. It’s been pretty stable for a while now.
First steps
Given I’m most settled on ExpressJS, it probably makes sense to tackle the API first. I’d like to be able to get something done without being concerned with the other technology choices. The API can be its own thing. But let’s keep them in the back of the mind whilst tackling it.