0x1 問題
更新時間:2020-05-25 23:09:58
公司需要用到uni-app
開發新的項目,關於uni-app
的介紹可以移步官網介紹。
核心就是用Vue
寫多端應用程序,但是uni-app
的官方編輯器HbuilderX
對代碼校驗這一塊基本是空白。自己對Hbuilderx
配置也是有點模糊。
用Vue-cli
創建的項目默認啓用了保存代碼檢查,但是uni-app
開發方式有點區別。編譯和打包集成到了工具內部。所以我們只能在提交代碼之前來做代碼校驗了。
關於爲什麼要做代碼校驗,一個人開發還好。要是團隊合作,沒有統一的規則。你是天津狗不理,我是長沙臭豆腐。那個工程寫出來,基本沒有維護性可言。要自己去維護別人寫的代碼就是一個態度,他寫的代碼像💩一樣,看不懂,只能重構。大多數人都是這個樣子,沒有例外。作爲一個程序員,是要想想爲什麼那些大佬的代碼一看就能懂,寫代碼就像寫詩,在看看自己寫的,過幾天出了問題,等到親切問候了全家之後再來看是自己寫的。。。😮
由此可見規範是很重要的。
0202年了, ECMAScript 都已經2020版本了,別再用
var
定義變量、用==
做if
做判斷了。
0x2 規範提交代碼
可以參考約定式提交
一種用於給提交信息增加人機可讀含義的規範。
簡單來說就是提交代碼的規範。
已經詳細記錄到個人的文檔網站,這裏不做詳細介紹 地址
0x3 安裝需要用到的依賴
yarn add eslint babel-eslint eslint-plugin-vue husky lint-staged -D
- eslint - 校驗代碼的核心
- babel-eslint - babel插件,用babel解析js文件
- eslint-plugin-vue - vue官方的eslint插件
- husky - 可以讓git hooks的使用變得更簡單方便
- lint-staged - 可以在git staged階段的文件上執行linters,簡單點來說就是當我們運行
eslint
或stylelint
的命令時,只會檢查我們通過git add
添加到暫存區的文件,可以避免我們每次檢查都把整個項目的代碼都檢查一遍
0x4 配置
eslint
eslint的配置複製於
PanJiaChen
大佬的項目,vue-admin-template,關閉了一些實在是太變態的警告。。。(大部分是格式問題)
${app}/.eslintrc.js
/**
* @name: .eslintrc.js
* @author: SunSeekerX
* @Date: 2020-04-18 11:43:35
* @LastEditors: SunSeekerX
* @LastEditTime: 2020-05-25 22:01:11
*/
module.exports = {
root: true,
env: {
browser: true,
es6: true,
node: true,
},
// 配置js全局變量,因爲是uni-app,全局的uni是不需要引入的,還有5+的plus對象
globals: {
uni: 'readonly',
plus: 'readonly',
},
extends: ['plugin:vue/essential', 'eslint:recommended'],
parserOptions: {
parser: 'babel-eslint',
},
rules: {
'no-console': [
'warn',
{
allow: ['warn', 'error'],
},
],
'no-eval': 'error',
'no-alert': 'error',
'vue/max-attributes-per-line': [
0,
{
singleline: 10,
multiline: {
max: 1,
allowFirstLine: false,
},
},
],
'vue/singleline-html-element-content-newline': 'off',
'vue/multiline-html-element-content-newline': 'off',
'vue/name-property-casing': ['error', 'PascalCase'],
'vue/no-v-html': 'off',
'accessor-pairs': 2,
'arrow-spacing': [
2,
{
before: true,
after: true,
},
],
'block-spacing': [2, 'always'],
'brace-style': [
2,
'1tbs',
{
allowSingleLine: true,
},
],
camelcase: [
0,
{
properties: 'always',
},
],
'comma-dangle': [2, 'only-multiline'],
'comma-style': [2, 'last'],
'constructor-super': 2,
curly: [2, 'multi-line'],
'dot-location': [2, 'property'],
'eol-last': 2,
eqeqeq: ['error', 'always', { null: 'ignore' }],
'generator-star-spacing': [
2,
{
before: true,
after: true,
},
],
'handle-callback-err': [2, '^(err|error)$'],
'jsx-quotes': [2, 'prefer-single'],
'new-cap': [
2,
{
newIsCap: true,
capIsNew: false,
},
],
'new-parens': 2,
'no-array-constructor': 2,
'no-caller': 2,
'no-class-assign': 2,
'no-cond-assign': 2,
'no-const-assign': 2,
'no-control-regex': 0,
'no-delete-var': 2,
'no-dupe-args': 2,
'no-dupe-class-members': 2,
'no-dupe-keys': 2,
'no-duplicate-case': 2,
'no-empty-character-class': 2,
'no-empty-pattern': 2,
'no-ex-assign': 2,
'no-extend-native': 2,
'no-extra-bind': 2,
'no-extra-boolean-cast': 2,
'no-extra-parens': [2, 'functions'],
'no-fallthrough': 2,
'no-floating-decimal': 2,
'no-func-assign': 2,
'no-implied-eval': 2,
'no-inner-declarations': [2, 'functions'],
'no-invalid-regexp': 2,
'no-irregular-whitespace': 2,
'no-iterator': 2,
'no-label-var': 2,
'no-labels': [
2,
{
allowLoop: false,
allowSwitch: false,
},
],
'no-lone-blocks': 2,
'no-mixed-spaces-and-tabs': 1,
'no-multi-spaces': 2,
'no-multi-str': 2,
'no-native-reassign': 2,
'no-negated-in-lhs': 2,
'no-new-object': 2,
'no-new-require': 2,
'no-new-symbol': 2,
'no-new-wrappers': 2,
'no-obj-calls': 2,
'no-octal': 2,
'no-octal-escape': 2,
'no-path-concat': 2,
'no-proto': 2,
'no-redeclare': 2,
'no-regex-spaces': 2,
'no-return-assign': [2, 'except-parens'],
'no-self-assign': 2,
'no-self-compare': 2,
'no-sequences': 2,
'no-shadow-restricted-names': 2,
'no-spaced-func': 2,
'no-sparse-arrays': 2,
'no-this-before-super': 2,
'no-throw-literal': 2,
'no-trailing-spaces': 0,
'no-undef': 2,
'no-undef-init': 2,
'no-unexpected-multiline': 2,
'no-unmodified-loop-condition': 2,
'no-unneeded-ternary': [
2,
{
defaultAssignment: false,
},
],
'no-unreachable': 2,
'no-unsafe-finally': 2,
'no-unused-vars': [
2,
{
vars: 'all',
args: 'none',
},
],
'no-useless-call': 2,
'no-useless-computed-key': 2,
'no-useless-constructor': 2,
'no-useless-escape': 0,
'no-whitespace-before-property': 2,
'no-with': 2,
'one-var': [
2,
{
initialized: 'never',
},
],
'operator-linebreak': [
2,
'after',
{
overrides: {
'?': 'before',
':': 'before',
},
},
],
'padded-blocks': [2, 'never'],
quotes: [
2,
'single',
{
avoidEscape: true,
allowTemplateLiterals: true,
},
],
'semi-spacing': [
2,
{
before: false,
after: true,
},
],
'space-before-function-paren': [2, 'never'],
'space-in-parens': [2, 'never'],
'space-infix-ops': 1,
'space-unary-ops': [
2,
{
words: true,
nonwords: false,
},
],
'spaced-comment': [
2,
'always',
{
markers: [
'global',
'globals',
'eslint',
'eslint-disable',
'*package',
'!',
',',
],
},
],
'template-curly-spacing': [2, 'never'],
'use-isnan': 2,
'valid-typeof': 2,
'wrap-iife': [2, 'any'],
'yield-star-spacing': [2, 'both'],
yoda: [2, 'never'],
'prefer-const': 2,
'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
'object-curly-spacing': [
2,
'always',
{
objectsInObjects: false,
},
],
'array-bracket-spacing': [2, 'never'],
'no-prototype-builtins': 0,
// 自定義開始
'vue/html-indent': 0,
'vue/html-closing-bracket-newline': 0,
'vue/html-self-closing': 0,
indent: 0,
semi: 0,
'comma-spacing': 0,
'space-before-blocks': 0,
'keyword-spacing': 0,
'key-spacing': 0,
'no-multiple-empty-lines': 0,
},
}
package.json
刪除了不必要的信息
${app}/package.json
{
"name": "ybt-mp",
"version": "1.0.0",
"scripts": {
"gc": "git add -A && git cz && git pull && git push",
"lint": "eslint --ext .js,.vue ./"
},
"license": "MIT",
"devDependencies": {
"@commitlint/cli": "^8.3.5",
"@commitlint/config-conventional": "^8.3.4",
"babel-eslint": "^10.1.0",
"cz-conventional-changelog": "3.2.0",
"eslint": "^7.1.0",
"eslint-plugin-vue": "^6.2.2",
"husky": "^4.2.5",
"lint-staged": "^10.2.6"
},
"config": {
"commitizen": {
"path": "./node_modules/cz-conventional-changelog"
}
},
"dependencies": {
"uview-ui": "^1.2.8"
},
"commitlint": {
"extends": [
"@commitlint/config-conventional"
]
},
"husky": {
"hooks": {
"pre-commit": "lint-staged",
"commit-msg": "commitlint -e $GIT_PARAMS"
}
},
"lint-staged": {
"*.{js,vue}": [
"yarn lint",
"git add"
]
}
}
0x5 使用
提交代碼
本地執行
yarn gc
# 實際執行,這是個人自己定義的命令,因爲經常需要推送和拉取代碼,核心就是git cz替代git commit -m ''可以選擇本次提交的類型,很方便
git add -A && git cz && git pull && git push
示例
SunSeekerX@SunSeekerX-NoteBook MINGW64 /w/Coding/uni-app/ybt-mp (master)
$ yarn gc
yarn run v1.22.4
$ git add -A && git cz && git pull && git push
[email protected], [email protected]
? Select the type of change that you're committing: feat: A new feature
? What is the scope of this change (e.g. component or file name): (press enter to skip)
? Write a short, imperative tense description of the change (max 66 chars):
(16) 加入代碼提交eslint校驗配置
? Provide a longer description of the change: (press enter to skip)
? Are there any breaking changes? No
? Does this change affect any open issues? No
husky > pre-commit (node v12.16.3)
‼ Some of your tasks use `git add` command. Please remove it from the config since all modifications made by tasks will be automatically added to the git commit index.
[STARTED] Preparing...
[SUCCESS] Preparing...
[STARTED] Running tasks...
[STARTED] Running tasks for *.{js,vue}
[STARTED] yarn lint
[SUCCESS] yarn lint
[STARTED] git add
[SUCCESS] git add
[SUCCESS] Running tasks for *.{js,vue}
[SUCCESS] Running tasks...
[STARTED] Applying modifications...
[SUCCESS] Applying modifications...
[STARTED] Cleaning up...
[SUCCESS] Cleaning up...
husky > commit-msg (node v12.16.3)
[master c050a53] feat: 加入代碼提交eslint校驗配置
11 files changed, 1851 insertions(+), 1076 deletions(-)
create mode 100644 .eslintignore
rewrite components/ybt-patient-card/ybt-patient-card.vue (97%)
rewrite pages/home/home.vue (84%)
rewrite pages/patrol/patrol.vue (97%)
Already up to date.
Enumerating objects: 44, done.
Counting objects: 100% (44/44), done.
Delta compression using up to 4 threads
Compressing objects: 100% (19/19), done.
Writing objects: 100% (23/23), 16.87 KiB | 2.11 MiB/s, done.
Total 23 (delta 11), reused 0 (delta 0)
To http://gitlab.lvyii.com/yibiaotong/ybt-mp.git
be3ffc1..c050a53 master -> master
Done in 19.97s.
一條命令搞定了代碼提交、校驗、拉取、推送。當然遇到有衝突的情況還是需要自己手動解決。
代碼校驗
yarn lint
# 實際執行,調用eslint檢查後綴是js和vue的文件,暫時沒有加入css,和scss校驗
eslint --ext .js,.vue ./
示例
SunSeekerX@SunSeekerX-NoteBook MINGW64 /w/Coding/uni-app/ybt-mp (master)
$ yarn lint
yarn run v1.22.4
$ eslint --ext .js,.vue ./
W:\Coding\uni-app\ybt-mp\main.js
31:7 error 's' is assigned a value but never used no-unused-vars
W:\Coding\uni-app\ybt-mp\pages\home\home.vue
6:2 warning Mixed spaces and tabs no-mixed-spaces-and-tabs
201:7 warning Unexpected console statement no-console
W:\Coding\uni-app\ybt-mp\pages\patrol\patrol-detail\patrol-detail.vue
124:4 warning Unexpected console statement no-console
W:\Coding\uni-app\ybt-mp\pages\patrol\patrol-list\patrol-list.vue
38:4 warning Unexpected console statement no-console
W:\Coding\uni-app\ybt-mp\utils\app-update.js
40:7 warning Unexpected console statement no-console
45:9 warning Unexpected console statement no-console
48:9 warning Unexpected console statement no-console
60:3 warning Unexpected console statement no-console
W:\Coding\uni-app\ybt-mp\utils\index.js
29:4 warning Unexpected console statement no-console
42:4 warning Unexpected console statement no-console
56:4 warning Unexpected console statement no-console
✖ 12 problems (1 error, 11 warnings)
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
0x6 總結
經過這麼配置之後,代碼的質量和規範相對於沒有配置之前維護性大大提高,同時也可以避免一些錯誤的發生。但工具終究是工具,寫代碼的終究是人,在編寫代碼的同時,養成好的編碼習慣和優化意識才是最重要的。
在我眼中程序員可以不穿很時髦的衣服,但是一定要穿的乾淨。多多少少有點潔癖、有點強迫症、😂
0x7 其他
參考文章:lint-staged和husky在pre-commit階段做代碼檢查
關於我
SunSeekerX,前端開發、Nodejs開發、小程序、uni-app
開發、等等
喜歡探討技術實現方案和細節,完美主義者,見不得bug
。
Github:https://github.com/SunSeekerX
個人博客:https://yoouu.cn/
個人在線筆記:https://sunseekerx.yoouu.cn/