Using Yalc to Test Node Packages Locally
The first step to improve code quality is to start using static testing tools. Static testing checks code for errors as we write it, but without running any of that code.
- Linters analyze code to catch common errors such as unused code and to help avoid pitfalls, to flag style guide no-nos like using tabs instead of spaces (or vice versa, depending on the configuration). In this case we will use ESLint and Commitlint
- Type checking ensures that the construct passed to a function matches what the function was designed to accept, preventing passing a string to a counting function that expects a number, for instance. In this case we will use Typescript.
Setup
1. Setting up Commitlint and Husky
Install Commitlint and its conventional config to ensure commit messages meet the conventional commit format.
npm install --save-dev @commitlint/{cli,config-conventional}
Configure Commitlint to use the conventional configuration:
echo "module.exports = { extends: ['@commitlint/config-conventional'] };" > commitlint.config.cjs
Install Husky to manage Git hooks:
npm install husky@latest --save-dev
Activate Husky hooks:
npx husky install
Ensure Git hooks are automatically enabled after installation by adding a script in package.json
:
npm pkg set scripts.prepare="husky install"
Add a commit message hook:
npx husky add .husky/commit-msg 'npx --no -- commitlint --edit ${1}'
2. Installing and Setting up Prettier
Prettier automates code formatting. Install Prettier and its types:
npm install --save-dev prettier @types/prettier
Configure Prettier rules:
touch prettier.config.js
Add some configuration. We will edit this file as we needed more custom configuration
// prettier.config.js
// You can customize rules as you like.
/** @type {import("prettier").Config} */
const config = {
singleQuote: true,
trailingComma: "all",
printWidth: 100,
};
module.exports = config;
Optionally, create a .prettierignore file to exclude specific files and directories from formatting:
touch .prettierignore
// add files or folders that you want to be ignored by prettier
// e.g for nextjs project
.next
next-env.d.ts
pnpm-lock.yaml
yarn.lock
.husky/
.prettierignore
Add a script to package.json
for easy formatting:
npm pkg set scripts.prettify="prettier --write ."
Run Prettier across project:
npm run prettify
3. Setting up lint-staged
Lint-staged runs linters on staged Git files. This is useful since we don’t want to check all files in the repo everytime we want to commit or push some changes.
Install lint-staged:
npm install --save-dev lint-staged
Create linstage configuration file
touch .lintstagedrc
Add configuration
{
"*": "eslint --fix"
}
Set up a pre-commit hook to run lint-staged:
npx husky add .husky/pre-commit 'npx lint-staged'
4. Setting up Eslint Checks on GitHub Actions
As a bonus, add a typecheck script to ensure type safety:
npm pkg set scripts.typecheck="tsc --noEmit"
Create a continuous integration (CI) workflow for GitHub Actions:
mkdir -p ./.github/workflows/ && nano ./.github/workflows/ci.yml
Define the CI workflow:
name: CI
on:
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
version: 8
- uses: actions/setup-node@v3
- run: npm install
- run: npm run typecheck
- run: npm run lint