Improving your (Web) Dev Foo

Darkø Tasevski - Feb 1 '20 - - Dev Community

I've been writing this since the last year, and in the end, I wasn't sure if I should publish it as this is mostly just a rant. Hopefully, some of you might find something interesting here as I wrote up some of the stuff I've learned and I'm doing in practice to keep writing effective and clean code.

Editor/IDE

If you are starting learning about web development, you can't go wrong, pick any code editor and code on.

Currently, for web development, there are many choices when you come to choosing the editor for your work. I use Webstorm/Xcode combo for work and VS Code/Vim for my stuff. From my experience, my suggestion would be that beginner devs start learning with a simple editor without many plugins, such as VS Code, Notepad ++ or Sublime Text, typing out all those keywords and language methods by hand helps a lot with memorizing/learning all that stuff. Once you feel comfortable with a language you're writing your code with, you can switch to full-blown IDE like Webstorm or plugins enhanced VS Code.

Linters & Formatters

TLDR: Use Eslint and Prettier

When your code base gets bigger, it's also more challenging to keep an eye on all those lines, and syntax errors problems creep in. By highlighting problematic code, undeclared variables, or missing imports, your productivity can be increased a lot and is going to save a lot of time and many nerves as well.

Using Eslint from a very start would also help a lot with learning Js, as it will force you to build healthy habits and write clean code. Over the years, I've tailored my version of the eslint rules based on eslint-config-airbnb, but lately, I've been looking into Wes Bos's eslint config and would probably give it a go in a some of my future projects.

Beside Eslint I'm using Prettier for code formatting, combined with husky and lint-staged for automating linting/formatting as precommit hooks.

The optimal directory structure

Dan Abramov's solution

I have mixed feelings about this topic. The only thing that I'm sure of is that there is no right solution.
Every application is different in some way or another, and each project has its own distinct needs. How we structure our applications should change based on the needs of the project, just like the technologies we choose.

Do not try to optimize the project structure from the beginning of the project, but keep in mind that changing the project structure later in the project can be a problem in VCS because of history rewriting.

That being said, don't overthink it. Pick a folder structure that works for your application. If you’re spending a massive amount of time organizing and reorganizing components, containers, styles, reducers, sagas, you’re doing it wrong.


File naming

Rant incoming

Regarding file naming, one rule that I find immensely useful is this: name your file the same as the thing you’re exporting from that file. I can't stress enough how angry I feel when I have hundreds on index.js files in a poorly structured project, and finding some chunk of logic takes so much time, which feels wasted...

It staggers me that some people are happy to work like this.

indexes everywhere

Even if your IDE is clever and puts the directory in the tab name for non-unique filenames, you still have a bunch of redundancy there, and will run out of tab room sooner, and you still can’t type the filename to open it. Having said that, I understand that there is the reasoning behind this — It’s a definite trade-off. Shorter import statements vs. file names that match exports.

Not a worthy trade-off, in my opinion.

In my case, for the last two or three years, I'm mostly using CRA's project structure, with a few modifications, like adding a redux/ or sagas/ dir for state management logic and moving all jsx/tsx files to components/.

Debugging

Just console.log anywhere where you think there is a code "smell."

Writing about debugging can be a post on its own, yet there is a lot of already excellent posts and courses on Js debugging so I'll keep it short.

Many devs would say that using debugger looks more professional, but the console.log is something I'm using the most for a quick debugging. I'm lately working on the apps for Smart TVs and streaming devices, and those are not really debugger friendly, so logging data in console or going through device logs in telnet is sometimes the only way to debug. That aside, you should learn how to use the debugger, as it can save you with more complex bugs.

The simplest way to debug, at least in terms of tooling, is by reading the code you wrote. After that, use the console.logs, and if even that doesn't pinpoint the problem, switch to the debugger and good luck.

Documentation

Don't write a comment just for the sake of it. Write comments only for stuff that needs explanation.

