【這篇隨筆記錄的很簡單,沒有涉及具體的Eslint規則解釋以及FlowType的類型說明和使用等,只是鏈接了所需的若干文檔】
js開發很舒服,但是代碼一多起來就參差不齊,難以閱讀了。所以加上一些代碼規范以及檢測報錯會保證項目代碼的健康程度,我這里使用的是Eslint + FlowType來進行代碼規范的(我還不會TypeScript,所以就沒有和TS的對比了)。
達到的目標:
- Eslint
- 對代碼的縮進、格式等有規定
- ...諸多Eslint的規定,具體參見Eslint文檔。
- FlowType
- 所有的方法參數都有明確的類型聲明和返回類型聲明
具體的環境配置方法:
- Eslint
- 參考 Eslint Getting Started進行環境配置(我使用的是airbnb的,並且有所修改)。
- 配置.eslintrc文件,指定屬於你自己的規則。
- (可選)設置git提交,在eslint檢測通過后才可以。修改git的
/.git/hooks/pre-commit文件(沒有的話,新建一個),修改為如下所示。(這里可以用ln -s將.git/hooks鏈接到git倉庫里的自己創建的gitHooks目錄,可以使用git管理這些文件,默認的.git/目錄是被git忽視的,無法直接管理。)
#! /usr/bin/env python
import sys
import os
# in "<project_dir>/gitHooks"
os.chdir(os.path.dirname(__file__))
# in "<project_dir>"
os.chdir('..')
def runCommand(command):
return os.popen(command).read().strip('\n')
cachedFiles = runCommand('git diff --name-only --cached --diff-filter=ACMR')
if not cachedFiles:
sys.exit(0)
files = cachedFiles.split('\n')
filePaths = ''
folderPath = os.getcwd()
for file in files:
if file.endswith('.js'):
filePaths += os.path.join(file) + ' '
if not filePaths.strip():
sys.exit(0)
checkStylePath = ''
checkStyleCommand = './node_modules/.bin/eslint {files}'.format(files=filePaths)
if os.system(checkStyleCommand) == 0:
sys.exit(0)
else:
sys.exit(1)
- FlowType
- 參考FlowType的eslint引導,將其中的規則copy到eslintrc文件里。可以根據自己的要求修改。
- FlowType的具體type定義使用參考FlowType
項目報錯,但是想修改這個eslint rule的步驟(針對WebStorm)
- 查看錯誤原因(指針指着紅線就可以了),copy里面的原因,此處為"spaced-comment"
- 在node_module目錄下全局搜索錯誤原因,從搜索結果里挨個找,可以找到air-bnb的文件,叫作
eslint-config-airbnb-base...
,從里面可以查看具體的規則說明,可以通過注釋的鏈接跳轉到詳細的網頁。 - 在網頁上查看具體規則說明,並修改自己的eslintrc文件的rule。
我的.eslintrc.js
module.exports = {
env: {
es6: true,
node: true,
},
extends: 'airbnb',
globals: {
Atomics: 'readonly',
SharedArrayBuffer: 'readonly',
},
// let babel-eslint parse, because type definition will be error with eslint parser.
parser: "babel-eslint",
parserOptions: {
ecmaFeatures: {
jsx: true,
},
ecmaVersion: 2018,
sourceType: 'module',
},
plugins: [
'react',
"flowtype",
],
rules: {
// 0 for 'off', 1 for 'warning',2 for 'error',
// indent by 4
"indent": ["error", 4, {
"SwitchCase": 1,
"FunctionDeclaration": {
"parameters": "first"
},
"FunctionExpression": {
"parameters": "first"
}
}],
// Enforce JSX indentation
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-indent.md
'react/jsx-indent': ['error', 4],
// Validate props indentation in JSX
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-indent-props.md
'react/jsx-indent-props': ['error', 4],
// max length of one line
"max-len": ["error", 130],
// should have space after "{" and before "}"
"object-curly-spacing": ["error", "never"],
// When there is only a single export from a module, prefer using default export over named export.
'import/prefer-default-export': 'off',
// http://eslint.org/docs/rules/quotes
"quotes": ["off"],
// https://eslint.org/docs/rules/object-curly-newline
'object-curly-newline': ['error', {
ObjectExpression: {minProperties: 4, multiline: true, consistent: true},
ObjectPattern: {minProperties: 4, multiline: true, consistent: true},
// it is not necessary to do with import and export( WebStorm does not supprt quick format to this )
// ImportDeclaration: {minProperties: 4, multiline: true, consistent: true},
// ExportDeclaration: {minProperties: 4, multiline: true, consistent: true},
}],
// http://eslint.org/docs/rules/no-underscore-dangle
"no-underscore-dangle": [0],
// allow
"no-unused-expressions": 0,
// allow use of variables before they are defined
"no-use-before-define": 0,
// only .js and .jsx files may have JSX,
// https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-filename-extension.md
'react/jsx-filename-extension': [
2,
{
extensions: ['.js', '.jsx'],
},
],
// Validate whitespace in and around the JSX opening and closing brackets
// https://github.com/yannickcr/eslint-plugin-react/blob/843d71a432baf0f01f598d7cf1eea75ad6896e4b/docs/rules/jsx-tag-spacing.md
'react/jsx-tag-spacing': ['error', {
closingSlash: 'never',
beforeSelfClosing: 'never',
afterOpening: 'never',
beforeClosing: 'never',
}],
// do not require all requires be top-level to allow static require for <Image/>
// https://eslint.org/docs/rules/global-require
'global-require': 0,
// enforces no braces where they can be omitted
// https://eslint.org/docs/rules/arrow-body-style
'arrow-body-style': [1, 'as-needed', {
requireReturnForObjectLiteral: false,
}],
// below is flowType lint
// https://github.com/gajus/eslint-plugin-flowtype
"flowtype/boolean-style": [
2,
"boolean"
],
"flowtype/define-flow-type": 1,
"flowtype/delimiter-dangle": [
2,
"never"
],
"flowtype/generic-spacing": [
2,
"never"
],
"flowtype/no-mixed": 2,
"flowtype/no-primitive-constructor-types": 2,
"flowtype/no-types-missing-file-annotation": 2,
"flowtype/no-weak-types": 2,
"flowtype/object-type-delimiter": [
2,
"comma"
],
"flowtype/require-parameter-type": 2,
"flowtype/require-return-type": [
2,
"always",
{
"annotateUndefined": "never"
}
],
"flowtype/require-valid-file-annotation": 2,
"flowtype/semi": [
2,
"always"
],
"flowtype/space-after-type-colon": [
2,
"always"
],
"flowtype/space-before-generic-bracket": [
2,
"never"
],
"flowtype/space-before-type-colon": [
2,
"never"
],
"flowtype/type-id-match": [
2,
"^([A-Z][a-z0-9]+)+Type$"
],
"flowtype/union-intersection-spacing": [
2,
"always"
],
"flowtype/use-flow-type": 1,
"flowtype/valid-syntax": 1
},
};