Useful setup that I always use when starting a new project
This post was originally published on https://tomekdev.com/posts/powerful-start. Go there for slightly nicer code snippets. ✌️
I’m not a huge fan of “the art of the start” articles because, after all, starting in a non-optimal way is worth more than not starting at all with a head full of knowledge that wasn’t applied.
With that said, I still have a list of useful stuff that was proven to be working extremely well. The setup is meant to remove some worries from your head and focus on the product/project.
1. Use version control — git
We start with an obvious one. Even if you don’t work on software, use version control, and commit regularly. It will pay off when you make mistakes (everyone does them). When it comes to my projects, I always have to add
.gitignore because I'm using WebStorm 🙄
2. Use .editorconfig
Tabs vs spaces? Inconsistent indent between different files or between team members? There is a well-established solution for that. Even if you are the only person working on the project, do yourself a favor and share
.editorconfig between your projects. Most IDEs will read that file and keep the format of files the way you want.
My personal preference is to apply a consistent style to ALL types of files by setting a small indent, trimming whitespaces, and inserting a new line at the end of the file:
root = true[*]
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
indent_size = 2
3. Add linters
Linters everywhere! Really.
Linter is a tool (script) that checks if you keep a certain “style” in your files. That is enforced by following the rules. Some rules will try to keep you out of trouble, where the community knows that certain construction can harm you. And some others will enforce visual style. That’s good as well because it ends useless discussions about the style of code, removes inconsistency and frustration within the team.
A lot of rules comes with autofixable feature that can modify the code for you. Not only pointing what’s wrong.
Remember to update your linter dependencies regularly and check their release notes for new rules!
Note: TSLint would be something worth mentioning as well (to analyze TypeScript syntax) but it was deprecated in 2019 if someone didn’t notice. The proper way of using it now is typescript-eslint.
4. Add Prettier
Prettier is an opinionated code formatter. Linters do affect the way your code looks but prettier is much more in terms of styling the code. It offers support for multiple languages. The reason to use it is similar to linters — the code should look like written by a single person. Consistency is worth aiming for because it makes it easier to read the files.
Believe or not but developers read and think about code more than they actually write.
5. Automate it!
Having linters and prettier running in Continues Integration is a must. If the rules are violated then the build should fail. The bigger the project is the longer it takes to analyze the whole codebase. I am a big fan of linting only the files that were changed. So I am using:
- Husky — to manage git hooks,
- Lint staged — to run linters only against files that were changed.
How does it work? Husky reacts on git hook before committing files. Lint staged runs linters. Here is an example from
package.json of one of my projects:
"eslint --cache --fix"
"*.css": "stylelint \"src/**/*.css\" --fix"
In one of the projects I’m working on, linting JS files take more than 50 seconds when run against the whole project. Running it only against files that were modified within a commit takes close to nothing. Here is how it looks when I commit something to my blog:
I understand some people like to experiment and don’t always have clean commits that will pass linting. Fortunately, you can bypass the checks by adding
--no-verify argument. So for example:
git commit -m "Blog Post 005: Powerful start" --no-verify
6. Setup CI to deploy quickly
That’s another thing worth investing time in the beginning. The easier it is to deploy the better. Of course, set the pipeline and deploy only when tests are passing and linters are satisfied. I’m not giving any recipe this time because it differs between projects. If you use a service like Netlify then it should be super easy to do it. If you use something else invest the time to set up the process.
For open-source projects, I use Travis CI and for commercial (indie) projects I use CircleCI. I think Travis is completely free for opensource and Circle has a quite generous free plan (2,500 credits/week) that will be enough for a side-project.
In some cases, I have used GitHub Actions, like when I had to deploy a single static file to S3.
Updating your dependencies is important because you get security fixes and regular bugs fix. But who has time to remember about it? No-one. So it’s better to automate that process. If you happen to have tests in place with decent coverage then ideally you should be able to just merge Pull Requests created by Dependabot.
The tool was acquired by GitHub in May 2019 and since then it is offered free of charge.
That’s it. A few tools, a few configuration files, maybe two services to keep your project great and ready for fast deployment. I found myself adding these ingredients to every project I work on: server-side (in nodejs), React, Ember, Angular, standalone library, Chrome extension, React Native application, and so on. As you see, it’s not bounded to any technology so it’s hard to come up with a starter pack.
You can set the sails now.