Have you ever wondered if there was an easier way to manage your tooling across projects?
With so many tools in the frontend ecosystem to set up, it can be really time consuming and difficult to manage everything; taking time away you could be spending on actual development.
In this series, we'll cover approaches for managing tooling and how you can implement this yourself to increase your productivity. I'll be using my own personal setup throughout the series as a reference.
Frontend Tooling
Before we dive in, let's consider popular tooling a developer will need for frontend projects and how important it will be to manage them more efficiently.
-
Git Hooks
help automate the development lifecycle and tools likeHusky
help make setting this up easier across different systems. - Tools like
Commitizen
help standardize commit message rules with user friendly prompts andCommitlint
to lint commit messages -
Lint-Staged
helps automate code linting on changed files after commits -
Stylelint
lints styling,Postcss
provides a variety of plugins to transform css, andSass
helps scalecss
with helpful features. -
TypeScript
provides type-safety for projects -
Eslint
lints yourJavaScript
andTypeScript
code. -
Prettier
enforces consistent styling and across your entire codebase and provides linting -
Jest
is a popular testing framework -
Browserslist
defines your supported browsers/devices -
Secretlint
helps prevent accidently committing credentials - Tools like
HTMLHint
andMarkdownlint
linthtml
andmd
files -
Semantic Release
automates versioning and publishing
That was a lot! But our tooling isn't limited to the list above. You might be using a framework or a completely different setup that will require its own set up of tools which is why it's important to think of ways to make managing this easier.
Extendable Configurations
Luckily for us, many of the tools above provide ways to create our own custom configurations and extend them by reference.
For example, we might define our own eslint
configuration:
index.js
module.exports = {
// my custom eslint setup
}
But how do we reference this in our own projects? We'll want to publish this somewhere like npm
so we can download anywhere and install in our project.
In our project's .eslintrc.js
file we can define our configuration like so:
.eslintrc.js
module.exports = {
extends: '@[unique-scoped-name]/eslint-config',
};
See eslint's guide for more information.
Versioning and Publishing
So far so good, but what if we need to make a change to our shareable configuration? We'll don't want to manually bump our package.json
version and manually publish out to npm
.
Let's automate! We can use a tool like semantic-release
to do this for us:
.github/workflows/release.yml
...
- name: Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: npx semantic-release
And in our .releaserc.json
file:
.releaserc.json
{
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
"@semantic-release/changelog",
"@semantic-release/npm",
"@semantic-release/github",
"@semantic-release/git"
],
"branches": "main"
}
In this setup, we have semantic release automating versioning, publishing to npm
, and changelog generation to help us keep track of changes.
Monorepos
For publishing one or two packages, this setup works well. But what if we have several configurations to maintain? This setup will be hard to scale. We'll need to rethink our approach.
This is where monorepos come to save the day. A monorepo is like a regular repo, except that it can hold many projects. If we have a lot of configurations we can keep and maintain them in the same repository.
What if we want to automate versioning and publishing? Using semantic-release
won't work in a monorepo setup. But with a monorepo tool like Lerna
we can leverage it to version and publish multiple changed packages.
We can also use a tool called Yarn Workspaces
to optimize and link different packages together. While Lerna
can do this too, Yarn Workspaces
offers improved performance.
Conclusion
After reviewing our options, a more ideal setup for managing multiple configurations involves using a monorepo structure to manage, version, and publish our packages.
A common monorepo structure for our configurations will look like the following:
/
.github/
# github CI/CD files
packages/
eslint-config/
stylelint-config/
...
package.json
lerna.json
...
In part 2 of this series, we'll go into detail on how to set up this repository. I'll be basing this off my own personal shareable configuration monorepo. Follow for updates on new article releases!
Top comments (0)