Tutorial project to configure Husky with:
- Lint-staged (using semistandard lint)
- Commitlint
- Commitizen
Please keep this list up to date!
Project organized by branches, for each configuration/structure added, create a new branch and tell us a story (in the readme) of how to use it creating a new step in the list.
1. [ optional ] Create a basic index.js (back-end) [branch: feat-node-express-cors]
Optional: if you already have a project created and just need to set up hooks, skip this step
Added to test the lint-staged and confirm that code is still running.
Express - https://github.com/expressjs/express
Cors - https://github.com/expressjs/cors
npm i --save express cors;
something like:
const cors = require('cors');
const express = require('express');
const app = express();
const port = 3000;
let thisWillGiveError = "";
app.use(express.json());
app.use(cors());
app.get('/', (req, res) => {
console.log('GET / called!')
res.send('All configured!');
});
app.listen(port);
console.log(`Running on ${port}!`);
npm start
> husky-scaffold@1.0.0 start D:\dev\personal\projects\study\guides\husky-scaffold
> node index.js
Running on 3000!
Open localhost:3000 in a browser and check the console message
$ npm start
> husky-scaffold@1.0.0 start D:\dev\personal\projects\study\guides\husky-scaffold
> node index.js
Running on 3000!
GET / called!
2. Add husky [branch: feat-husky]
Add husky to configure hooks.
Husky - https://github.com/typicode/husky
npm i --save-dev husky@4;
I'm using v4 because v5 is in early access (on the date this file was created)
{
"hooks": {
"pre-commit": "echo \"[Husky] pre-commit example message\"",
"commit-msg": "echo \"[Husky] commit-msg example message\"",
"prepare-commit-msg": "echo \"[Husky] prepare-commit-msg example message\""
}
}
git add .huskyrc.json
git commit -m "feat: add husky configs"
husky > pre-commit (node v12.18.3)
[Husky] pre-commit example message
husky > prepare-commit-msg (node v12.18.3)
[Husky] prepare-commit-msg example message
husky > commit-msg (node v12.18.3)
[Husky] commit-msg example message
[feat-husky dfd1f8d] feat: add husky configs
1 file changed, 7 insertions(+)
create mode 100644 .huskyrc.json
If you see a log like the one above, you have successfully configured husky in your project!
3. Add semistandard and lint-staged [branch: feat-semistandard-lint-staged]
Add semistandard lint and lint-staged for lint automation.
Semistandard - https://github.com/standard/semistandard
Lint-Staged - https://github.com/okonet/lint-staged
npm i --save-dev semistandard lint-staged;
Editorconfig - https://editorconfig.org/
Below a example of .editorconfig file (check if your IDE have a plugin to generate automatically)
# https://editorconfig.org
root = true
[*]
indent_style = space
indent_size = 2
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
end_of_line = lf
[*.md]
trim_trailing_whitespace = false
[*.js]
quote_type = "single"
This configuration below is used to check all files with extension '.js' and check the style with semistandard rules
{
"*.js": [
"./node_modules/.bin/semistandard --fix"
]
}
If you want to use another lint, this is where you must change to which lint you want (and add it to the project via npm)
{
"hooks": {
"hooks": {
"pre-commit": "./node_modules/.bin/lint-staged",
"commit-msg": "echo \"[Husky] commit-msg example message\"",
"prepare-commit-msg": "echo \"[Husky] prepare-commit-msg example message\""
}
}
If you are using my file to create a backend with express (index.js), you should check the contents of this file.
There are two errors that the semistandard will not like:
- line 6
let thisWillGiveError = ""
'thisWillGiveError' is assigned a value but never used. (no-unused-vars)semistandard(no-unused-vars)
- line 12
console.log('GET / called!')
Missing semicolon. (semi)semistandard(semi
To test the lint-staged, resolve one of them and commit the index.js file For this documentation. I'll solve the second, add semicolon in line 12 and committing file:
elcio@DESKTOP-H3TVAF1 MINGW64 /d/dev/personal/projects/study/guides/husky-scaffold (feat-semistandard-lint-staged)
$ git add index.js
elcio@DESKTOP-H3TVAF1 MINGW64 /d/dev/personal/projects/study/guides/husky-scaffold (feat-semistandard-lint-staged)
$ git commit -m "refactor: update index to test lint-staged"
husky > pre-commit (node v12.18.3)
[STARTED] Preparing...
[SUCCESS] Preparing...
[STARTED] Running tasks...
[STARTED] Running tasks for *.js
[STARTED] ./node_modules/.bin/semistandard --fix
[FAILED] ./node_modules/.bin/semistandard --fix [FAILED]
[FAILED] ./node_modules/.bin/semistandard --fix [FAILED]
[SUCCESS] Running tasks...
[STARTED] Applying modifications...
[SKIPPED] Skipped because of errors from tasks.
[STARTED] Reverting to original state because of errors...
[SUCCESS] Reverting to original state because of errors...
[STARTED] Cleaning up...
[SUCCESS] Cleaning up...
β ./node_modules/.bin/semistandard --fix:
semistandard: Semicolons For All! (https://github.com/standard/semistandard)
D:\dev\personal\projects\study\guides\husky-scaffold\index.js:6:7: 'thisWillGiveError' is assigned a value but never used.
husky > pre-commit hook failed (add --no-verify to bypass)
If you see a log like the one above, you have successfully configured lint-staged and lint (semistandard) in your project!
4. Add commitlint [branch: feat-commitlint]
Add commitlint to check the messages of commits
Commitlint - https://github.com/conventional-changelog/commitlint
npm install --save-dev @commitlint/{cli,config-conventional}
This configuration below is used to set the config-conventional for your commit messages https://www.conventionalcommits.org
{
"extends": ["@commitlint/config-conventional"]
}
{
"hooks": {
"hooks": {
"pre-commit": "./node_modules/.bin/lint-staged",
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS",
"prepare-commit-msg": "echo \"[Husky] prepare-commit-msg example message\""
}
}
First, confirm and send the package.json and the configuration file.
After doing this, all of your commit messages will be checked, so let's try it out!
Change the index.js by adding some '!' on one of the code consoles.
Now, let's test the commitlint.
elcio@DESKTOP-H3TVAF1 MINGW64 /d/dev/personal/projects/study/guides/husky-scaffold (feat-commitlint)
$ git add index.js
elcio@DESKTOP-H3TVAF1 MINGW64 /d/dev/personal/projects/study/guides/husky-scaffold (feat-commitlint)
$ git commit -m "update index to test commitlint"
husky > pre-commit (node v12.18.3)
[STARTED] Preparing...
[SUCCESS] Preparing...
[STARTED] Running tasks...
[STARTED] Running tasks for *.js
[STARTED] ./node_modules/.bin/semistandard --fix
[SUCCESS] ./node_modules/.bin/semistandard --fix
[SUCCESS] Running tasks for *.js
[SUCCESS] Running tasks...
[STARTED] Applying modifications...
[SUCCESS] Applying modifications...
[STARTED] Cleaning up...
[SUCCESS] Cleaning up...
husky > prepare-commit-msg (node v12.18.3)
[Husky] prepare-commit-msg example message
husky > commit-msg (node v12.18.3)
β§ input: update index to test commitlint
β subject may not be empty [subject-empty]
β type may not be empty [type-empty]
β found 2 problems, 0 warnings
β Get help: https://github.com/conventional-changelog/commitlint/#what-is-commitlint
husky > commit-msg hook failed (add --no-verify to bypass)
If you see a log like the one above, you have successfully configured commitlint in your project!
5. [ optional ] Add commitizen [branch: feat-commitizen]
Add commitizen, a cli for commit messages
Commitizen - https://github.com/commitizen/cz-cli
npm install --save-dev commitizen
Running this configuration, commitizen will add a configuration and update your package.json file with additional properties.
./node_modules/.bin/commitizen init cz-conventional-changelog --save-dev --save-exact
To run more easily, add the 'cz' script
"scripts": {
"start": "node index.js",
"cz": "./node_modules/.bin/cz"
},
{
"hooks": {
"pre-commit": "./node_modules/.bin/lint-staged",
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS",
"prepare-commit-msg": "/dev/tty && git ./node_modules/.bin/cz --hook || true"
}
}
Why exec < /dev/tty? By default, git hooks are not interactive. This command allows the user to use their terminal to interact with Commitizen during the hook.
First, confirm and commit the package.json and the configuration file.
Now, let's test the commitizen.
elcio@DESKTOP-H3TVAF1 MINGW64 /d/dev/personal/projects/study/guides/husky-scaffold (feat-commitizen)
$ npm run cz
cz-cli@4.2.3, cz-conventional-changelog@3.2.0
? Select the type of change that you're committing: refactor: A code change that neither fixes a bug nor adds a feature
? What is the scope of this change (e.g. component or file name): (press enter to skip)
? Write a short, imperative tense description of the change (max 90 chars):
(35) update index to test commitizen cli
? Provide a longer description of the change: (press enter to skip)
? Are there any breaking changes? No
? Does this change affect any open issues? No
husky > pre-commit (node v12.18.3)
[STARTED] Preparing...
[SUCCESS] Preparing...
[STARTED] Running tasks...
[STARTED] Running tasks for *.js
[STARTED] ./node_modules/.bin/semistandard --fix
[SUCCESS] ./node_modules/.bin/semistandard --fix
[SUCCESS] Running tasks for *.js
[SUCCESS] Running tasks...
[STARTED] Applying modifications...
[SUCCESS] Applying modifications...
[STARTED] Cleaning up...
[SUCCESS] Cleaning up...
husky > prepare-commit-msg (node v12.18.3)
sh: /dev/tty: No such file or directory
husky > commit-msg (node v12.18.3)
[feat-commitizen 039bf67] refactor: update index to test commitizen cli
1 file changed, 1 insertion(+), 1 deletion(-)
If you see a log like the one above, you have successfully configured commitizen in your project!
To remove the settings we created in package.json when starting commitizen. This step is optional and has the purpose of organizing this configuration creating a separate file.
This configuration below just tells Commitizen which adapter actually want when try to commit to this repo
{
"path": "./node_modules/cz-conventional-changelog"
}
If you opted to use a specific configuration file, you need to remove the same lines in package.json
"config": {
"commitizen": {
"path": "./node_modules/cz-conventional-changelog"
}
}
Want to contribute? Follow these recommendations.