├── .eslintrc.js ├── .gitignore ├── .stylelintrc.js ├── .travis.yml ├── LICENSE ├── README.md ├── bin └── code-lint ├── config ├── default.config.js ├── lint.config.js └── type.config.js ├── doc ├── CHANGELOG.md └── TODO.md ├── lint.config.json ├── lint.js ├── lintIgnore ├── eslint.default.ignore.js └── stylelint.default.ignore.js ├── package-lock.json ├── package.json ├── test └── util.test.js └── util ├── pubMethod.js └── util.js /.eslintrc.js: -------------------------------------------------------------------------------- 1 | 2 | // const extend = require('extend'); 3 | const finalLintConfigJson = require('./config/lint.config'); 4 | 5 | const eslintConfig = { 6 | root: true, 7 | parser: "babel-eslint", 8 | env: { 9 | browser: true, 10 | }, 11 | globals: finalLintConfigJson.eslint.globals, 12 | extends: [ 13 | // https://github.com/standard/standard/blob/master/docs/RULES-zhcn.md 14 | 'standard' 15 | ], 16 | plugins: [ 17 | 'html' 18 | ], 19 | rules: finalLintConfigJson.eslint.rules 20 | } 21 | 22 | module.exports = eslintConfig; 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Runtime data 7 | pids 8 | *.pid 9 | *.seed 10 | 11 | # Directory for instrumented libs generated by jscoverage/JSCover 12 | lib-cov 13 | 14 | # Coverage directory used by tools like istanbul 15 | coverage 16 | 17 | # nyc test coverage 18 | .nyc_output 19 | 20 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 21 | .grunt 22 | 23 | # node-waf configuration 24 | .lock-wscript 25 | 26 | # Compiled binary addons (http://nodejs.org/api/addons.html) 27 | build/Release 28 | 29 | # Dependency directories 30 | node_modules 31 | jspm_packages 32 | 33 | # Optional npm cache directory 34 | .npm 35 | 36 | # Optional REPL history 37 | .node_repl_history 38 | -------------------------------------------------------------------------------- /.stylelintrc.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const extend = require('extend'); 4 | const finalLintConfigJson = require('./config/lint.config'); 5 | 6 | const stylelintConfig = { 7 | "extends": "stylelint-config-standard", 8 | "plugins": [ 9 | "stylelint-scss" 10 | ], 11 | "rules": extend({ 12 | "at-rule-no-unknown": null, 13 | "scss/at-rule-no-unknown": true 14 | },finalLintConfigJson.stylelint.rules) 15 | } 16 | 17 | module.exports = stylelintConfig; 18 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "8" 4 | install: npm install 5 | script: 6 | - npm run test -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 淘淘笙悦 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [code-lint](https://github.com/ttsy/code-lint) 2 | 3 | 一个基于 eslint、stylelint 的代码规范检测工具 4 | 5 | ## :star: 特性 6 | 7 | - 基于 eslint 进行 js 代码规范检测 8 | - 基于 stylelint 进行 css 代码规范检测 9 | - 基于 stylelint-scss 对 scss 代码更加友好的规范检测 10 | - 定向检测文件 11 | - localdiff 检测文件(基于 git) 12 | 13 | js 代码检测仅包含后缀为 .html、.vue、.js 的文件,而 css 代码检测仅包含后缀为 .html、.vue、.css、.scss、less。 14 | 15 | ## :rocket: 使用指南 16 | 17 | 通过 npm 下载安装 18 | 19 | ``` bash 20 | npm install code-lint --save-dev 21 | ``` 22 | 23 | ### 定向检测 24 | 25 | 检测配置文件中配置的文件 26 | 27 | - 在根目录 package.json 文件中加入检测命令 28 | 29 | ``` 30 | "scripts": { 31 | "lint": "code-lint" 32 | } 33 | ``` 34 | 35 | - 在根目录中加入配置文件,文件名为 lint.config.json,文件格式示例内容如下 36 | 37 | ```js 38 | { 39 | "lintTargetFiles": [ 40 | "**/*.html", 41 | "**/*.vue", 42 | "**/*.js", 43 | "**/*.css", 44 | "**/*.scss", 45 | "**/*.less" 46 | ] 47 | } 48 | ``` 49 | 50 | lintTargetFiles 为检测目标文件,使用 glob 语法。 51 | 52 | - 运行检测命令检测 53 | 54 | ``` bash 55 | npm run lint 56 | ``` 57 | 58 | ### localdiff 检测 59 | 60 | 只检测本地 diff 的文件(包含 untracked 文件)。diff 检测允许没有配置文件 lint.config.json。 61 | 62 | - 在根目录 package.json 文件中加入检测命令 63 | 64 | ``` 65 | "scripts": { 66 | "lint-localdiff": "code-lint --localdviff" 67 | } 68 | ``` 69 | 70 | - 运行检测命令检测 71 | 72 | ``` bash 73 | npm run lint-localdiff 74 | ``` 75 | 76 | ### 检测规则 77 | 78 | js 检测规则继承 [eslint-config-standard](https://github.com/standard/standard/blob/master/docs/RULES-zhcn.md) 中的规则,并可根据配置文件中 eslint.rules 参数添加检测规则。 79 | 80 | css 检测规则继承 [stylelint-config-standard](https://github.com/stylelint/stylelint-config-standard/blob/master/index.js) 中的规则,可根据配置文件中 stylelint.rules 参数添加检测规则。 81 | 82 | ### 其它说明 83 | 84 | lint.config.json 配置文件中,除了 lintTargetFiles 参数外,还可以通过配置其它参数决定仅检测 js 或者 css 以及添加自己的检测规则,详见下述默认配置文档(default.config.js)。 85 | 86 | ## :bookmark_tabs: 文档 87 | 88 | 默认配置:[default.config.js](./config/default.config.js) 89 | 90 | js 检测默认忽略文件:[eslintignore.js](./lintIgnore/eslintignore.js) 91 | 92 | css 检测默认忽略文件:[stylelintignore.js](./lintIgnore/stylelintignore.js) 93 | 94 | ## :gear: 更新日志 95 | [CHANGELOG.md](./doc/CHANGELOG.md) 96 | 97 | ## :airplane: 计划列表 98 | [TODO.md](./doc/TODO.md) -------------------------------------------------------------------------------- /bin/code-lint: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const path = require('path'); 4 | const argv = require('yargs').argv; 5 | const exec = require('child_process').exec; 6 | const packageJson = require('../package.json'); 7 | const pub = require('../util/pubMethod'); 8 | 9 | const param = { 10 | version:(argv.v || argv.version), // 查看版本号 11 | localdiff: argv.localdiff // localdiff 检测(包含 untracked 文件) 12 | } 13 | 14 | if (param.version) { 15 | console.log(packageJson.version); 16 | process.exit(); 17 | } 18 | 19 | if (param.localdiff) { 20 | pub.setLocalDiffFileList(); 21 | process.env.isDiffLint = true; 22 | } 23 | 24 | const cmd = 'gulp --gulpfile ' + path.join(__dirname, '..', 'lint.js'); 25 | 26 | exec(cmd, function (error, stdout, stderr) { 27 | console.log(stdout) 28 | if (error) { 29 | console.log(stderr); 30 | process.exit(1); 31 | } 32 | }); -------------------------------------------------------------------------------- /config/default.config.js: -------------------------------------------------------------------------------- 1 | // 默认配置 2 | module.exports = { 3 | "lintTargetFiles": [ // 检测目标文件(可选) 4 | // "**/*.html", 5 | // "**/*.vue", 6 | // "**/*.js", 7 | // "**/*.css", 8 | // "**/*.scss", 9 | // "**/*.less", 10 | // "!**/ignore/*.js" 11 | ], 12 | "ignoreFiles":[], // 检测忽略文件(可选) 13 | "lintType": { // 检测类型(可选) 14 | "js": true, 15 | "css": true 16 | }, 17 | "eslint": { // eslint 配置规则(可选) 18 | "globals": { // 同 eslint globals 字段 19 | '$': false, 20 | 'jQuery': false 21 | }, 22 | "rules": { // 同 eslint rules 字段 23 | // // 不强制使用一致的缩进 24 | // 'indent': 'off', 25 | // // 不强制使用一致的反勾号、双引号或单引号 26 | // 'quotes': 'off', 27 | // // 不要求在语句末尾是否需要添加分号 28 | // 'semi': 'off', 29 | // // 不要求一定要使用 === 和 !== 30 | // 'eqeqeq': 'off', 31 | // // 不要求函数圆括号之前是否需要一个空格 32 | // 'space-before-function-paren': 'off', 33 | // // 不要求语句块之前是否需要空格 34 | // 'space-before-blocks': 'off', 35 | // // 不强制在关键字前后使用一致的空格 36 | // 'keyword-spacing': 'off', 37 | // // 不强制在对象字面量的键和值之间使用一致的空格 38 | // 'key-spacing': 'off', 39 | // // 允许行尾空格 40 | // 'no-trailing-spaces': 'off', 41 | // // 允许 arguments.caller 或 arguments.callee 42 | // 'no-caller': 'off', 43 | // // 允许 new 创建对象实例后不赋值给变量 44 | // 'no-new': 'off', 45 | // // 允许不必要的转义 46 | // 'no-useless-escape': 'off' 47 | } 48 | }, 49 | "stylelint": { // stylelint 配置规则(可选) 50 | "rules": { // 同 stylelint rules 字段 51 | // // at-rule 名后面必须有一个空格 52 | // "at-rule-name-space-after": "always", 53 | // // 开始大括号前不限制是否需要空格 54 | // "block-opening-brace-space-before": null, 55 | // // 不限制颜色十六进制值长短模式 56 | // "color-hex-length": null, 57 | // // 不限制冒号后是否需要空格 58 | // "declaration-colon-space-after": null, 59 | // // 不限制 function 逗号后的新行格式 60 | // "function-comma-newline-after": null, 61 | // // 不限制缩进 62 | // "indentation": null, 63 | // // 规则块间不允许空行 64 | // "rule-empty-line-before": ["never"] 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /config/lint.config.js: -------------------------------------------------------------------------------- 1 | // 获得最终配置文件 2 | 'use strict'; 3 | 4 | /* eslint-disable no-console */ 5 | const path = require('path'); 6 | const extend = require('extend'); 7 | 8 | // 运行检测命令的目录 9 | const lintCMDPath = process.env.INIT_CWD; 10 | // 默认配置 11 | let defaultLintConfigJson = require('./default.config'); 12 | // 配置文件 lint.config.json 13 | let lintConfigJson = require(path.join(lintCMDPath, 'lint.config.json')); 14 | // 最终配置 15 | let lintConfig = extend(true, {}, defaultLintConfigJson, lintConfigJson); 16 | 17 | if (process.env.isDiffLint) { 18 | let lintLocalDiffJson = require(path.join(__dirname, '..', 'lint.local.diff.json')); 19 | lintConfig.lintTargetFiles = lintLocalDiffJson.lintTargetFiles; 20 | } 21 | 22 | module.exports = lintConfig; 23 | -------------------------------------------------------------------------------- /config/type.config.js: -------------------------------------------------------------------------------- 1 | // 类型检测对应可以检测的后缀文件 2 | module.exports = { 3 | js: ['html', 'vue', 'js'], 4 | css: ['html', 'vue', 'css', 'scss', 'less'], 5 | all: ['html', 'vue', 'js', 'css', 'scss', 'less'] 6 | } 7 | -------------------------------------------------------------------------------- /doc/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 更新日志 2 | 3 | ## 1.3.0 / 2018-12-26 4 | 5 | - 去除全局修复功能 6 | 7 | ## 1.2.0 / 2018-12-24 8 | 9 | - 升级 gulp 为 4.0 版本 10 | - 升级 gulp-elint 为 5.0 版本 11 | 12 | ## 1.1.0 / 2018-12-21 13 | 14 | - 新增配置字段 ignoreFiles 表示检测忽略的文件 15 | - 定向/localdiff 修复更改为全局修复 16 | 17 | ## 1.0.0 / 2018-12-15 18 | 19 | - 新增基于 eslint 的 js 代码规范检测 20 | - 新增基于 stylelint 的 css(含 css、scss、less) 代码规范检测 21 | - 新增基于 stylelint-scss 对 scss 代码更加友好的规范检测 22 | - 新增集成单元测试环境(mocha) 23 | - 新增 travis-ci 24 | 25 | -------------------------------------------------------------------------------- /doc/TODO.md: -------------------------------------------------------------------------------- 1 | # 计划列表 2 | 3 | 这里列出会在未来添加的新功能,和已经完成的功能。 4 | [X] 已完成、[ ] 未完成 5 | 6 | - [X] js 代码规范检测 7 | - [X] css 代码规范检测 8 | - [ ] html 代码规范检测 9 | -------------------------------------------------------------------------------- /lint.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "lintTargetFiles": [ 3 | "**/*.html", 4 | "**/*.vue", 5 | "**/*.js", 6 | "**/*.css", 7 | "**/*.scss", 8 | "**/*.less" 9 | ], 10 | "ignoreFiles":[ 11 | 12 | ], 13 | "lintType":{ 14 | "js":true, 15 | "css":true 16 | }, 17 | "eslint": { 18 | "globals": { 19 | "describe": false, 20 | "it": false 21 | }, 22 | "rules": { 23 | "indent": "off", 24 | "quotes": "off", 25 | "semi": "off", 26 | "eqeqeq": "off", 27 | "space-before-function-paren": "off", 28 | "space-before-blocks": "off", 29 | "keyword-spacing": "off", 30 | "key-spacing": "off", 31 | "no-trailing-spaces": "off", 32 | "no-caller": "off", 33 | "no-new": "off", 34 | "no-useless-escape": "off" 35 | } 36 | }, 37 | "stylelint": { 38 | "rules": { 39 | "at-rule-name-space-after": "always", 40 | "block-opening-brace-space-before": null, 41 | "color-hex-length": null, 42 | "declaration-colon-space-after": null, 43 | "function-comma-newline-after": null, 44 | "indentation": null, 45 | "rule-empty-line-before": [ 46 | "never" 47 | ] 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /lint.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* eslint-disable no-console */ 4 | const path = require('path'); 5 | const fs = require('fs'); 6 | const gulp = require('gulp'); 7 | const gulpEslint = require('gulp-eslint'); 8 | const gulpStylelint = require('gulp-stylelint'); 9 | 10 | // const util = require('./util/util'); 11 | const pub = require('./util/pubMethod'); 12 | const typeConfig = require('./config/type.config'); 13 | const lintConfig = require('./config/lint.config'); 14 | const eslintDefaultIgnoreFiles = require('./lintIgnore/eslint.default.ignore'); 15 | const stylelintDefaultIgnoreFiles = require('./lintIgnore/stylelint.default.ignore'); 16 | 17 | // 运行检测命令的目录 18 | const lintCMDPath = process.env.INIT_CWD; 19 | // 当前工作目录(--gulpfile lint.js 会将 cwd 设置为 lint.js 所在目录) 20 | // const cwd = process.cwd(); 21 | 22 | // eslint 占位文件,防止没任何待检测文件时程序报错 23 | const eslintBaseFile = [`${lintCMDPath}/lint-base.js`]; 24 | // stylelint 占位文件,防止没任何待检测文件时程序报错 25 | const stylelintBaseFile = [`${lintCMDPath}/lint-base.css`]; 26 | 27 | let lintFiles = {}; 28 | let lintIgnoreFiles = {}; 29 | typeConfig.all.map((val) => { 30 | lintFiles[val] = []; 31 | lintIgnoreFiles[val] = []; 32 | }) 33 | 34 | lintConfig.lintTargetFiles.map((val) => { 35 | if (val.includes('!')) { // 兼容 lintTargetFiles 配置 ! 忽略检测文件的情况 36 | lintConfig.ignoreFiles.push(val.slice(1)) 37 | }else{ 38 | let fileType = val.substr(val.lastIndexOf('.') + 1); 39 | let filePath; 40 | if (process.env.isDiffLint) { // 如果是 diff 检测,被检测文件已经配置为绝对路径,无需再拼接 41 | filePath = val; 42 | } else { 43 | filePath = path.join(lintCMDPath, val); 44 | filePath.includes('!') && (filePath = '!' + filePath.replace('!', '')); 45 | } 46 | lintFiles[fileType] && lintFiles[fileType].push(filePath); 47 | } 48 | }); 49 | 50 | lintConfig.ignoreFiles.map((val) => { 51 | let fileType = val.substr(val.lastIndexOf('.') + 1); 52 | let filePath; 53 | filePath = '!' + path.join(lintCMDPath, val); 54 | lintIgnoreFiles[fileType] && lintIgnoreFiles[fileType].push(filePath); 55 | }) 56 | 57 | let typeObj = { 58 | js: 'eslint', 59 | css: 'stylelint' 60 | } 61 | let lintType = lintConfig.lintType; 62 | let lintTask = []; 63 | for (let key in lintType){ 64 | lintType[key] && lintTask.push(typeObj[key]); 65 | } 66 | 67 | // 检测文件 68 | let myEsLintFiles = pub.getFilesArr(lintFiles, 'js') 69 | let myStyleLintFiles = pub.getFilesArr(lintFiles, 'css') 70 | // let myLintFiles = pub.getFilesArr(lintFiles, 'all') 71 | // 检测忽略文件 72 | let myEsLintIgnoreFiles = pub.getFilesArr(lintIgnoreFiles, 'js') 73 | let myStyleLintIgnoreFiles = pub.getFilesArr(lintIgnoreFiles, 'css') 74 | // let myLintIgnoreFiles = pub.getFilesArr(lintIgnoreFiles, 'all') 75 | 76 | // pub.printLintFiles(lintType, myLintFiles, myEsLintFiles, myStyleLintFiles); 77 | // pub.printLintIgnoreFiles(lintType, myLintIgnoreFiles, myEsLintIgnoreFiles, myStyleLintIgnoreFiles); 78 | 79 | // js 代码规范检测 80 | gulp.task('eslint', () => { 81 | let files = myEsLintFiles 82 | .concat(myEsLintIgnoreFiles) 83 | .concat(eslintDefaultIgnoreFiles) 84 | .concat(eslintBaseFile); 85 | return gulp.src(files, { allowEmpty: true }) 86 | .pipe(gulpEslint({ 87 | configFile: '.eslintrc.js' 88 | })) 89 | .pipe(gulpEslint.format()) 90 | .pipe(gulpEslint.failAfterError()); 91 | }); 92 | 93 | // css 代码规范检测 94 | gulp.task('stylelint', () => { 95 | let files = myStyleLintFiles 96 | .concat(myStyleLintIgnoreFiles) 97 | .concat(stylelintDefaultIgnoreFiles) 98 | .concat(stylelintBaseFile); 99 | return gulp.src(files, { allowEmpty: true }) 100 | .pipe(gulpStylelint({ 101 | reporters: [ 102 | { formatter: 'string', console: true } 103 | ] 104 | })); 105 | }); 106 | 107 | // default task 108 | gulp.task('default', gulp.series(lintTask, (done) => { 109 | // 如果是 diff 检测,检测完后删除配置文件 110 | process.env.isDiffLint && fs.unlinkSync(path.join(__dirname, 'lint.local.diff.json')); 111 | done() 112 | })); 113 | -------------------------------------------------------------------------------- /lintIgnore/eslint.default.ignore.js: -------------------------------------------------------------------------------- 1 | // 运行检测命令的目录 2 | const lintCMDPath = process.env.INIT_CWD; 3 | 4 | module.exports = [ 5 | `!${lintCMDPath}/**/node_modules/**/*.html`, 6 | `!${lintCMDPath}/**/node_modules/**/*.vue`, 7 | `!${lintCMDPath}/**/node_modules/**/*.js`, 8 | `!${lintCMDPath}/**/dist/**/*.html`, 9 | `!${lintCMDPath}/**/dist/**/*.js`, 10 | `!${lintCMDPath}/**/vendor/**/*.html`, 11 | `!${lintCMDPath}/**/vendor/**/*.js`, 12 | `!${lintCMDPath}/**/*.min.js` 13 | ] 14 | -------------------------------------------------------------------------------- /lintIgnore/stylelint.default.ignore.js: -------------------------------------------------------------------------------- 1 | // 运行检测命令的目录 2 | const lintCMDPath = process.env.INIT_CWD; 3 | 4 | module.exports = [ 5 | `!${lintCMDPath}/**/node_modules/**/*.html`, 6 | `!${lintCMDPath}/**/node_modules/**/*.vue`, 7 | `!${lintCMDPath}/**/node_modules/**/*.css`, 8 | `!${lintCMDPath}/**/node_modules/**/*.scss`, 9 | `!${lintCMDPath}/**/node_modules/**/*.less`, 10 | `!${lintCMDPath}/**/dist/**/*.html`, 11 | `!${lintCMDPath}/**/dist/**/*.css`, 12 | `!${lintCMDPath}/**/dist/**/*.scss`, 13 | `!${lintCMDPath}/**/dist/**/*.less`, 14 | `!${lintCMDPath}/**/vendor/**/*.html`, 15 | `!${lintCMDPath}/**/vendor/**/*.css`, 16 | `!${lintCMDPath}/**/vendor/**/*.scss`, 17 | `!${lintCMDPath}/**/vendor/**/*.less`, 18 | `!${lintCMDPath}/**/*.min.css`, 19 | `!${lintCMDPath}/**/*.min.scss`, 20 | `!${lintCMDPath}/**/*.min.less` 21 | ] 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "code-lint", 3 | "version": "1.3.0", 4 | "description": "", 5 | "main": "index.js", 6 | "bin": { 7 | "code-lint": "./bin/code-lint" 8 | }, 9 | "scripts": { 10 | "lint": "code-lint", 11 | "lint-localdiff": "code-lint --localdiff", 12 | "test": "mocha test/*.js" 13 | }, 14 | "repository": { 15 | "type": "git", 16 | "url": "" 17 | }, 18 | "keywords": [ 19 | "lint" 20 | ], 21 | "author": "ttsy", 22 | "license": "ISC", 23 | "dependencies": { 24 | "babel-eslint": "^10.0.1", 25 | "eslint": "^5.9.0", 26 | "eslint-config-standard": "^12.0.0", 27 | "eslint-plugin-html": "^4.0.6", 28 | "eslint-plugin-import": "^2.14.0", 29 | "eslint-plugin-node": "^8.0.0", 30 | "eslint-plugin-promise": "^4.0.1", 31 | "eslint-plugin-standard": "^4.0.0", 32 | "extend": "^3.0.2", 33 | "gulp": "^4.0.0", 34 | "gulp-eslint": "^5.0.0", 35 | "gulp-stylelint": "^8.0.0", 36 | "lowdb": "^1.0.0", 37 | "shelljs": "^0.8.1", 38 | "stylelint": "^9.8.0", 39 | "stylelint-config-standard": "^18.2.0", 40 | "stylelint-scss": "^3.4.0", 41 | "yargs": "^12.0.2" 42 | }, 43 | "devDependencies": { 44 | "chai": "*", 45 | "mocha": "*" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /test/util.test.js: -------------------------------------------------------------------------------- 1 | let util = require('../util/util.js'); 2 | let expect = require('chai').expect; 3 | 4 | describe('uniqueArr 数组去重函数测试', () => { 5 | it('传入 [1,1,2,3,4] 应该输出 [1,2,3,4]', () => { 6 | expect(util.uniqueArr([1, 1, 2, 3, 4])).to.deep.equal([1, 2, 3, 4]); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /util/pubMethod.js: -------------------------------------------------------------------------------- 1 | /* 业务相关公共函数 */ 2 | 3 | const path = require('path'); 4 | const shelljs = require('shelljs'); 5 | const low = require('lowdb'); 6 | const FileSync = require('lowdb/adapters/FileSync'); 7 | const typeConfig = require('../config/type.config'); 8 | 9 | module.exports = { 10 | /** 11 | * @desc 设置本地的变动文件列表 12 | */ 13 | setLocalDiffFileList() { 14 | let adapter = new FileSync(path.join(__dirname, '..', 'lint.local.diff.json')); 15 | let db = low(adapter); 16 | let diffFiles = shelljs.exec(`git diff --name-only`, { silent: true }).stdout.trim(); 17 | let untrackedFiles = shelljs.exec(`git ls-files --exclude-standard --others`, { silent: true }).stdout.trim(); 18 | // console.log(`------ diff files ------\n${diffFiles}\n------ diff files ------`); 19 | // console.log(`------ untracked files ------\n${untrackedFiles}\n------ untracked files ------`); 20 | let fileList = []; 21 | let lintFiles = diffFiles + '\n' + untrackedFiles; 22 | lintFiles.split('\n').forEach((val) => { 23 | let file = path.join(process.cwd(), val); 24 | fileList.push(file); 25 | }); 26 | db.set('lintTargetFiles', fileList).write(); 27 | }, 28 | /** 29 | * @desc 获取文件数组 30 | * @param files 检测文件(对象数组格式) 31 | * @param type 类型,js、css、all 32 | * @return {Array} 检测文件(数组格式) 33 | */ 34 | getFilesArr(files, type) { 35 | let filesArr = []; 36 | typeConfig[type].map((val) => { 37 | filesArr = filesArr.concat(files[val]); 38 | }) 39 | return filesArr; 40 | }, 41 | /** 42 | * @desc 打印检测文件 43 | */ 44 | printLintFiles(lintType, myLintFiles, myEsLintFiles, myStyleLintFiles) { 45 | if ((lintType['js'] && lintType['css'] && myLintFiles.length <= 0) || 46 | (lintType['js'] && !lintType['css'] && myEsLintFiles.length <= 0) || 47 | (!lintType['js'] && lintType['css'] && myStyleLintFiles.length <= 0)) return; 48 | console.log(`------ lint files ------`); 49 | if (lintType['js'] && lintType['css']) { 50 | console.log(myLintFiles.join('\n')); 51 | } else if (lintType['js']) { 52 | console.log(myEsLintFiles.join('\n')); 53 | } else if (lintType['css']) { 54 | console.log(myStyleLintFiles.join('\n')); 55 | } 56 | console.log(`------ lint files ------`); 57 | }, 58 | /** 59 | * @desc 打印检测忽略文件 60 | */ 61 | printLintIgnoreFiles(lintType, myLintIgnoreFiles, myEsLintIgnoreFiles, myStyleLintIgnoreFiles) { 62 | if ((lintType['js'] && lintType['css'] && myLintIgnoreFiles.length <= 0) || 63 | (lintType['js'] && !lintType['css'] && myEsLintIgnoreFiles.length <= 0) || 64 | (!lintType['js'] && lintType['css'] && myStyleLintIgnoreFiles.length <= 0)) return; 65 | console.log(`------ ignore files ------`); 66 | if (lintType['js'] && lintType['css']) { 67 | console.log(myLintIgnoreFiles.join('\n').replace(/!/g, '')); 68 | } else if (lintType['js']) { 69 | console.log(myEsLintIgnoreFiles.join('\n').replace(/!/g, '')); 70 | } else if (lintType['css']) { 71 | console.log(myStyleLintIgnoreFiles.join('\n').replace(/!/g, '')); 72 | } 73 | console.log(`------ ignore files ------`); 74 | } 75 | }; 76 | -------------------------------------------------------------------------------- /util/util.js: -------------------------------------------------------------------------------- 1 | 2 | /* 业务无关工具函数 */ 3 | 4 | module.exports = { 5 | /** 6 | * @desc 数组去重 7 | * @desc Array.prototype.includes 8 | * @param arr 原始数组 9 | * @return {Array} 去重后的新数组 10 | */ 11 | uniqueArr(arr) { 12 | var newArr = []; 13 | arr.map((val) => { 14 | !newArr.includes(val) && newArr.push(val); 15 | }) 16 | return newArr; 17 | } 18 | }; 19 | --------------------------------------------------------------------------------