Last active
November 3, 2022 05:04
-
-
Save jonathanhudak/96600bce4540cb7bf29a4b9211bebbc5 to your computer and use it in GitHub Desktop.
Setup NPM Package
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# This script installs and configures typescript, eslint, prettier and commitizen for a basic NodeJS package. | |
# If all goes well you will have precommit hooks that lint and format your code and a prompt to craft a conventional commit message. 😎 | |
# It is largely based on https://jamesandrewwright.com/articles/commitizen-eslint-prettier-husky/ | |
step() { | |
read -p "$1? " -r | |
echo # (optional) move to a new line | |
if [[ $REPLY =~ ^[Yy]$ ]] | |
then | |
echo "[Running]: $2" | |
eval "$2" | |
fi | |
} | |
stepWithFn() { | |
read -p "$1? " -r | |
echo # (optional) move to a new line | |
if [[ $REPLY =~ ^[Yy]$ ]] | |
then | |
($2) | |
fi | |
} | |
stepWithInput() { | |
read -p "$1? " -r | |
echo # (optional) move to a new line | |
if [[ $REPLY =~ ^[Yy]$ ]] | |
then | |
read -p "$2 " -r | |
echo # (optional) move to a new line | |
($3 $REPLY) | |
fi | |
} | |
manualStep() { | |
echo -e "$@" | |
read -p "Are you done? " -r | |
echo # (optional) move to a new line | |
if [[ $REPLY =~ ^[Yy]$ ]] | |
then | |
echo | |
fi | |
} | |
# --- BEGIN | |
step \ | |
"Initialize git repo" \ | |
"git init" \ | |
# setup typescript | |
step \ | |
"Setup typescript" \ | |
"npm install typescript --save-dev && npx tsc --init" \ | |
# --- | |
# Prettier and ESLint | |
step \ | |
"Install Prettier and ESLint node modules from npm" \ | |
"npm install eslint prettier eslint-config-prettier --save-dev" | |
step \ | |
"Create ESLint configuration file" \ | |
"npm init @eslint/config" | |
step \ | |
"Create ESLint ignore file" \ | |
"echo .eslintrc.js >> .eslintignore" | |
step \ | |
"Create .prettierrc" \ | |
"echo -e '{\n\t\"tabWidth\": 4\n}' >> .prettierrc" | |
step \ | |
"Create .prettierignore" \ | |
"echo -e '# Ignore artifacts:\npackage-lock.json\nbuild\ncoverage' >> .prettierignore" | |
manualStep \ | |
"Add \"prettier\" to eslint config \"extends\"\n" \ | |
'\nExample:\n\t"extends": ["eslint:recommended", "prettier"],\n' | |
checkRules() { | |
eval "npx eslint-config-prettier $1" ; | |
} | |
stepWithInput \ | |
"Run npx eslint-config-prettier" \ | |
"Provide a path to your files:" \ | |
checkRules | |
# Testing ESLint and Prettier | |
testESLintPrettier() { | |
p=${1:-"."} | |
eval "npx eslint . $p" | |
eval "npx prettier --check . $p" | |
eval "npx prettier --write . $p" | |
} | |
stepWithInput \ | |
"Test eslint and prettier" \ | |
"Provide a path - [Press Enter] for default (.):" \ | |
testESLintPrettier | |
# Adding helper scripts to package.json | |
# https://docs.npmjs.com/cli/v7/commands/npm-pkg | |
step \ | |
'Add "prettier:check" script to package.json' \ | |
"npm pkg set 'scripts.prettier:check'='npx prettier --check .'" | |
step \ | |
'Add "prettier:fix" script to package.json' \ | |
"npm pkg set 'scripts.prettier:fix'='npx prettier --write .'" | |
step \ | |
'Add "lint" script to package.json' \ | |
"npm pkg set 'scripts.lint'='npx eslint .'" | |
# --- | |
# Add extensions to VSCode (optional) | |
addExtensions() { | |
mkdir -p .vscode | |
cat >.vscode/extensions.json <<EOL | |
{ | |
"recommendations": [ | |
"dbaeumer.vscode-eslint", | |
"esbenp.prettier-vscode" | |
] | |
} | |
EOL | |
} | |
stepWithFn \ | |
"Add recommended .vscode/extensions.json" \ | |
addExtensions | |
#TODO | |
# husky | |
step \ | |
"Setup and install Husky to configure git hooks" \ | |
"npx husky-init && npm install --save-dev" | |
# lint-staged | |
step \ | |
"Setup and install \"lint-staged\" to limit linting to staged files" \ | |
"npm install lint-staged --save-dev" | |
addLintStagedConfig() { | |
npm pkg set 'lint-staged[*.{css,html,json,jsx,js,ts,tsx}][0]=prettier --write' | |
npm pkg set 'lint-staged[*.{js,jsx,ts,tsx}][0]=eslint --fix' | |
} | |
stepWithFn \ | |
'Add "lint-staged" config to package.json' \ | |
addLintStagedConfig | |
updateHuskyPreCommit() { | |
cat << EOF > "$PWD/.husky/pre-commit" | |
#!/bin/sh | |
. "\$(dirname "\$0")/_/husky.sh" | |
npx lint-staged | |
EOF | |
} | |
stepWithFn \ | |
"Update .husky/pre-commit" | |
updateHuskyPreCommit | |
# Commitizen and friends | |
installCommitizen() { | |
npm install commitizen cz-conventional-changelog @commitlint/cli @commitlint/config-conventional --save-dev | |
npm pkg set 'scripts.commitizen:init'='commitizen init cz-conventional-changelog --save-dev --save-exact' | |
npm run commitizen:init | |
} | |
stepWithFn \ | |
"Install Commitizen, cz-conventional-changelog lint-staged and @commitlint" | |
installCommitizen | |
addCommitLintConfig() { | |
cat << EOF > "$PWD/commitlint.config.js" | |
module.exports = { extends: ["@commitlint/config-conventional"] }; | |
EOF | |
} | |
stepWithFn \ | |
"Create commitlint.config.js" \ | |
addCommitLintConfig | |
# .husky/prepare-commit-msg | |
updateHuskyPrepareCommitMessage() { | |
cat << EOF > "$PWD/.husky/prepare-commit-msg" | |
#!/bin/sh | |
. "\$(dirname "\$0")/_/husky.sh" | |
exec < /dev/tty && node_modules/.bin/cz --hook || true | |
EOF | |
} | |
stepWithFn \ | |
"Update .husky/prepare-commit-msg" | |
updateHuskyPrepareCommitMessage | |
# .husky/commit-msg | |
updateHuskyCommitMessage() { | |
cat << EOF > "$PWD/.husky/commit-msg" | |
#!/bin/sh | |
. "\$(dirname "\$0")/_/husky.sh" | |
npx commitlint --edit $1 | |
EOF | |
} | |
stepWithFn \ | |
"Update .husky/commit-msg" | |
updateHuskyCommitMessage | |
makeHuskyExec() { | |
chmod +x "$PWD/./husky/*" | |
} | |
makeHuskyExec() { | |
chmod +x "$PWD/.husky/commit-msg" | |
chmod +x "$PWD/.husky/pre-commit" | |
chmod +x "$PWD/.husky/prepare-commit-msg" | |
} | |
stepWithFn \ | |
"Make .husky scripts executable" \ | |
makeHuskyExec | |
echo -e "\n\nAll done! Test with:\n\tgit add .\n\tgit commit -m \"I am a cowboy\"\n\n" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment