SPFx 1.22 — Pre-commit hooks to improve quality
Why pre-commit hooks
Heft brings consistency to the SPFx 1.22 toolchain. Combine it with pre-commit hooks to keep code clean and catch issues early: format, lint, type-check key files before they get committed.
References:
- Heft toolchain: https://learn.microsoft.com/en-us/sharepoint/dev/spfx/toolchain/sharepoint-framework-toolchain-rushstack-heft
- Customize SPFx Heft rig: https://learn.microsoft.com/en-us/sharepoint/dev/spfx/toolchain/customize-heft-toolchain-overview
Tooling overview
- Husky: Git hooks manager
- lint-staged: Run linters on staged files only
- Prettier: Formatting
- ESLint: Linting (TypeScript 5.x compatible)
- Optional: Stylelint (via Heft run-script), Commitlint (conventional commits)
Install
# prerequisites: run inside your SPFx repo with git initialized
git init
npm i -D husky lint-staged prettier
# optional extras
npm i -D @commitlint/cli @commitlint/config-conventional
# initialize Husky (v9+). This creates the .husky/ folder
npx husky init
Add scripts to package.json:
{
"scripts": {
"prepare": "husky",
"lint": "heft test",
"format": "prettier --write ."
},
"lint-staged": {
"*.{ts,tsx,js,jsx}": ["eslint --max-warnings=0 --fix"],
"*.{css,scss}": ["stylelint --fix"],
"*.{md,mdx,json}": ["prettier --write"]
}
}
Husky hooks
Create hooks to run on staged files and block bad commits.
# pre-commit hook (Husky v9+)
echo 'npx --no-install lint-staged' > .husky/pre-commit
chmod +x .husky/pre-commit
# optional: commit-msg hook for conventional commits
echo 'npx --no-install commitlint --edit "$1"' > .husky/commit-msg
chmod +x .husky/commit-msg
Tie into Heft
Heft already runs lint in its rig. For stronger guarantees:
- Keep pre-commit fast by focusing on staged files.
- Run full
heft buildorheft testin CI for comprehensive checks.
Optional: add a Stylelint task in Heft using the Run Script plugin.
{
"$schema": "https://developer.microsoft.com/json-schemas/heft/v0/heft.schema.json",
"extends": "@microsoft/spfx-web-build-rig/profiles/default/config/heft.json",
"phasesByName": {
"build": {
"tasksByName": {
"stylelint": {
"taskPlugin": {
"pluginPackage": "@rushstack/heft",
"pluginName": "run-script-plugin",
"options": { "scriptPath": "./config/run-script/stylelint.mjs" }
}
}
}
}
}
}
import { execa } from "execa";
export async function runAsync() {
await execa("npx", ["stylelint", "src/**/*.scss", "--fix"], { stdio: "inherit" });
}
Note: ESLint is provided by the SPFx 1.22 Heft rig (@microsoft/spfx-web-build-rig). You typically don’t need a custom .eslintrc — rely on the rig defaults and use heft test --only lint -- for CI.
Suggested workflow
- Dev: rely on pre-commit hooks (fast feedback)
- CI: run
heft build,heft test, and packaging - Enforce formatting/lint via lint-staged; keep heavy checks for CI
TL;DR
- Add Husky + lint-staged to SPFx 1.22
- Format with Prettier, lint with ESLint (and Stylelint if needed)
- Keep hooks fast; use Heft for full lint/build in CI