Node項(xiàng)目經(jīng)常需要使用eslint規(guī)范代碼。我們希望eslint的檢查是自動(dòng)化的,在git commit時(shí)進(jìn)行,針對所有要commit的文件進(jìn)行。
步驟
-
npm install husky --save-dev。安裝husky。 - 安裝好eslint和gulp,及gulp-eslint插件。
- 配置gulpfile.js如下:
const gulp = require('gulp');
const eslint = require('gulp-eslint');
const exec = require('child_process').execSync;
function OctalDecode(str) {
const matches = str.match(/(\\\d{3}){3}/g);
if (matches) matches.forEach(match => {
let encoded = '';
const splits = match.split('\\');
splits.forEach(code => !code || (encoded += '%' + parseInt(code, 8).toString(16)));
const cChar = decodeURI(encoded);
str = str.replace(match, cChar);
});
return str;
}
const stdout = exec('git diff --cached --name-only', {encoding: 'utf-8'});
const cachedJsList = stdout.split('\n')
.map(v => OctalDecode(v.replace(/^"|"$/g, '')))
.filter(v => v.endsWith('.js') && v!=='gulpfile.js');
console.log('需要eslint的文件:', cachedJsList);
gulp.task('eslint', () => {
return gulp.src(cachedJsList)
.pipe(eslint())
.pipe(eslint.format())
.pipe(eslint.failAfterError('failes'));
});
- 在.eslintignore中添加“gulpfile.js”。
- 在package.json中添加
scripts.precommit: "gulp eslint"
測試
- 修改文件,
git add . -
npm run precommit,查看執(zhí)行結(jié)果是否合理 -
git commit -m "xxx",查看eslint是否運(yùn)行
缺陷
eslint執(zhí)行時(shí),直接針對當(dāng)前文件內(nèi)容。如果在git add后,又修改了文件的內(nèi)容,則會針對修改后內(nèi)容進(jìn)行檢查。
假如修改前內(nèi)容有誤,而修改后無誤。不執(zhí)行git add而再次執(zhí)行git commit時(shí),會根據(jù)修改后的文件進(jìn)行檢查,而不能發(fā)現(xiàn)已緩存文件仍然錯(cuò)誤。
優(yōu)化方法是,檢查所有改動(dòng),要求所有在緩存區(qū)的文件改動(dòng)必須重新緩存。
更新
gulp任務(wù)同時(shí)并行執(zhí)行,不能保證前面的代碼能夠先執(zhí)行。前面的代碼應(yīng)作為前置任務(wù)存在。
整體改為:
const gulp = require('gulp');
const eslint = require('gulp-eslint');
const exec = require('child_process').execSync;
function OctalDecode(str) {
const matches = str.match(/(\\\d{3}){3}/g);
if (matches) matches.forEach(match => {
let encoded = '';
const splits = match.split('\\');
splits.forEach(code => !code || (encoded += '%' + parseInt(code, 8).toString(16)));
const cChar = decodeURI(encoded);
str = str.replace(match, cChar);
});
return str;
}
let cachedJsList = [];
gulp.task('pre-eslint', (cb) => {
const stdout = exec('git diff --cached --name-only', {encoding: 'utf-8'});
cachedJsList = stdout.split('\n')
.map(v => OctalDecode(v.replace(/^"|"$/g, '')))
.filter(v => v.endsWith('.js') && v!=='gulpfile.js');
console.log('需要eslint的文件:', cachedJsList);
cb();
});
gulp.task('eslint', ['pre-eslint'], () => {
return gulp.src(cachedJsList)
.pipe(eslint())
.pipe(eslint.format())
.pipe(eslint.failAfterError('failes'));
});