背景
最近媳妇接到一个任务,将无外网的vue老项目添加规范,接到这个任务之后,我和我媳妇在家研究了三天三夜,不眠不休,终于搞定了,咱们来往下看看,如何添加规范的。
分析
考虑到开发环境的特殊性,咱们本着低风险,高收益的原则(渐进式)去处理。 受限条件:
- 文件个数 1k+
- 开发人员无法 install package,只能领导将包下载好之后 copy 给开发人员
- 多人维护的项目,尽量不让其他开发人员添加更多的配置
- windows 系统
根据上的面的限制,市场上比较流行的组合:eslint+prettier+husky+lint-staged.
husky:不太好使用,因为husky在install的时候才在.git/hooks中添加钩子脚本,内网开发人员做不到install
lint-staged: 主要是一个在 git 暂存文件上(也就是被 git add
的文件)运行已配置的 linter(或其他)任务。这里我们自己实现,能减少依赖尽量减少
最后,我们这个项目只用到 eslint+prettier 了。
那么问题来了,不适用husky,我们怎么在git commit 之前做lint呢?
其实,git已经给我们预留好了钩子,不过需要我们添加,.git/hooks/pre-commit,添加pre commit的相关操作即可,我们git commit之前git会先执行.git/hooks/pre-commit 再往后执行(除非被exit了)
还有一个就是渐进式去lint文件,所谓渐进式,就是commit哪个文件就lint哪个文件,其他的文件不做任何处理,这样只会影响自己改动的,不会影响到其他的文件了。
分析好了,咱们就开始操作了
安装eslint 和 prettier 插件和配置文件
- 插件 这个项目老到了node是10版本,因此,使用比较来的插件来处理,这里的插件就不一一解说了,自己可以百度看看是干啥的。
{
"eslint": "^5.16.0",
"eslint-config-standard": "^12.0.0",
"eslint-loader": "^2.2.1",
"eslint-plugin-html": "^6.1.2",
"eslint-plugin-import": "^2.24.2",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^5.1.0",
"eslint-plugin-standard": "^5.0.0",
"eslint-plugin-vue": "^5.0.0",
"vue-eslint-parser": "^7.11.0",
"eslint-config-prettier": "^4.0.0",
"babel-eslint": "^9.0.0",
"prettier": "^1.0.0",
"eslint-plugin-prettier": "^3.0.0"
}
- eslintrc配置 在根目录添加.eslintrc.js配置文件
// https://eslint.org/docs/user-guide/configuring
module.exports = {
root: true,
parserOptions: {
parser: 'babel-eslint'
},
env: {
browser: true
},
extends: ['plugin:vue/essential', 'standard', 'plugin:prettier/recommended'],
plugins: ['vue'],
rules: {
'prettier/prettier': [
'error',
{
printWidth: 100,
tabWidth: 2,
useTabs: false,
singleQuote: true,
semi: true,
bracketSpacing: true,
jsxBracketSameLine: true
}
],
'generator-star-spacing': 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
// semi 语句结束带分号
semi: 0,
// 换行缩进 4个空格
// indent: ["warn", 2, { SwitchCase: 1 }],
'template-curly-spacing': 'off',
indent: [
'error',
2,
{
ignoredNodes: ['TemplateLiteral']
}
],
// 禁止空块语句
'no-empty': 2,
// 不允许空比较
'no-eq-null': 2,
// 不允许 new 完后不赋值
'no-new': 0,
// 要求使用 === 和 !==
eqeqeq: 0,
// 生产环境无 console
'no-console': process.env.NODE_ENV === 'production' ? ['error'] : 'off',
// 函数左圆括号空格设置
'space-before-function-paren': 0,
// 对 Vue 组件标签,不进行检查
'vue/no-parsing-error': [2, { 'x-invalid-end-tag': false }],
'no-mixed-operators': 0,
camelcase: 0,
'standard/computed-property-even-spacing': 0,
'prefer-promise-reject-errors': 0,
'no-unused-vars': 0
}
}
- prettier配置 在根目录添加.prettierrc.js配置文件
module.exports = {
// 最大长度80个字符
printWidth: 80,
// 行末分号
semi: false,
// 单引号
singleQuote: true,
// JSX双引号
jsxSingleQuote: false,
// 尽可能使用尾随逗号(包括函数参数)
trailingComma: "none",
// 在对象文字中打印括号之间的空格。
bracketSpacing: true,
// > 标签放在最后一行的末尾,而不是单独放在下一行
jsxBracketSameLine: false,
// 箭头圆括号
arrowParens: "avoid",
// 在文件顶部插入一个特殊的 @format 标记,指定文件格式需要被格式化。
insertPragma: false,
// 缩进
tabWidth: 2,
// 使用tab还是空格
useTabs: false,
// 行尾换行格式
endOfLine: "auto",
HTMLWhitespaceSensitivity: "ignore"
};
- 渐进式校验并格式化文件 根据老项目的结构,我是放在了 build\pre-commit.sh
#!/bin/sh
# 代码冲突
result=$(git --no-pager diff HEAD --check | grep "conflict")
if [[ "$result" != "" ]]; then
echo Resolve code conflicts, $result,$?
exit 1
fi
# eslint staged
INFO='\033[36m'
NOR='\033[0m'
# 获取staged的文件相对路径
file=$(git diff --staged --name-only | egrep "^src/")
if [ -z "${file}" ]; then
echo -e "${INFO}No file changed, exit now ${NOR}"
exit 0
fi
# 校验并格式化staged的文件
npx eslint --fix --ext .js,.vue $file --cache > .eslitStash
a=$(cat .eslitStash | egrep "[1-9]\d*\s*problems?\s\([1-9]\d*\s*errors?")
cat .eslitStash
rm -rf .eslitStash
if [ -n "${a}" ]; then
exit 1
fi
# 将格式化之后的文件重新 git add
exec git add $file
如何去做pre-commit呢
上面的分析已经说了,在.git/hooks
文件夹中添加pre-commit
脚本文件,然后去调用上面的 build\pre-commit.sh
,这里的.git/hooks/pre-commit 我采用npm run xx形式添加,这样对于其他开发人员操作更加方便.
build\add-exec-to-pre-commit.sh
#!/bin/sh
echo "#!/bin/sh" > .git/hooks/pre-commit
echo "cd ." >> .git/hooks/pre-commit
echo "build\\\pre-commit.sh" >> .git/hooks/pre-commit
在package.json 的 scripts 添加执行命令
{
"scripts":{
"addPreCommitHook": "sh build/add-exec-to-pre-commit.sh"
}
}
这样就OK啦,后面git commit 就会直接lint & fix staged的文件了。
如何利用vscode自动格式化呢
只需要安装三个插件: Prettier 、ESLint、Prettier-ESLint
- vscode配置
{
"prettier.configPath": ".prettierrc.js",
"editor.formatOnSave": true,
"[javascript]": { "editor.defaultFormatter": "rvest.vs-code-prettier-eslint" },
"[typescript]": { "editor.defaultFormatter": "rvest.vs-code-prettier-eslint" },
"[javascript|react]": { "editor.defaultFormatter": "rvest.vs-code-prettier-eslint" },
"[typescript|react]": { "editor.defaultFormatter": "rvest.vs-code-prettier-eslint" },
"[less]": { "editor.defaultFormatter": "rvest.vs-code-prettier-eslint" },
"[css]": { "editor.defaultFormatter": "rvest.vs-code-prettier-eslint" },
"[json]": { "editor.defaultFormatter": "rvest.vs-code-prettier-eslint" }
}
}
注意,一定要看
- 上面用的Linux语法,因此,windows系统的,咱们git命令一定要在git bash中执行。否则sh文件无法执行
- 使用git bash 方式
- windows系统右击可以调出 git bash命令板
- vscode的terminal,配置方式 vscode 终端设置 Git Bash
- 使用git bash 方式
- 如果不想eslint校验&fix, 直接使用
git commit -m "xxx" --no-verify
结束
感谢您认真看完,如有不同见解,可以在留言区一起讨论一下