We all (hopefully) know how important proper documentation and reference material is to a successful software project. Without good docs, a particular library may be next to impossible to use. Without a reference to how different components and methods work in isolation, let alone examples of how all the different pieces of a project fit together with each other, we are left to interpret the original intention of the author merely by reading the source code, or if we are lucky, reaching for StackOverflow and googling random error messages. If this is an in-house or small project, you are probably entirely screwed (been there).

This is especially important if you are working with several other fellow devs on the project; think about what the other member of the team is going to think about that hack you wrote when he doesn't know why is that needed. By keeping knowledge of how the code works and why is there many hacks in it or intentionally making code more complicated than it needs to be, you are just making lives of the everyone working on the same project more harder. And if you are doing this for the sole purpose of assuring your job security, you are just a censored.

For documenting my projects, I've been using JSDoc syntax. JSDoc is a standardized way of writing comments in your code to describe functions, classes, methods, and variables in your codebase. The idea is that we describe how our code works with a few special keywords and formatting conventions, and later we can use a parser to run through all of our commented code and generate beautiful, readable documentation based on the comments we write.

Here’s a short example of how's it looking like in practice:

/**
 * @desc Represents a book.
 * @param {string} title - The title of the book.
 * @param {string} author - The author of the book.
 */
function Book(title, author) {
}
Enter fullscreen mode Exit fullscreen mode

Some of this stuff can be replaced with Typescript types, but even with that, for more complex functions, it's helpful if we have a good explanation of what it is doing and why do we need it to do that.

Also, every and one hack in your code should be documented, believe me, future you are going to be thankful for that.

And for the end, if you already haven't, please read Clean-Code by Robert C. Martin. Writing clean and readable code is a skill on its own.

Learn Javascript

But seriously

Jumping on a Js framework or using a library to solve problems you have because you're not familiar with the core language is going to bite you soon enough. But do not despair, most of us have been there on some level, Js documentation is enormous and, unless you have an excellent memory, there is no way to memorize even a quarter of this stuff. But leveraging Pareto principle (also known as the 80/20 rule) would be in many cases just enough. Learn how is this working, all possible operations you can do with objects and arrays, that in Js everything is an object, scope rules, async ops, prototypes (you'll rarely use these, but it's essential to understand how inheritance in Js works) and coercion scenarios (so you can laugh at people making stupid mistakes by adding numbers to strings or arrays to arrays and then creating posts on Reddit flaming Js).

There is truth in saying that if you know Javascript good, then all frameworks and tools based on it are going to be much easier to learn. In the end, those are all just Js under the hood.

I can also recommend reading You Don't Know JS book series if you want to dive deep into Js core mechanisms. (I'm rereading it for the 2nd time).

Use the latest standards

Keep up with times

It can be challenging to keep up with all the things going on in the web development world, especially since the JavaScript language itself has been changing a lot over the last several years. In 2015, TC39, the committee responsible for drafting the ECMAScript specifications decided to move to a yearly model for defining new standards, where new features would be added as they were approved, rather than drafting complete planned out specs that would only be finalized when all features were ready. As a result, we have ES6 - ES10 specifications which have changed the language a lot, and in a better way. Each of these specifications includes a set of new features/improvements integrated into Javascript, nullifying the need for cumbersome libraries or tools so that you can work with Js and not pull your hair out.

If you want to get a quick overview of the features being considered for future releases, the best place to look is the TC39 proposals repo on Github. Proposals go through a 4 stage process, where stage 1 can best be understood as a cool “idea,” and stage 4 is “confirmed for the next ECMAScript release.” There is a lot of cool stuff coming with ES10 :)

If you’re interested in keeping up with new proposals but want somebody to walk you through them, I recommend subscribing to Axel Rauschmayer’s 2ality blog. But if you are more of a social interaction person, probably the easiest way to keep up with language evolution is to follow the people who are shaping and teaching the new language features: @TC39, Sebastian Markbåge, Mathias Bynens, Daniel Ehrenberg, Tierney Cyren, Axel Rauschmayer and probably a lot of other people I forgot.

Babel has implemented almost all of the higher stage proposals on the TC39 list, and you can try them out in the Babel REPL or by setting up a small project that loads in Babel with the appropriate plugins installed. Also, ff you aren’t familiar with ES6 yet, Babel has a excellent summary of its most essential features.

