เรียกใช้ linters กับไฟล์ git ที่จัดฉากแล้วอย่าให้ ? เข้าสู่ฐานรหัสของคุณ!
npm install --save-dev lint-staged # requires further setup
$ git commit
✔ Preparing lint-staged...
❯ Running tasks for staged files...
❯ packages/frontend/.lintstagedrc.json — 1 file
↓ *.js — no files [SKIPPED]
❯ *.{json,md} — 1 file
⠹ prettier --write
↓ packages/backend/.lintstagedrc.json — 2 files
❯ *.js — 2 files
⠼ eslint --fix
↓ *.{json,md} — no files [SKIPPED]
◼ Applying modifications from tasks...
◼ Cleaning up temporary files...
Linting เหมาะสมกว่าเมื่อรันก่อนที่จะคอมมิตโค้ดของคุณ การทำเช่นนี้จะทำให้คุณมั่นใจได้ว่าไม่มีข้อผิดพลาดใดเข้าไปในพื้นที่เก็บข้อมูลและบังคับใช้รูปแบบโค้ด แต่การรันกระบวนการกำจัดขุยทั้งโปรเจ็กต์นั้นช้า และผลลัพธ์ของการขุยอาจไม่เกี่ยวข้อง ท้ายที่สุดคุณเพียงต้องการเพียงแค่ไฟล์ผ้าสำลีที่จะคอมมิตเท่านั้น
โปรเจ็กต์นี้มีสคริปต์ที่จะรันงานเชลล์ที่กำหนดเองพร้อมรายการไฟล์ที่จัดฉากเป็นอาร์กิวเมนต์ ซึ่งกรองตามรูปแบบ glob ที่ระบุ
dotnet-format
และ lint-staged
หากคุณเคยเขียนไว้ โปรดส่ง PR พร้อมลิงก์ไปได้เลย!
หากต้องการติดตั้ง Lint-staged ด้วยวิธีที่แนะนำ คุณต้อง:
npm install --save-dev lint-staged
pre-commit
เพื่อรัน lint-staged{ "*.js": "eslint" }
เพื่อรัน ESLint สำหรับไฟล์ JS ที่จัดฉากทั้งหมด อย่าลืมยอมรับการเปลี่ยนแปลงใน package.json
และ .husky
เพื่อแชร์การตั้งค่านี้กับทีมของคุณ!
ตอนนี้เปลี่ยนไฟล์บางไฟล์ git add
หรือ git add --patch
บางไฟล์ในการคอมมิตของคุณ และลองคอม git commit
ไฟล์เหล่านั้น
ดูตัวอย่างและการกำหนดค่าสำหรับข้อมูลเพิ่มเติม
ดูข่าวประชาสัมพันธ์
v15.0.0
lint-staged ไม่รองรับ Node.js 16 อีกต่อไป โปรดอัปเกรดเวอร์ชัน Node.js ของคุณเป็นอย่างน้อย 18.12.0
v14.0.0
lint-staged ไม่รองรับ Node.js 14 อีกต่อไป โปรดอัปเกรดเวอร์ชัน Node.js ของคุณเป็นอย่างน้อย 16.14.0
v13.0.0
lint-staged ไม่รองรับ Node.js 12 อีกต่อไป โปรดอัปเกรดเวอร์ชัน Node.js ของคุณเป็นอย่างน้อย 14.13.1
หรือ 16.0.0
เป็นต้นไปv13.3.0
ได้รับการเผยแพร่อย่างไม่ถูกต้อง รวมถึงโค้ดของเวอร์ชัน v14.0.0
ซึ่งหมายความว่าการเปลี่ยนแปลงล่าสุดของ v14
จะรวมอยู่ใน v13.3.0
ซึ่งเป็นเวอร์ชัน v13
ล่าสุดที่เปิดตัว v12.0.0
lint-staged เป็นโมดูล ESM ล้วนๆ ดังนั้นตรวจสอบให้แน่ใจว่าเวอร์ชัน Node.js ของคุณมีอย่างน้อย 12.20.0
, 14.13.1
หรือ 16.0.0
อ่านเพิ่มเติมเกี่ยวกับโมดูล ESM จากไซต์เอกสาร Node.js อย่างเป็นทางการที่นี่ v10.0.0
เป็นต้นไป การแก้ไขใหม่ใดๆ ในไฟล์ที่จัดฉากไว้ในตอนแรกจะถูกเพิ่มลงในการคอมมิตโดยอัตโนมัติ หากงานของคุณก่อนหน้านี้มีขั้นตอน git add
โปรดลบขั้นตอนนี้ออก ลักษณะการทำงานอัตโนมัติช่วยให้แน่ใจว่ามีสภาวะการแข่งขันน้อยลง เนื่องจากการพยายามเรียกใช้การดำเนินการ git หลายรายการพร้อมกันมักส่งผลให้เกิดข้อผิดพลาดv10.0.0
เป็นต้นไป Lint-staged จะใช้ git stashes เพื่อปรับปรุงความเร็วและให้การสำรองข้อมูลขณะทำงาน เนื่องจาก git stashes ต้องการการคอมมิตครั้งแรกเป็นอย่างน้อย คุณจึงไม่ควรรัน lint-staged ใน repo ที่ว่างเปล่าv10.0.0
เป็นต้นไป Lint-staged ต้องใช้ Node.js เวอร์ชัน 10.13.0 หรือใหม่กว่าv10.0.0
เป็นต้นไป Lint-staged จะยกเลิกการคอมมิตหากงาน linter เลิกทำการเปลี่ยนแปลงตามขั้นตอนทั้งหมด หากต้องการอนุญาตให้สร้างคอมมิตว่าง โปรดใช้ตัวเลือก --allow-empty
❯ npx lint-staged --help
Usage: lint-staged [options]
Options:
-V, --version output the version number
--allow-empty allow empty commits when tasks revert all staged changes (default: false)
-p, --concurrent <number|boolean> the number of tasks to run concurrently, or false for serial (default: true)
-c, --config [path] path to configuration file, or - to read from stdin
--cwd [path] run all tasks in specific directory, instead of the current
-d, --debug print additional debug information (default: false)
--diff [string] override the default "--staged" flag of "git diff" to get list of files. Implies
"--no-stash".
--diff-filter [string] override the default "--diff-filter=ACMR" flag of "git diff" to get list of files
--max-arg-length [number] maximum length of the command-line argument string (default: 0)
--no-stash disable the backup stash, and do not revert in case of errors. Implies
"--no-hide-partially-staged".
--no-hide-partially-staged disable hiding unstaged changes from partially staged files
-q, --quiet disable lint-staged’s own console output (default: false)
-r, --relative pass relative filepaths to tasks (default: false)
-x, --shell [path] skip parsing of tasks for better shell support (default: false)
-v, --verbose show task output even when tasks succeed; by default only failed output is shown
(default: false)
-h, --help display help for command
--allow-empty
: ตามค่าเริ่มต้น เมื่องาน linter เลิกทำการเปลี่ยนแปลงตามขั้นตอนทั้งหมด lint-staged จะออกโดยมีข้อผิดพลาดและยกเลิกการคอมมิต ใช้แฟล็กนี้เพื่ออนุญาตให้สร้างคอมมิตว่างๆ--concurrent [number|boolean]
: ควบคุมการทำงานพร้อมกันของงานที่รันโดย lint-staged หมายเหตุ : สิ่งนี้ไม่ส่งผลกระทบต่อการทำงานพร้อมกันของงานย่อย (งานย่อยจะถูกรันตามลำดับเสมอ) ค่าที่เป็นไปได้คือ:false
: รันงานทั้งหมดตามลำดับtrue
(ค่าเริ่มต้น) : เห็นพ้องกัน ไม่มีที่สิ้นสุด รันงานคู่ขนานให้ได้มากที่สุด{number}
: รันงานตามจำนวนที่ระบุพร้อมกัน โดยที่ 1
เทียบเท่ากับ false
--config [path]
: ระบุเส้นทางไปยังไฟล์ปรับแต่งหรือชื่อแพ็คเกจ npm ด้วยตนเอง หมายเหตุ: เมื่อใช้ Lint-staged จะไม่ทำการค้นหาไฟล์กำหนดค่า และจะพิมพ์ข้อผิดพลาดหากไม่พบไฟล์ที่ระบุ หากระบุ '-' เป็นชื่อไฟล์ การกำหนดค่าจะถูกอ่านจาก stdin ทำให้สามารถไพพ์ในการกำหนดค่าเช่น cat my-config.json | npx lint-staged --config -
.--cwd [path]
: โดยค่าเริ่มต้นงานจะทำงานในไดเร็กทอรีการทำงานปัจจุบัน ใช้ --cwd some/directory
เพื่อแทนที่สิ่งนี้ เส้นทางอาจเป็นแบบสัมบูรณ์หรือสัมพันธ์กับไดเร็กทอรีการทำงานปัจจุบัน--debug
: ทำงานในโหมดแก้ไขข้อบกพร่อง เมื่อตั้งค่าแล้ว จะดำเนินการดังต่อไปนี้:$DEBUG
เป็น lint-staged*
verbose
สำหรับ listr2
; สิ่งนี้ทำให้เกิดเอาต์พุตแบบอนุกรมที่ไม่มีสีไปยังเทอร์มินัล แทนที่จะเป็นเอาต์พุตเริ่มต้น (สวยงาม ไดนามิก) (สามารถเปิดใช้งานตัวเรนเดอร์ verbose
ได้โดยการตั้งค่าตัวแปรสภาพแวดล้อม TERM=dumb
หรือ NODE_ENV=test
)--diff
: โดยค่าเริ่มต้น linters จะถูกกรองกับไฟล์ทั้งหมดที่จัดฉากใน git ซึ่งสร้างจาก git diff --staged
ตัวเลือกนี้ช่วยให้คุณสามารถแทนที่การตั้งค่าสถานะ --staged
ด้วยการแก้ไขตามต้องการ ตัวอย่างเช่น หากต้องการรับรายการไฟล์ที่เปลี่ยนแปลงระหว่างสองสาขา ให้ใช้ --diff="branch1...branch2"
คุณยังสามารถอ่านเพิ่มเติมจากเกี่ยวกับ git diff และ gitrevisions ตัวเลือกนี้ยังหมายความถึง --no-stash
ด้วย--diff-filter
: ตามค่าเริ่มต้นจะรวมเฉพาะไฟล์ที่ เพิ่ม คัดลอก แก้ไข หรือ เปลี่ยนชื่อ เท่านั้น ใช้แฟล็กนี้เพื่อแทนที่ค่า ACMR
เริ่มต้นด้วยค่าอื่น: เพิ่ม ( A
), คัดลอก ( C
), ลบ ( D
), แก้ไข ( M
), เปลี่ยนชื่อ ( R
), ประเภทเปลี่ยนแปลง ( T
), ไม่ถูก ผสาน ( U
), ไม่ทราบ ( X
) หรือ การจับคู่ที่ขาด ( B
) ดูเพิ่มเติมที่เอกสาร git diff
สำหรับ --diff-filter--max-arg-length
: คำสั่งแบบยาว (ไฟล์จำนวนมาก) จะถูกแบ่งออกเป็นหลาย ๆ ส่วนโดยอัตโนมัติเมื่อตรวจพบว่าเชลล์ปัจจุบันไม่สามารถจัดการได้ ใช้แฟล็กนี้เพื่อแทนที่ความยาวสูงสุดของสตริงคำสั่งที่สร้างขึ้น--no-stash
: ตามค่าเริ่มต้น ที่เก็บข้อมูลสำรองจะถูกสร้างขึ้นก่อนที่จะรันงาน และการแก้ไขงานทั้งหมดจะถูกคืนกลับในกรณีที่เกิดข้อผิดพลาด ตัวเลือกนี้จะปิดการใช้งานการสร้างที่ซ่อน และปล่อยให้การแก้ไขทั้งหมดอยู่ในดัชนีแทนเมื่อยกเลิกการคอมมิต สามารถเปิดใช้งานอีกครั้งได้ด้วย --stash
ตัวเลือกนี้ยังหมายความถึง --no-hide-partially-staged
ด้วย--no-hide-partially-staged
: ตามค่าเริ่มต้น การเปลี่ยนแปลงที่ยังไม่ได้จัดฉากจากไฟล์ที่จัดฉากบางส่วนจะถูกซ่อน ตัวเลือกนี้จะปิดใช้ลักษณะการทำงานนี้และรวมการเปลี่ยนแปลงที่ยังไม่ได้จัดฉากทั้งหมดในไฟล์ที่จัดฉากบางส่วน สามารถเปิดใช้งานอีกครั้งได้ด้วย --hide-partially-staged
--quiet
: ระงับเอาต์พุต CLI ทั้งหมด ยกเว้นจากงาน--relative
: ส่งผ่านพาธไฟล์ที่สัมพันธ์กับ process.cwd()
(โดยที่ lint-staged
ทำงาน) ไปยังงาน ค่าเริ่มต้นเป็น false
--shell
: โดยค่าเริ่มต้น คำสั่ง linter จะถูกแยกวิเคราะห์เพื่อความรวดเร็วและความปลอดภัย นี่เป็นผลข้างเคียงที่เชลล์สคริปต์ปกติอาจไม่ทำงานตามที่คาดไว้ คุณสามารถข้ามการแยกวิเคราะห์คำสั่งด้วยตัวเลือกนี้ หากต้องการใช้เชลล์เฉพาะ ให้ใช้เส้นทางเช่น --shell "/bin/bash"
--verbose
: แสดงผลงานแม้ว่างานจะสำเร็จก็ตาม ตามค่าเริ่มต้นจะแสดงเฉพาะเอาต์พุตที่ล้มเหลวเท่านั้น Lint-staged สามารถกำหนดค่าได้หลายวิธี:
lint-staged
ใน package.json
หรือ package.yaml
ของคุณ.lintstagedrc
ไฟล์ในรูปแบบ JSON หรือ YML หรือคุณสามารถกำหนดนามสกุลไฟล์ให้ชัดเจนได้:.lintstagedrc.json
.lintstagedrc.yaml
.lintstagedrc.yml
.lintstagedrc.mjs
หรือ lint-staged.config.mjs
ในรูปแบบ ESMexport default { ... }
.lintstagedrc.cjs
หรือ lint-staged.config.cjs
ในรูปแบบ CommonJSmodule.exports = { ... }
lint-staged.config.js
หรือ .lintstagedrc.js
ในรูปแบบ ESM หรือ CommonJS ขึ้นอยู่กับว่า package.json ของโปรเจ็กต์ของคุณมีตัวเลือก "type": "module"
หรือไม่--config
หรือ -c
การกำหนดค่าควรเป็นออบเจ็กต์โดยที่แต่ละค่าเป็นคำสั่งให้รัน และคีย์ของมันคือรูปแบบ glob ที่จะใช้สำหรับคำสั่งนี้ แพ็คเกจนี้ใช้ micromatch สำหรับรูปแบบ glob ไฟล์ JavaScript ยังสามารถส่งออกการกำหนดค่าขั้นสูงเป็นฟังก์ชันได้ ดูการใช้ไฟล์การกำหนดค่า JS สำหรับข้อมูลเพิ่มเติม
คุณยังสามารถวางไฟล์การกำหนดค่าหลายไฟล์ไว้ในไดเร็กทอรีที่แตกต่างกันภายในโปรเจ็กต์ได้ สำหรับไฟล์ที่จัดฉากที่กำหนด ไฟล์การกำหนดค่าที่ใกล้เคียงที่สุดจะถูกใช้เสมอ ดู "วิธีใช้ lint-staged
ใน monorepo หลายแพ็คเกจ" สำหรับข้อมูลเพิ่มเติมและตัวอย่าง
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
ตามค่าเริ่มต้น Lint-staged จะรันงานที่กำหนดค่าไว้พร้อมกัน ซึ่งหมายความว่าสำหรับทุก ๆ glob คำสั่งทั้งหมดจะเริ่มทำงานพร้อมกัน ด้วยการกำหนดค่าต่อไปนี้ ทั้ง eslint
และ prettier
จะทำงานพร้อมกัน:
{
"*.ts" : " eslint " ,
"*.md" : " prettier --list-different "
}
โดยทั่วไปจะไม่มีปัญหาเนื่องจาก globs จะไม่ทับซ้อนกัน และคำสั่งจะไม่ทำการเปลี่ยนแปลงไฟล์ แต่จะรายงานเฉพาะข้อผิดพลาดที่เป็นไปได้เท่านั้น (ยกเลิกการคอมไพล์คอมไพล์) หากคุณต้องการรันหลายคำสั่งสำหรับไฟล์ชุดเดียวกัน คุณสามารถใช้ไวยากรณ์อาร์เรย์เพื่อให้แน่ใจว่าคำสั่งต่างๆ ทำงานตามลำดับ ในตัวอย่างต่อไปนี้ prettier
จะทำงานสำหรับทั้งสอง globs และนอกจากนี้ eslint
จะทำงานสำหรับไฟล์ *.ts
หลังจาก นั้น คำสั่งทั้งสองชุด (สำหรับแต่ละ glob) ยังคงเริ่มต้นพร้อมกัน (แต่อย่าทับซ้อนกัน)
{
"*.ts" : [ " prettier --list-different " , " eslint " ],
"*.md" : " prettier --list-different "
}
ให้ความสนใจเป็นพิเศษเมื่อ Globs ที่กำหนดค่าซ้อนทับกัน และงานต่างๆ ทำการแก้ไขไฟล์ ตัวอย่างเช่น ในการกำหนดค่านี้ prettier
และ eslint
อาจพยายามทำการเปลี่ยนแปลงกับไฟล์ *.ts
เดียวกันในเวลาเดียวกัน ทำให้เกิด สภาวะการแข่งขัน :
{
"*" : " prettier --write " ,
"*.ts" : " eslint --fix "
}
คุณสามารถแก้ไขได้โดยใช้รูปแบบการปฏิเสธและไวยากรณ์อาเรย์:
{
"!(*.ts)" : " prettier --write " ,
"*.ts" : [ " eslint --fix " , " prettier --write " ]
}
อีกตัวอย่างหนึ่งที่งานทำการแก้ไขไฟล์และ globs จับคู่หลายไฟล์แต่ไม่ทับซ้อนกัน:
{
"*.css" : [ " stylelint --fix " , " prettier --write " ],
"*.{js,jsx}" : [ " eslint --fix " , " prettier --write " ],
"!(*.css|*.js|*.jsx)" : [ " prettier --write " ]
}
หรือหากจำเป็น คุณสามารถจำกัดการทำงานพร้อมกันโดยใช้ --concurrent <number>
หรือปิดใช้งานทั้งหมดด้วย --concurrent false
คำสั่ง Linter ทำงานกับชุดย่อยของไฟล์ที่จัดฉากทั้งหมด ซึ่งกำหนดโดย รูปแบบ glob lint-staged ใช้ micromatch สำหรับการจับคู่ไฟล์ตามกฎต่อไปนี้:
/
) ตัวเลือก matchBase
ของ micromatch จะถูกเปิดใช้งาน ดังนั้น globs จะตรงกับชื่อพื้นฐานของไฟล์โดยไม่คำนึงถึงไดเรกทอรี:"*.js"
จะจับคู่ไฟล์ JS ทั้งหมด เช่น /test.js
และ /foo/bar/test.js
"!(*test).js"
จะจับคู่ไฟล์ JS ทั้งหมด ยกเว้นไฟล์ที่ลงท้ายด้วย test.js
ดังนั้น foo.js
แต่ไม่ใช่ foo.test.js
"!(*.css|*.js)"
จะจับคู่ไฟล์ทั้งหมดยกเว้นไฟล์ CSS และ JS/
) รูปแบบนั้นจะจับคู่กับเส้นทางด้วย:"./*.js"
จะจับคู่ไฟล์ JS ทั้งหมดในรูท repo git ดังนั้น /test.js
แต่ไม่ใช่ /foo/bar/test.js
"foo/**/*.js"
จะจับคู่ไฟล์ JS ทั้งหมดภายในไดเร็กทอรี /foo
ดังนั้น /foo/bar/test.js
แต่ไม่ใช่ /test.js
เมื่อจับคู่ Lint-staged จะดำเนินการดังต่อไปนี้
หมายเหตุ: lint-staged
จะส่งผ่านเส้นทาง ที่แน่นอน ไปยัง linters เพื่อหลีกเลี่ยงความสับสนในกรณีที่ดำเนินการในไดเร็กทอรีการทำงานอื่น (เช่น เมื่อไดเร็กทอรี .git
ของคุณไม่เหมือนกับไดเร็กทอรี package.json
ของคุณ)
ดูเพิ่มเติมที่วิธีใช้ lint-staged
ใน monorepo แบบหลายแพ็คเกจ
แนวคิดของ lint-staged
คือการรันงาน linter ที่กำหนดค่าไว้ (หรืองานอื่นๆ) บนไฟล์ที่จัดฉากใน git lint-staged
จะส่งรายการไฟล์ที่จัดฉากทั้งหมดไปยังงานเสมอ และการละเว้นไฟล์ใด ๆ ควรได้รับการกำหนดค่าในงานนั้นเอง
พิจารณาโปรเจ็กต์ที่ใช้ prettier
เพื่อรักษารูปแบบโค้ดให้สอดคล้องกันในทุกไฟล์ โปรเจ็กต์ยังจัดเก็บไลบรารีของผู้จำหน่ายบุคคลที่สามที่ย่อขนาดไว้ในไดเร็กทอรี vendor/
เพื่อป้องกันไม่ให้ไฟล์เหล่านี้ prettier
ควรเพิ่มไดเร็กทอรีผู้ขายในการกำหนดค่าการละเว้นของ prettier ไฟล์ . .prettierignore
วิ่ง npx prettier .
จะเพิกเฉยต่อไดเร็กทอรีผู้ขายทั้งหมดโดยไม่มีข้อผิดพลาด เมื่อมีการเพิ่ม lint-staged
ให้กับโปรเจ็กต์และกำหนดค่าให้รันได้สวยขึ้น ไฟล์ที่แก้ไขและจัดฉากทั้งหมดในไดเร็กทอรีผู้จำหน่ายจะถูกละเว้นโดย prettier แม้ว่าจะได้รับเป็นอินพุตก็ตาม
ในสถานการณ์ขั้นสูง ซึ่งเป็นไปไม่ได้ที่จะกำหนดค่างาน linter เองให้ละเว้นไฟล์ แต่ไฟล์ที่จัดฉากบางไฟล์ควรยังคงถูกละเว้นโดย lint-staged
เป็นไปได้ที่จะกรองพาธของไฟล์ก่อนที่จะส่งต่อไปยังงานโดยใช้ไวยากรณ์ของฟังก์ชัน ดูตัวอย่าง: ละเว้นไฟล์จากการจับคู่
สิ่งที่รองรับคือไฟล์ปฏิบัติการใดๆ ที่ติดตั้งภายในเครื่องหรือทั่วโลกผ่าน npm
รวมถึงไฟล์สั่งการใดๆ จาก $PATH ของคุณ
ไม่แนะนำให้ใช้สคริปต์ที่ติดตั้งทั่วโลก เนื่องจาก lint-staged อาจไม่เหมาะกับผู้ที่ไม่ได้ติดตั้งสคริปต์ไว้
lint-staged
ใช้ execa เพื่อค้นหาสคริปต์ที่ติดตั้งในเครื่อง ดังนั้นใน .lintstagedrc
ของคุณ คุณสามารถเขียน:
{
"*.js" : " eslint --fix "
}
ซึ่งจะส่งผลให้เกิดการรัน lint-staged eslint --fix file-1.js file-2.js
เมื่อคุณมีไฟล์ฉาก file-1.js
, file-2.js
และ README.md
ส่งผ่านอาร์กิวเมนต์ไปยังคำสั่งของคุณโดยคั่นด้วยช่องว่างเช่นเดียวกับที่คุณทำในเชลล์ ดูตัวอย่างด้านล่าง
คุณสามารถรันหลายคำสั่งตามลำดับในทุก ๆ glob หากต้องการทำเช่นนั้น ให้ส่งอาร์เรย์ของคำสั่งแทนคำสั่งเดียว สิ่งนี้มีประโยชน์สำหรับการเรียกใช้เครื่องมือการจัดรูปแบบอัตโนมัติเช่น eslint --fix
หรือ stylefmt
แต่สามารถใช้กับลำดับที่กำหนดเองได้
ตัวอย่างเช่น:
{
"*.js" : [ " eslint " , " prettier --write " ]
}
กำลังจะรัน eslint
และถ้ามันออกด้วยโค้ด 0
มันจะรัน prettier --write
ในไฟล์ *.js
ที่จัดฉากทั้งหมด
ซึ่งจะส่งผลให้เกิดการรัน eslint file-1.js file-2.js
แบบ lint-staged เมื่อคุณมีไฟล์แบบฉาก file-1.js
, file-2.js
และ README.md
และหากผ่าน จะ prettier --write file-1.js file-2.js
การเขียนไฟล์การกำหนดค่าใน JavaScript เป็นวิธีที่มีประสิทธิภาพที่สุดในการกำหนดค่า lint-staged ( lint-staged.config.js
คล้ายกัน หรือส่งผ่าน --config
) จากไฟล์การกำหนดค่า คุณสามารถส่งออกฟังก์ชันเดียวหรือออบเจ็กต์ได้
หากค่า exports
เป็นฟังก์ชัน ก็จะได้รับอาร์เรย์ของชื่อไฟล์ที่จัดฉากทั้งหมด จากนั้นคุณสามารถสร้างตัวจับคู่ของคุณเองสำหรับไฟล์และส่งกลับสตริงคำสั่งหรืออาร์เรย์ของสตริงคำสั่งได้ สตริงเหล่านี้ถือว่าสมบูรณ์และควรมีอาร์กิวเมนต์ชื่อไฟล์ด้วย หากต้องการ
หากค่า exports
เป็นออบเจ็กต์ คีย์ควรเป็นค่าที่ตรงกัน (เช่นในรูปแบบการกำหนดค่าที่ไม่ใช่ js ปกติ) ค่าอาจเป็นเช่นในการกำหนดค่าปกติหรือแต่ละฟังก์ชันตามที่อธิบายไว้ข้างต้น แทนที่จะรับไฟล์ที่ตรงกันทั้งหมด ฟังก์ชันในออบเจ็กต์ที่ส่งออกจะได้รับเฉพาะไฟล์ฉากที่ตรงกับคีย์ glob ที่เกี่ยวข้องเท่านั้น
โดยสรุป ตามค่าเริ่มต้น lint-staged จะเพิ่มรายการไฟล์ที่จัดฉากที่ตรงกันลงในคำสั่งของคุณโดยอัตโนมัติ แต่เมื่อสร้างคำสั่งโดยใช้ฟังก์ชัน JS ก็คาดว่าจะดำเนินการนี้ด้วยตนเอง ตัวอย่างเช่น:
export default {
'*.js' : ( stagedFiles ) => [ `eslint .` , `prettier --write ${ stagedFiles . join ( ' ' ) } ` ] ,
}
ซึ่งจะส่งผลให้ eslint .
ทำงานครั้งแรกด้วย lint-staged (จับคู่ไฟล์ ทั้งหมด ) และถ้ามันผ่าน prettier --write file-1.js file-2.js
เมื่อคุณมีไฟล์ฉาก file-1.js
, file-2.js
และ README.md
ฟังก์ชั่นนี้สามารถเป็นแบบอะซิงโครนัสได้:
( filenames : string [ ] ) => string | string [ ] | Promise < string | string [ ] >
// lint-staged.config.js
import micromatch from 'micromatch'
export default ( allStagedFiles ) => {
const shFiles = micromatch ( allStagedFiles , [ '**/src/**/*.sh' ] )
if ( shFiles . length ) {
return `printf '%sn' "Script files aren't allowed in src directory" >&2`
}
const codeFiles = micromatch ( allStagedFiles , [ '**/*.js' , '**/*.ts' ] )
const docFiles = micromatch ( allStagedFiles , [ '**/*.md' ] )
return [ `eslint ${ codeFiles . join ( ' ' ) } ` , `mdl ${ docFiles . join ( ' ' ) } ` ]
}
// .lintstagedrc.js
export default {
'**/*.js?(x)' : ( filenames ) => filenames . map ( ( filename ) => `prettier --write ' ${ filename } '` ) ,
}
tsc
เมื่อมีการเปลี่ยนแปลงไฟล์ TypeScript แต่อย่าส่งผ่านอาร์กิวเมนต์ชื่อไฟล์ใดๆ // lint-staged.config.js
export default {
'**/*.ts?(x)' : ( ) => 'tsc -p tsconfig.json --noEmit' ,
}
// .lintstagedrc.js
export default {
'**/*.js?(x)' : ( filenames ) =>
filenames . length > 10 ? 'eslint .' : `eslint ${ filenames . join ( ' ' ) } ` ,
}
ควรใช้การกำหนดค่าตามฟังก์ชัน (ดูด้านบน) หากกรณีการใช้งานของคุณเป็นเช่นนี้
// lint-staged.config.js
import micromatch from 'micromatch'
export default {
'*' : ( allFiles ) => {
const codeFiles = micromatch ( allFiles , [ '**/*.js' , '**/*.ts' ] )
const docFiles = micromatch ( allFiles , [ '**/*.md' ] )
return [ `eslint ${ codeFiles . join ( ' ' ) } ` , `mdl ${ docFiles . join ( ' ' ) } ` ]
} ,
}
หากคุณต้องการละเว้นไฟล์จากการจับคู่ glob ด้วยเหตุผลบางประการ คุณสามารถใช้ micromatch.not()
:
// lint-staged.config.js
import micromatch from 'micromatch'
export default {
'*.js' : ( files ) => {
// from `files` filter those _NOT_ matching `*test.js`
const match = micromatch . not ( files , '*test.js' )
return `eslint ${ match . join ( ' ' ) } `
} ,
}
โปรดทราบว่าในกรณีส่วนใหญ่ globs ก็สามารถบรรลุผลเช่นเดียวกันได้ สำหรับตัวอย่างข้างต้น glob ที่ตรงกันจะเป็น !(*test).js
import path from 'path'
export default {
'*.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-staged เพื่อป้องกันสภาวะการแข่งขันโดยต้องแก้ไขไฟล์เดียวกันหลายงาน หาก Lint-staged ตรวจพบ git add
ในการกำหนดค่างาน มันจะแสดงคำเตือนในคอนโซล โปรดลบ git add
ออกจากการกำหนดค่าของคุณหลังจากอัปเกรด
ตัวอย่างทั้งหมดถือว่าคุณได้ตั้งค่า lint-staged ในไฟล์ package.json
และ husky ในไฟล์กำหนดค่าของตัวเองแล้ว
{
"name" : " My project " ,
"version" : " 0.1.0 " ,
"scripts" : {
"my-custom-script" : " linter --arg1 --arg2 "
},
"lint-staged" : {}
}
ใน .husky/pre-commit
# .husky/pre-commit
npx lint-staged
หมายเหตุ: เราไม่ผ่านเส้นทางเพื่อเป็นข้อโต้แย้งสำหรับนักวิ่ง นี่เป็นสิ่งสำคัญเนื่องจากผ้าสำลีจะทำสิ่งนี้เพื่อคุณ
*.js
และ *.jsx
ที่ทำงานเป็น hook ที่คอมมิตล่วงหน้า{
"*.{js,jsx}" : " eslint "
}
--fix
และเพิ่มเพื่อคอมมิต{
"*.js" : " eslint --fix "
}
สิ่งนี้จะรัน eslint --fix
และเพิ่มการเปลี่ยนแปลงในการคอมมิตโดยอัตโนมัติ
หากคุณต้องการใช้สคริปต์ npm ที่กำหนดไว้ใน package.json ของคุณซ้ำ:
{
"*.js" : " npm run my-custom-script -- "
}
สิ่งต่อไปนี้เทียบเท่า:
{
"*.js" : " linter --arg1 --arg2 "
}
คำสั่ง Linting ไม่ สนับสนุนรูปแบบเชลล์ของการขยายตัวแปรสภาพแวดล้อม หากต้องการเปิดใช้งานแบบแผนด้วยตนเอง ให้ใช้เครื่องมือเช่น cross-env
ตัวอย่างเช่น นี่คือการล้อ jest
ที่ทำงานบนไฟล์ .js
ทั้งหมดที่มีการตั้งค่าตัวแปร NODE_ENV
เป็น "test"
:
{
"*.js" : [ " cross-env NODE_ENV=test jest --bail --findRelatedTests " ]
}
prettier
สำหรับทุกรูปแบบที่ Prettier รองรับ{
"*" : " prettier --ignore-unknown --write "
}
prettier
สำหรับ JavaScript, TypeScript, Markdown, HTML หรือ CSS{
"*.{js,jsx,ts,tsx,md,html,css}" : " prettier --write "
}
{
"*.css" : " stylelint " ,
"*.scss" : " stylelint --syntax=scss "
}
{
"*.scss" : [ " postcss --config path/to/your/config --replace " , " stylelint " ]
}
{
"*.{png,jpeg,jpg,gif,svg}" : " imagemin-lint-staged "
}
imagemin-lint-staged
imagemin-lint-staged เป็นเครื่องมือ CLI ที่ออกแบบมาสำหรับการใช้งานที่เป็นขุยโดยมีค่าเริ่มต้นที่สมเหตุสมผล
ดูเพิ่มเติมในบล็อกโพสต์นี้เพื่อดูประโยชน์ของแนวทางนี้
{
"*.{js,jsx}" : " flow focus-check "
}
// .lintstagedrc.js
// See https://nextjs.org/docs/basic-features/eslint#lint-staged for details
const path = require ( 'path' )
const buildEslintCommand = ( filenames ) =>
`next lint --fix --file ${ filenames . map ( ( f ) => path . relative ( process . cwd ( ) , f ) ) . join ( ' --file ' ) } `
module . exports = {
'*.{js,jsx,ts,tsx}' : [ buildEslintCommand ] ,
}
Git 2.36.0 นำเสนอการเปลี่ยนแปลงใน hooks โดยที่ไม่ได้ทำงานใน TTY ดั้งเดิมอีกต่อไป สิ่งนี้ได้รับการแก้ไขใน 2.37.0:
https://raw.githubusercontent.com/git/git/master/Documentation/RelNotes/2.37.0.txt
- ใน Git 2.36 เราได้ปรับปรุงวิธีการเรียกใช้ hooks การเปลี่ยนแปลงประการหนึ่งที่ผู้ใช้ปลายทางมองเห็นได้ก็คือเอาต์พุตของ hook จะไม่เชื่อมต่อโดยตรงกับเอาต์พุตมาตรฐานของ "git" ที่สร้าง hook อีกต่อไป ซึ่งสังเกตเห็นได้หลังการเปิดตัว เรื่องนี้กำลังได้รับการแก้ไข (รวม a082345372 ab/hooks-regression-fix ภายหลังเพื่อบำรุงรักษา)
หากการอัปเดต Git ไม่ได้ผล คุณสามารถลองเปลี่ยนเส้นทางเอาต์พุตใน Git hook ของคุณด้วยตนเอง ตัวอย่างเช่น:
# .husky/pre-commit
if sh -c " : >/dev/tty " > /dev/null 2> /dev/null ; then exec > /dev/tty 2>&1 ; fi
npx lint-staged
ที่มา: typicode/husky#968 (ความคิดเห็น)
lint-staged
ผ่านโหนดได้หรือไม่ใช่!
import lintStaged from 'lint-staged'
try {
const success = await lintStaged ( )
console . log ( success ? 'Linting was successful!' : 'Linting failed!' )
} catch ( e ) {
// Failed to load configuration
console . error ( e )
}
พารามิเตอร์ของ lintStaged
เทียบเท่ากับพารามิเตอร์ CLI:
const success = await lintStaged ( {
allowEmpty : false ,
c