Javascript is an awesome programming language, however, writing clean javascript code can be a challenge, even for seasoned programmers.
What does clean javascript code look like? It should be:
- Easy to read
- Easy to debug
- Efficient and high performing
Here are the top tools and tricks you can use take your Javascript code quality to the next level:
1. Use a try catch on all api requests & JSON methods
Numerous things can go wrong when making api requests to fetch data, so taking care of these scenarios are a must. When handling JSON don’t automatically trust what is being given, try to make your code more robust by handling possible inconsistencies.
2. Use a linter (ESLint)
A linter is a static code analysis tool that will check for programmatic and stylistic errors based on a predefined set of rules and configuration. In short it will improve your Javascript/Typescript and help keep it more consistent.
3. Track Javascript issues in your editor
A major component of keeping your Javascript codebase clean is making it easy to track and see issues in the code itself. Tracking codebase issues in the editor allows engineers to:
- Get full visibility on larger issues like tech debt
- See context for each codebase issue
- Reduce context switching
- Solve tech debt continuously
You can use various tools to track your technical debt but the quickest and easiest way to get started is to use the free Stepsize extensions for VSCode and JetBrains that integrate with Jira, Linear, Asana and other project management tools.
4. Utilise template strings
Template strings will allow you to inject values into the string while preserving the format and the code is much more reader friendly than doing string arithmetic.
5. Utilise regex when needing to search strings
Although regex can seem esoteric from the outside, it is such a powerful string parsing tool and allows you to construct complex patterns to account for a variety of difficult string matching scenarios.
6. Utilise optional chainings
Stop having long logical conjunctions and simplify your code with optional chaining.
7. Avoid nesting
Nesting is a sure fire way to increase the complexity of your code and make it much harder to read and comprehend. Consider refactoring if it’s more than two levels deep, by having root level return conditions, shorter blocks and abstracting nested logic to its own functions.
8. Comment all atypical code, but don’t let it replace code readability
There will be times when you have to handle uncommon scenarios where there aren’t established conventions. Commenting this code to help explain what it does and the context that is being considered will greatly help other programmers as well as be a reminder to yourself when you return to the code in the future. But this should not be used as a crutch for not being thoughtful around writing readable code in the first place!
Oldest comments (35)
Useful!! Thanks.
Thanks for the great article. :)
These are some awesome tips, thanks for sharing 👍✨💯
Anywhere between 4 to 5 levels of nesting is okay; and forcibly getting rid of it often risks turning the code into spaghetti where a single unit of business logic gets spread out over multiple co-dependent functions.
A better approach, imo, is to treat each level of nesting as a point where you should ask "Is this inner block its own unit of logic?" if yes, extract it, if not, leave it.
Projects I've worked on had Sonar Quality Gates configured. It's a great way to keep high quality code and teach developers clean code practices at the same time.
I remembered because there were a lot of issues concerning deep nesting of if-else statements 😂
Sonar Quality Gates, Is it extension to be installed to VS Code or any other editor?
SonarQube is an application that you can either run locally or on a remote server and integrate to your CI/CD pipeline. It's connected to your git repository and every time a commit is pushed to a branch, SonarQube runs the code analysis and provides reports on the code quality.
Quality Gate is just a name of the part of the pipeline which checks if the code quality check passed in order for the pipeline to continue the deployment.
You can read more in the docs on the official website of SonarQube! :)
You should try:
github.com/SonarSource/eslint-plug...
I think about how I will/would test each portion of my code which drives out the levels naturally. This usually means more and smaller testable well named functions and then a larger testable function that consolidates them and reads cleanly when I return to it in the future.
As I said, about 4 to 5 levels of indentation is usually the limit; beyond that, you're almost always doing something unreasonable.
But medium sized functions can be tested just as easily as smaller functions. In fact, you should do this anyway so you're not really saving any work by splitting them into smaller subdivisions and testing those individually.
And there just comes a point where you spend more time writing additional tests than you would just looking at a bigger function and figuring out why it fails the way it does. Tests should not replace debugging tools.
On average/in general: Medium sized funtions have much more cognitive complexity and paths then smaller functions. The smaller the function, the easier it is to test. I recommend 10 lines or less per function as a rule of thumb.
Note that there are RgeEx that can open your server to DoS if user input is involved. Check your regex accordingly.
"Use a try catch on all api requests & JSON methods" I'de argue you should have abstract methods which deal with this sort of thing as middleware. I don't like seeing try catches in all the controller's, rather abstract that away so developers writing controllers it's all been accounted for them already. I consider these sort of this strategic code of your own framework and should be done uniformly and abstractly.
youtu.be/ITogH7lJTyE
Absolutely, errors should not be used for control flow which is promoted a lot in JS. Anything unexpected should bubble unless you can deal with it at the call site. A Data Adapter pattern is a much better choice for remote data validation/parsing - which can also remove the need for optional chaining which spreads like a virus and shouldn't be considered a good default.
If this is code that you are maintaining, you should catch and log errors where they happen for good telemetry. On client side, there should be a service for logging back to the server to capture as many of those as possible. Even if it is flaky as the service could be down, that could be mitigated a bit with a logging cache on the client side.
Waiting until you are outside of the controller could lead to not having the internal variables to log for debugging. Yes, this might not be the cleanest code, but I would prefer to know the exact cause instead of a vague idea of what is failing.
Don't Error objects bundle up their stack traces from the throw's point of origin anyways?
TSLint is depricated. Use ESLint for botth Javascript and Typescript. palantir.github.io/tslint/
Thanks for sharing these tips in detailed.
Tslint has been deprecated..
My 2¢ - Code should be readable, regex isn't (at least by a lot of developers who will read the code someday).
how would you validate email and phone numbers WITHOUT regex?
You don't validate email addresses with regular expressions. If you try, there's a 99.9% chance you will get it wrong.
Developers should be able to read regex (at least to a certain degree) and they should be aware of ReDoS. But I agree that there is a point where regex are becoming too complex and unreadable and reduce maintainabililty.
Thanks for sharing :)
That's awesome.
I always forget about optional chaining! Thanks for the reminder and the great article.
Сongratulations 🥳! Your article hit the top posts for the week - dev.to/fruntend/top-10-posts-for-f...
Keep it up 👍
I use 7 out of 8 items. The only one I don't use is eslint. It is not used in the company I work for. I could not convince the people working in the company to use eslint, but I use eslint in my personal projects.