Shit Javascript Coders Say

Dave Sag
Dave Sag
Mar 9, 2018 · 6 min read

I’ve been coding in Javascript for over 20 years and I’ve got a lot of strongly held opinions based on those years of experience. I’m going to have a small rant now about stuff I see in the wild that real Javascript developers say to me, that I completely disagree with.

Maybe back in the day before ES6 syntax and modern versions of Node some of these things made sense, but now there is just no excuse.

1. Let’s use Typescript.

Seriously why the hell would you use Typescript? Oh, right, you like Angular. Nuff said.

But my IDE likes Typescript and helps me write nice clean code.

No, it doesn’t. It transpiles your code into bloated, insufferable, hard-to-debug shit. Your IDE is a crutch. Don’t treat Javascript like it’s the enemy. Stop trying to force your old Java and C# patterns onto it.

See also 2, 3, 4, and 7 below.

2. Let’s use the Flow extensions for Javascript

What part of Javascript is a weakly typed language do you not get?

Following on from the points I made in 1 above, stop being afraid of Javascript. Weak typing is a strength, not a weakness. It gives you flexibility. If you want strong typing use Go, or Java, or, hell, I dunno, Ada.

Don’t encumber your Javascript just because you are afraid of the language. Harden the fuck up and write better tests.

3. Let’s make everything a Class

Just no. If you are writing Javascript like it’s traditional OO you are doing it wrong. Compose and curry all the things.

There are very few cases where using Classes in Javascript makes sense and they all involve mocking other libraries’ constructors.

Here’s something, the likes of which I see all the time

class Utilities {  static doSomeThing(data) {
return data.whatever()
}
static someOtherThing() {
return 'yay, a thing'
}
}
module.exports = Utilities

Why would you do that when you could just do

const doSomething = (data) => data.whatever()const someOtherThing = () => 'yay, a thing'module.exports = {
doSomething,
someOtherThing
}

4. Let’s build the front-end in Angular [1|2|4|whatever]

Angular is for people who are afraid of code. Use React. Be a grown-up.

I’ve never seen a well structured, elegant, well tested Angular project. Angular is the PHP of the Javscript world. Amazingly I’ve seen a lot of projects that use both Angular and jQuery. You’ll notice I don’t even mention jQuery in this list because no-one uses jQuery any more.

As Bono might have said:

Let’s make Angular History

5. Let’s use immutable.js

No. Don’t use additional libraries that force you to code around their inadequacies just because you are afraid of accidentally mutating something. Just use object spread notation, now a standard feature in Node 9+, and write proper tests of your reducers.

In what way is

return immutable(state, { goodTimes: { $set: myAmazingData })

better than

return { ...state, goodTimes: myAmazingData }

Neither mutate the state, but the latter is much easier to read.

6. Let’s use [lodash|underscore|whatever]

No. Let’s not use lodash. There is almost nothing in lodash you can’t do better with modern vanilla Javascript. Javascript has had map and reduce for years now.

Remember folks, the fewer dependencies you have, the more maintainable your project is.

7. Let’s write this in Coffeescript

The Naughties called and they want their hard-to-debug bloatware back.

I used to love Coffeescript, but then Javascript evolved, and suddenly there was just no need for Coffeescript any more. Sure it’s nice and terse, and you don’t need commas in lists, but other than that it adds nothing and it forces you to add a lot of return nil at the end of functions because of its annoying ‘let’s be like Ruby’ habit of returning the last thing it saw from any function. Throw in a console.log ‘is thing thing on’ at the end of a function and break random stuff. No thanks.

See also 1 above.

8. Let’s build our project with [Gulp|Grunt|whatever]

No. Use Webpack and simple npm scripts. Avoid ancient build systems that force you to manufacture and maintain your own asset pipelines.

9. Let’s use Generators

Seriously no. Generators are write only code! It’s close to impossible to work out what a morass of generator code is doing. Use async and await instead. Much nicer.

These two things have the same basic effect

function* doTheThing() {
const x = yield somethingReturnsPromise()
// do something with x
return x
}

and

const doTheThing = async () => {
const x = await somethingReturnsPromise()
// do something with x
return x
}

The latter is code people can reason about.

Sure there are some reasons to use Generators, but those use-cases are actually very rare. Most of the time you can just use async / await and keep your code comprehensible.

If you need to inject context into a function, or series of functions (which is essentially what having multiple yield statements achieves) then use currying.

Also async / await code is faster, almost twice as fast in modern versions of Node.

10. Let’s use Sagas in Redux/React

Sagas rely on Generators and, as outlined in 9 above, Generators are slow and ugly.

Use promises, async / await, and Thunks and keep your actions comprehensible.

Compare this trivial Saga code

function* fetchThing(id) {
try {
const thing = yield fetch(`${BASE}/things/${id}`)
yield put(Actions.fetchThingSuccess({ thing }))
} catch (err) {
console.error('Caught', err)
yield put(Actions.fetchThingFail({ err }))
}
}

with the same function done as a Thunk

const fetchThing = id => async (dispatch) => {
try {
const thing = await fetch(`${BASE}/things/${id}`)
dispatch(Actions.fetchThingSuccess({ thing }))
} catch {
console.error('Caught', err)
dispatch(Actions.fetchThingFail({ err }))
}
}

They look the same right? But even in this trivial example the Thunk is much easier to reason about.

Every Redux aware developer knows what the dispatch function is, but reasoning about yield gets really difficult really fast, especially when the code becomes non-trivial.

By contrast reasoning about the flow of async and await code could not be simpler.

Sure people will go on about how sagas are all pull vs traditional actions being push, and how that somehow makes them great, but 99% of actions simply don’t need to be that complicated, and if they do you are probably doing it wrong.

See 9 above.

11. Let’s use Yarn

Why? What does Yarn give you over modern versions on NPM?

Okay sure, NPM version 5.0.0 through to NPM 5.3.x were dogs. The introduction of the package-lock.json file, in direct response to Yarn’s yarn.lock file was handled particularly horribly and caused a lot of needless developer pain. But that was almost a year go and, occasional incidents of stupidity aside, NPM versions 5.6.0 and beyond are excellent, and npm 5.7.1 is really super fast.

Just use NPM and skip a global dependency.

Conclusion

Like I said up top, this is all my opinion, but it’s opinion based on two decades of Javascript development. Overall follow these rules:

  1. Don’t use external packages that do what the language itself does very well.
  2. For server-side projects, don’t use higher-level languages that compile down to Javascript. For client side projects, keep the amount of pre-processing to the minimum possible.
  3. Favour simplicity and readability over being clever.

Thanks.

Dave Sag

Written by

Dave Sag

Blockchain Tsar & Senior Javascript Practitioner at Industrie&Co. (https://industrie.co)

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade