Node项目经常需要使用eslint规范代码。我们希望eslint的检查是自动化的,在git commit时进行,针对所有要commit的文件进行。
步骤
-
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
,查看执行结果是否合理 -
git commit -m "xxx"
,查看eslint是否运行
缺陷
eslint执行时,直接针对当前文件内容。如果在git add
后,又修改了文件的内容,则会针对修改后内容进行检查。
假如修改前内容有误,而修改后无误。不执行git add
而再次执行git commit
时,会根据修改后的文件进行检查,而不能发现已缓存文件仍然错误。
优化方法是,检查所有改动,要求所有在缓存区的文件改动必须重新缓存。
更新
gulp任务同时并行执行,不能保证前面的代码能够先执行。前面的代码应作为前置任务存在。
整体改为:
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'));
});