lint-staged 是一個在git暫存文件上運行linters的工具,當然如果你覺得每次修改一個文件就給所有文件執行一次lint檢查不惡心的話,這個工具對你來說就沒有什么意義了,請直接關閉即可。
npx mrm lint-staged
它將根據package.json
依賴項中的代碼質量工具來安裝和配置husky和lint-staged
,因此請確保在此之前安裝(npm install --save-dev
)並配置所有代碼質量工具,如Prettier和ESlint。
不要忘記提交對package.json
的更改以與您的團隊共享此設置!
現在更改一些文件,git add
或git add --patch
將其中一些文件修補到您的提交中,並嘗試git提交它們。
命令行標志
❯ npx lint-staged --help 用法: lint-staged [options] Options: -V, --version 輸出版本號 --allow-empty 當任務撤消所有分階段的更改時允許空提交(默認值:false) -c, --config [path] 配置文件的路徑 -d, --debug 打印其他調試信息(默認值:false) -p, --concurrent <parallel tasks> 要同時運行的任務數,或者為false則要連續運行任務(默認值:true) -q, --quiet 自己的控制台輸出(默認值:false) -r, --relative 將相對文件路徑傳遞給任務(默認值:false) -x, --shell 跳過任務解析以更好地支持shell(默認值:false) -h, --help 輸出用法信息
--allow-empty
: 默認情況下,當LITER任務撤消所有階段性的更改時,LITET階段將退出一個錯誤,並中止提交。使用此標志允許創建空git提交。--config [path]
: 手動指定配置文件或npm包名稱的路徑。注意:使用時,lint-staged
不會執行配置文件搜索,如果找不到指定的文件,則會打印錯誤。--debug
:在調試模式下運行。設置后,它將執行以下操作- 在內部使用debug記錄有關暫存文件、正在執行的命令、二進制文件的位置等的其他信息。通過傳遞標志自動啟用的調試日志也可以通過將環境變量
$DEBUG
設置為lint-staged*
啟用。 - 使用verbose渲染程序的listr; 這將導致串行無色輸出到終端,而不是默認(美化,動態)輸出。
- 在內部使用debug記錄有關暫存文件、正在執行的命令、二進制文件的位置等的其他信息。通過傳遞標志自動啟用的調試日志也可以通過將環境變量
--concurrent [number | (true/false)]
: 控制由lint-staged運行的任務的並發性。注意:這不會影響子任務的並發性(它們將始終按順序運行)。可能的值為:false
:依次運行所有任務true
(默認):無限並發。並行運行盡可能多的任務{number}
:並行運行指定數量的任務,其中1
等效於false
。
--quiet
:禁止所有CLI輸出,但任務中除外。--relative
: 將與process.cwd()
(lint-staged
運行)相關的文件路徑傳遞給任務。默認值為false
。--shell
:默認情況下,將分析linter命令以提高速度和安全性。這具有常規shell腳本可能無法按預期工作的副作用。您可以使用此選項跳過命令解析。
配置
從v3.1開始,您現在可以使用不同的方式進行配置:
lint-staged
在你的對象package.json
.lintstagedrc
JSON或YML格式的文件lint-staged.config.js
JS格式的文件- 使用
--config
或-c
標志傳遞配置文件
配置應該是一個對象,其中每個值都是要運行的命令,其鍵是要用於此命令的glob模式。這個軟件包使用micromatch進行全局模式匹配。
package.json
例:
{ "lint-staged": { "*": "your-cmd" } } .lintstagedrc 例: { "*": "your-cmd" }
該配置將your-cmd
使用作為參數傳遞的當前暫存文件的列表執行。
因此,考慮到您做了git add file1.ext file2.ext
,lint-staged
將運行以下命令:your-cmd file1.ext file2.ext
過濾文件
Linter命令處理由glob模式定義的所有暫存文件的子集。lint staged
使用micromatch將文件與以下規則匹配:
- 如果全局模式不包含斜杠(
/
),matchBase
則將啟用micromatch的選項,因此無論目錄如何,全局匹配文件的基本名稱:"*.js"
將匹配所有JS文件,例如/test.js
和/foo/bar/test.js
2."!(*test).js"
。將匹配所有以結尾的JS文件test.js
,因此foo.js
但不匹配foo.test.js
- 如果全局模式確實包含斜杠(
/
),則它也將與路徑匹配:"./*.js"
將匹配git repo根目錄中的所有JS文件,因此/test.js
但不匹配/foo/bar/test.js
2."foo/**/\*.js"
將匹配/foo
目錄中的所有JS文件,所以/foo/bar/test.js
但不匹配/test.js
匹配時,lint-staged
將執行以下操作
- 自動解決git root,無需配置。
- 選擇項目目錄中存在的暫存文件。
- 使用指定的glob模式過濾它們。
- 將絕對路徑傳遞給linters作為參數。
注意: lint-staged
將絕對路徑傳遞給linter,以免在其他工作目錄(例如,您的.git
目錄與您的package.json
目錄不同)中執行時產生混淆。
忽略文件
lint-staged
的概念是在git中暫存的文件上運行已配置的linter(或其他)任務。lint-staged
總是將所有暫存文件的列表傳遞給任務,忽略任何文件都應該在任務本身中配置。
考慮一個prettier用於使代碼格式在所有文件中保持一致的項目。 項目還將縮小的第三方供應商庫存儲在vendor/
目錄中。為了防止prettier在這些文件上拋出錯誤,應該將供應商目錄添加到prettier的忽略配置.prettierignore
文件中。運行npx prettier .
。將忽略整個供應商目錄,不會引發錯誤。當lint-staged
被添加到項目並配置為運行prettier時,prettier將忽略供應商目錄中所有修改的和暫存的文件,即使它將它們作為輸入接收。
在高級方案中,如果無法將linter任務本身配置為忽略文件,但lint-staged
仍應忽略某些暫存文件,則可以在使用函數語法將文件路徑傳遞給任務之前對其進行篩選。請參見示例:忽略match中的文件。
支持哪些命令?
支持通過本地或全局安裝的任何可執行文件npm
,以及$PATH
中的任何可執行文件。
不建議使用全局安裝的腳本,因為對於沒有安裝腳本的人,lint-staged
可能不起作用。
lint-staged
使用execa查找本地安裝的腳本。因此,您.lintstagedrc
可以編寫:
{ "*.js": "eslint --fix" }
依次運行多個命令
可以在每個glob上按順序運行多個命令。為此,請傳遞一個命令數組而不是單個命令。這對於運行諸如eslint --fix
或stylefmt
之類的自動格式化工具很有用,但可以用於任何任意序列。
例如:
{ "*.js": ["eslint", "prettier --write"] }
要執行esLIt,如果它用0
個代碼退出,它將執行prettier --write
所有暫存的*.js
文件。
使用JS函數自定義任務
當以JS格式提供配置時,可以將任務定義為一個函數,該函數將接收一個分段文件名/路徑數組,並應以字符串形式返回完整的命令。也可以返回一個完整的命令字符串數組,例如當任務只支持單個文件輸入時。函數可以是sync或async。
type TaskFn = (filenames: string[]) => string | string[] | Promise<string | string[]>
示例:將文件名用單引號引起來,並在每個文件中運行一次
// .lintstagedrc.js module.exports = { '**/*.js?(x)': filenames => filenames.map(filename => `prettier --write '${filename}'`) }
示例:運行tsc
對TypeScript文件的更改,但不傳遞任何文件名參數
// lint-staged.config.js module.exports = { '**/*.ts?(x)': () => 'tsc -p tsconfig.json --noEmit' }
示例:如果超過10個暫存文件,則在整個存儲庫上運行eslint
// .lintstagedrc.js module.exports = { '**/*.js?(x)': filenames => (filenames.length > 10 ? 'eslint .' : `eslint ${filenames.join(' ')}`) }
示例:使用自己的全局
// lint-staged.config.js const micromatch = require('micromatch') module.exports = { '*': allFiles => { const match = micromatch(allFiles, ['*.js', '*.ts']) return `eslint ${match.join(' ')}` } }
示例:忽略匹配文件
如果出於某種原因要忽略全局匹配中的文件,則可以使用micromatch.not()
:
// lint-staged.config.js const micromatch = require('micromatch') module.exports = { '*.js': files => { // from `files` filter those _NOT_ matching `*test.js` const match = micromatch.not(files, '*test.js') return `eslint ${match.join(' ')}` } }
請注意,在大多數情況下,全局效果可以達到相同的效果。對於上面的示例,匹配的glob為!(*test).js
。
** 示例:對命令使用相對路徑 **
const path = require('path') module.exports = { '*.ts': absolutePaths => { const cwd = process.cwd() const relativePaths = absolutePaths.map(file => path.relative(cwd, file)) return `ng lint myProjectName --files ${relativePaths.join(' ')}` } }
重新格式化代碼
像Prettier、ESLint/TSLint或stylelint這樣的工具可以根據適當的配置重新格式化代碼,方法是運行Prettier--write
/ ESLint --fix
/ TSLint --fix
/ stylelint --fix
。只要沒有錯誤,lint-staged
將自動向提交添加任何修改。
{ "*.js": "prettier --write" }
在版本10之前,git add
作為最后一步,必須手動包含任務。此行為已集成到lint階段本身中,以防止多個任務編輯同一文件時出現爭用情況。如果lint-staged
git add
在任務配置中檢測到,它將在控制台中顯示警告。git add
升級后,請從您的配置中刪除。
例子
假設您已經在中設置了lint-staged和husky的所有示例package.json
。
{ "name": "My project", "version": "0.1.0", "scripts": { "my-custom-script": "linter --arg1 --arg2" }, "husky": { "hooks": { "pre-commit": "lint-staged" } }, "lint-staged": { "*.{js}": [ "eslint --cache --fix", "prettier --write" ], "*.css": [ "stylelint --cache --fix", "prettier --write" ] } }
注意,我們不將路徑作為命令調用時的參數傳遞。這一點很重要,因為lint-stage將為您完成這一點。
具有默認參數的ESLint *.js
並*.jsx
作為預提交掛鈎運行
{ "*.{js,jsx}": "eslint" }
自動修復代碼樣式--fix
並添加提交
{ "*.js": "eslint --fix" }
這將運行eslint --fix
並自動向提交添加更改。
重用npm腳本
如果您想重用package.json
中定義的npm腳本:
{ "*.js": "npm run my-custom-script --" } 以
下是等效的:
{ "*.js": "linter --arg1 --arg2" }
在linting命令中使用環境變量
Linting命令不支持擴展環境變量的Shell約定。要自己啟用該約定,請使用諸如之類的工具cross-env。
例如,此處jest
正在.js
將NODE_ENV
變量設置為的所有文件上運行"test"
:
{ "*.js": ["cross-env NODE_ENV=test jest --bail --findRelatedTests"] }
使用prettier
自動修復javascript
、typescript
、markdown
、HTML
或CSS
的代碼樣式
{ "*.{js,jsx,ts,tsx,md,html,css}": "prettier --write" }
Stylelint用於具有默認值的CSS和具有SCSS語法的SCSS
{ "*.css": "stylelint", "*.scss": "stylelint --syntax=scss" }
運行PostCSS排序和Stylelint進行檢查
{ "*.scss": ["postcss --config path/to/your/config --replace", "stylelint"] }
縮小圖像
{ "*.{png,jpeg,jpg,gif,svg}": "imagemin-lint-staged" }
imagemin-lint-staged
是一個CLI工具,專門用於具有合理默認值的lint-staged使用。
使用流對您的暫存文件進行類型檢查
{ "*.{js,jsx}": "flow focus-check" }