Typescript

Types good, boilerplate code bad

JavaScript is a loosely typed language, also known as a dynamically typed language, which means that it is flexible and does type checking on run-time rather than compile time. This means you can create a variable that starts as string type, but then change it to a number type, etc.
For many people that have started programming in C or Java, this is horrifying (ergo coercion memes on Reddit), as those languages are pretty strict with types and require a full definition of data type or interface for a constant. Anyway, there’s a lot to love about static types: static types can be beneficial to help document functions, clarify usage, and reduce cognitive overhead. But, IMO, there’s a lot to love about dynamic types as well.

So, there comes Typescript. Typescript is Javascript, with an extra layer that adds static typing tools and capabilities to your Javascript code. As you’re developing an application, you will be writing Typescript code, which then gets compiled to plain JavaScript for the browser to understand. It can fix some of the issues dynamically typed languages have, a big plus is if you use one of the TS supported editors (VS Code, Atom, Webstorm) which can provide the excellent dev experience and boost your productivity. That aside, I hate a boilerplate code that comes with TS. A few TS projects I've been working with have at least 30-40% more lines of code just because of TS types, interfaces and enums. Errors can be cryptic sometimes, and debugging type issues can get on a nerve real quick. Merged types and some advanced type definitions can be tiring to read and understand sometimes.

There is a excellent article by Eric Elliott about Typescript's bad and good sides if you want to read more. Still, my overall opinion of TS is positive, just because whenever I go back to read the code, I can (almost always!) understand immediately and thoroughly what each type of variable is, what this function returns, whether this array has been changed throughout the program, etc. That's a lot of saved time and minimized the number of redundant operations to check the type and structure of the data.

Code testing, integration, and delivery

Give a developer a tedious task, and they'll find a way to automate it

Probably most of us here are familiar with tools as Webpack, Gulp, Grunt, lint-staged. Even Prettier and Eslint are a kind of automation tool. The less time we spend on menial or repeating tasks, the more time we have to focus on the actual problems.

Few developers get excited over the idea of writing tests for their code. Especially when there is a pressure to finish new features as fast as possible, writing test code that doesn’t directly contribute to the progress of the project can be annoying. When the project is small and you can test a few available features manually this might be fine, but once the project starts to grow manual testing is time-consuming and horribly inefficient.

Investing in testing upfront is one of the best investments you can make on your project. It is what allows you to write a feature, not touch it for weeks, come back, see it is passing all its tests, and have a level of confidence that everything is good in the world.

I've been using mostly Jest for my tests, but I've heard good things about Riteway. Testing React components have gotten more difficult since the introduction of the hooks, Enzyme is having a hard time so I'm not sure if I can recommend it anymore, react-testing-library might be a better choice for now.

Continuous integration is the software development practice of frequently integrating changes to a shared code repository. For every integration, automatic formatting and testing should be done. This gives the developers a quick feedback cycle for determining potential conflicts in commits while also allowing to frequently merge new updates to an application.

Continuous delivery works in conjunction with CI to take the tested and built application that results from the CI process and deploy (or deliver) it to the intended infrastructure. With CD, teams can push new code to production every day or even hourly and get quick feedback on what users care about.

A lot can be told about how to write tests and how to configure CI/CD pipeline but that would be a whole post on its own. There is no golden rule for how to write perfect tests but making sure that you at least write them and are trying to get ~80% coverage with a combination of unit, integration, and e2e tests should lead to clean and confident code.


Summary

I always struggle with summaries (same thing with prefaces). For me, it's usually hard to start writing a post, after that, I can go on and on, same with deciding how to end it 😄 I still feel like I haven't wrote enough about all topics mentioned, so feel free to comment if you have any questions.

Bear in mind that this is a half rant and half commentary to myself, after several years working with Js. There’s a whole class of internet comments that can be summarised as “I disagree, and that makes me ANGRY, here's a downvote”, which is a pity, because when two reasonable people disagree, there’s very often something interesting going on.

Thanks for reading!

Photo by Adi Goldstein on Unsplash

. . . . . . . . . .
Terabox Video Player