书写规范

  1. 文件命名规范
  2. HTML书写规范
  3. CSS书写规范
  4. JavaScript规范
    1. prettier规则
  5. TypeScript规范
  6. Vue单文件规范
  7. 参考地址

定义好格式与规范 是 写代码,做项目的基础; (格式与规范要禁得起验证!)

利于定义软件组件之间的接口,利于深入了解现存的js库的行为;

利于通过动态加载的组件来减少命名冲突,类型选择系统;


文件命名规范

1. 全部采用小写方式, 以下划线分隔

eg: my-project-name

HTML书写规范

<!--
    原则: 任何时候都要用 尽量小的复杂度和尽量少的标签 来解决问题

    1. 缩进使用soft tab(4个空格);
    2. 嵌套的节点应该缩进;
    3. 在属性上,使用双引号,不要使用单引号;
    4. 属性名全小写,用中划线做分隔符;
    5. 不要在自动闭合标签结尾处使用斜线;
    6. 不要忽略可选的关闭标签,例:</li> 和 </body>。
    7. 应在html标签上加上lang属性。这会给语音工具和翻译工具帮助,告诉它们应当怎么去发音和翻译
    8. 属性应该按照特定的顺序出现以保证易读性;
        class
        id
        name
        data-*
        src, for, type, href, value , max-length, max, min, pattern
        placeholder, title, alt
        aria-*, role
        required, readonly, disabled
    9. 在JS文件中生成标签让内容变得更难查找,更难编辑,性能更差(jsx除外)
    10. 在编写HTML代码时,需要尽量避免多余的父节点;很多时候,需要通过迭代和重构来使HTML变得更少。    
-->
<!DOCTYPE html>
<html lang='zh'>
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
        <title>Page title</title>
        <link rel="stylesheet" href="code_guide.css">
        <style></style>
    </head>
    <body>
        <img src="images/company_logo.png" alt="Company">
        <h1 class="hello-world">Hello, world!</h1>
        <input type="checkbox" value="1" checked>
        <script></script>
    </body>
</html>

CSS书写规范

<!--
    1. 使用soft tab(4个空格);
    2. 每个属性声明末尾都要加分号;
    3. 注释统一用'/* */';
    4. 最外层统一使用双引号;
    5. 尽量将媒体查询的规则靠近与他们相关的规则;
    6. 属性顺序: 
        1. Positioning Model 布局方式、位置,eg:position, top, z-index, display, float等
        2. Box Model 盒模型,eg:width, height, padding, margin,border, overflow
        3. Typographic 文本排版,eg:font, line-height, text-align
        4. Visual 视觉外观,eg:color, background, list-style, transform, animation
-->
/* class用 - 连接 尽量语义化 */
/* 属性能简写就简写 */
/* 颜色16进制能缩写就缩写 */
/* 去掉小数点前的0 */
/* 用 border: 0; 代替 border: none; */
/* 不轻易使用id */
/* id采用驼峰式命名 */
/* scss中的变量、函数、混合、placeholder采用驼峰式命名 */
.element,
.top-banner {
    /* position */
    position: absolute;
    top: 10px; /* 10px */
    left: 10px;

    width: 50px;
    height: 50px;
    border-radius: 10px;

    background-color: #012;
}

@media (min-width: 480px) {
    .element {

    }
}

@if {

} @else {

}

JavaScript规范

注意 JSDoc 的书写规范,可以让自己的代码更加富有可读性和规范性。

ESLint

console.log(111);

/* eslint-disable no-console, no-alert */
console.log(123);
/* eslint-enable */

console.log(123);

prettier规则

module.exports = {
    // 一行最多 80 字符
    printWidth: 80,
    // 使用 4 个空格缩进
    tabWidth: 4,
    // 不使用缩进符,而使用空格
    useTabs: false,
    // 行尾需要有分号
    semi: true,
    // 使用单引号
    singleQuote: true,
    // 对象的 key 仅在必要时用引号
    quoteProps: 'as-needed',
    // jsx 不使用单引号,而使用双引号
    jsxSingleQuote: false,
    // 末尾不需要逗号
    trailingComma: 'none',
    // 大括号内的首尾需要空格
    bracketSpacing: true,
    // jsx 标签的反尖括号需要换行
    jsxBracketSameLine: false,
    // 箭头函数,只有一个参数的时候,也需要括号
    arrowParens: 'always',
    // 每个文件格式化的范围是文件的全部内容
    rangeStart: 0,
    rangeEnd: Infinity,
    // 不需要写文件开头的 @prettier
    requirePragma: false,
    // 不需要自动在文件开头插入 @prettier
    insertPragma: false,
    // 使用默认的折行标准
    proseWrap: 'preserve',
    // 根据显示样式决定 html 要不要折行
    htmlWhitespaceSensitivity: 'css',
    // 换行符使用 lf
    endOfLine: 'lf'
};
// 无 BOM UTF-8编码
// 文件结尾处保留一个空行

// 缩进
switch () {
    case '1':
        // do...
        break;
    case '2': 
        // do...
        break;
    default:
        // do...       
}

// 二元运算符两侧必须有一个空格,一元运算符与操作对象之间不允许有空格
var a = !boo;
c++;
var b = c + d;

// 代码块起始;关键字之后的空格
if (condition) {
}

while (condition) {
}

(function () {
})();

// 对象属性
var obj = {
    a: 1,
    b: 2,
    c: 3
};

// 函数名
function funcName() {
}

var funcName = function funcName() {
};

funcName();

// 标点符号
callFunc(a, b);

// 括号内
callFunc(param1, param2, param3);

save(this.list[this.indexes[i]]);

needIncream && (variable += increament);

if (num > list.length) {
}

while (len--) {
}


// 数组对象
var arr1 = [];
var arr2 = [1, 2, 3];
var obj1 = {};
var obj2 = {name: 'obj'};
var obj3 = {
    name: 'obj',
    age: 20,
    sex: 1
};

// 换行,每个独立语句结束后必须换行,每行不得超过120个字符
if (user.isAuthenticated()
    && user.isInRole('admin')
    && user.hasAuthority('add-admin')
    || user.hasAuthority('delete-admin')
) {
    // Code
}
var result = number1 + number2 + number3
    + number4 + number5;

// 逗号换行
var obj = {
    a: 1,
    b: 2,
    c: 3
};

/**
 * @func
 * @desc 一个带参数的函数
 * @param {string} a - 参数a
 * @param {number} b=1 - 参数b默认值为1
 * @param {string} c=1 - 参数c有两种支持的取值</br>1—表示x</br>2—表示xx
 * @param {object} d - 参数d为一个对象
 * @param {string} d.e - 参数d的e属性
 * @param {string} d.f - 参数d的f属性
 * @param {object[]} g - 参数g为一个对象数组
 * @param {string} g.h - 参数g数组中一项的h属性
 * @param {string} g.i - 参数g数组中一项的i属性
 * @param {string} [j] - 参数j是一个可选参数
 */
function foo(a, b, c, d, g, j) {
    ...
}

foo(
    aVeryVeryLongArgument,
    anotherVeryLongArgument,
    callback
);

// 不同行为或逻辑的语句集,使用空行隔开,更易阅读
function setStyle(element, property, value) {
    if (element == null) {
        return;
    }

    element.style[property] = value;
}

// 较复杂的逻辑条件组合,将每个条件独立一行,逻辑运算符放置在行首进行分隔,或将部分逻辑按逻辑组合进行分隔。
// 建议最终将右括号 ) 与左大括号 { 放在独立一行,保证与 `if` 内语句块能容易视觉辨识。
if (user.isAuthenticated()
    && user.isInRole('admin')
    && user.hasAuthority('add-admin')
    || user.hasAuthority('delete-admin')
) {
    // Code
}

// 按一定长度截断字符串,并使用 + 运算符进行连接。
// 分隔字符串尽量按语义进行,如不要在一个完整的名词中间断开。
// 特别的,对于 HTML 片段的拼接,通过缩进,保持和 HTML 相同的结构。
// 使用 + 拼接字符串,如果拼接的全部是 StringLiteral,压缩工具可以对其进行自动合并的优化。所以,静态字符串建议使用 + 拼接。
// 在现代浏览器下,使用 + 拼接字符串,性能较数组的方式要高。
// 如需要兼顾老旧浏览器,应尽量使用数组拼接字符串。
var html = '' // 此处用一个空字符串,以便整个 HTML 片段都在新行严格对齐
    + '<article>'
    +     '<h1>Title here</h1>'
    +     '<p>This is a paragraph</p>'
    +     '<footer>Complete</footer>'
    + '</article>';

// 也可使用数组来进行拼接,相对 `+` 更容易调整缩进。
var html = [
    '<article>',
        '<h1>Title here</h1>',
        '<p>This is a paragraph</p>',
        '<footer>Complete</footer>',
    '</article>'
];
html = html.join('');

// 当参数过多时,将每个参数独立写在一行上,并将结束的右括号 ) 独立一行。
// 所有参数必须增加一个缩进。
foo(
    aVeryVeryLongArgument,
    anotherVeryLongArgument,
    callback
);

// 也可以按逻辑对参数进行组合。
// 最经典的是 baidu.format 函数,调用时将参数分为“模板”和“数据”两块
baidu.format(
    dateFormatTemplate,
    year, month, date, hour, minute, second
);

// 当函数调用时,如果有一个或以上参数跨越多行,应当每一个参数独立一行。
// 这通常出现在匿名函数或者对象初始化等作为参数时,如 `setTimeout` 函数等。
setTimeout(
    function () {
        alert('hello');
    },
    200
);

order.data.read(
    'id=' + me.model.id,
    function (data) {
        me.attchToModel(data.result);
        callback();
    },
    300
);

// 链式调用较长时采用缩进进行调整。
$('#items')
    .find('.selected')
    .highlight()
    .end();

// 三元运算符由3部分组成,因此其换行应当根据每个部分的长度不同,形成不同的情况。
var result = thisIsAVeryVeryLongCondition
    ? resultA : resultB;

var result = condition
    ? thisIsAVeryVeryLongResult
    : resultB;

// 数组和对象初始化的混用,严格按照每个对象的 `{` 和结束 `}` 在独立一行的风格书写。
var array = [
    {
        // ...
    },
    {
        // ...
    }
];

// 函数定义结束不允许添加分号,如果是函数表达式,分号是不允许省略的

// 立即执行函数(IIFE) 
var task = (function () {
   // Code
   return result;
})();

// 变量:驼峰命名法;常量:全大写,下划线连接;函数:驼峰命名法; 类: Pascal命名法
// 函数名 使用 动宾短语
// boolean 类型的变量使用 is 或 has 开头
// Promise对象 用 动宾短语的进行时 表达

// 避免使用 /*...*/ 这样的多行注释。有多行注释内容时,使用多个单行注释


// 在 Equality Expression 中使用类型严格的 ===。仅当判断 null 或 undefined 时,允许使用 == null

// 数组非空

// good
if (collection.length) {
    // ......
}

// null 或 undefined

// good
if (noValue == null) {
  // ......
}

// bad
if (noValue === null || typeof noValue === 'undefined') {
  // ......
}

// 对于相同变量或表达式的多值条件,用 switch 代替 if

// 如果函数或全局中的 else 块后没有任何语句,可以删除 else

// 不要在循环体中包含函数表达式,事先将函数提取到循环体外
// good
function clicker() {
    // ......
}

for (var i = 0, len = elements.length; i < len; i++) {
    var element = elements[i];
    addListener(element, 'click', clicker);
}

// 类型检测

// string
typeof variable === 'string'

// number
typeof variable === 'number'

// boolean
typeof variable === 'boolean'

// Function
typeof variable === 'function'

// Object
typeof variable === 'object'

// RegExp
variable instanceof RegExp

// Array
variable instanceof Array

// null
variable === null

// null or undefined
variable == null

// undefined
typeof variable === 'undefined'


// 转换string
num + '';

// 转换成 number 时,通常使用 +
+str

// string 转换成 number,要转换的字符串结尾包含非数字并期望忽略时,使用 parseInt
// 使用 parseInt 时,必须指定进制
var width = '200px';
parseInt(width, 10);

// 转换成boolean时, 使用!!
var num = 3.14;
!!num;

// number 去除小数点,使用 Math.floor / Math.round / Math.ceil
Math.ceil(num);

// 字符串开头和结束使用单引号 '

// 清空数组使用 .length = 0

// 一个函数的长度控制在 50 行以内

// 一个函数的参数控制在 6 个以内

VSCode直接下载eslint插件

 "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true
  }
module.exports = {
  // 以当前目录为根目录,不再向上查找 .eslintrc.js
  root: true,
  parser: 'babel-eslint',
  parserOptions: {
    ecmaVersion: 2019,
    // ECMA modules 模式
    sourceType: 'module',
    ecmaFeatures: {
      // 不允许 return 语句出现在 global 环境下
      globalReturn: false,
      // 开启全局 strict 模式
      impliedStrict: true,
      jsx: true
    },
    // 即使没有babelrc配置文件, 也使用 babel-eslint 来解析
    requireConfigFile: false,
    // 仅允许 import export 语句出现在模块的顶层
    allowImportExportEverywhere: false
  },
  extends: '',
  plugins: [
    'html'
  ],
  env: {
    browser: true,
    node: true,
    commonjs:true,
    es6: true
  },
  rules: {
    // setter 必须有对应的 getter,getter 可以没有对应的 setter
    'accessor-pairs': [
      'error',
      {
        setWithoutGet: true,
        getWithoutSet: false
      }
    ],
    // 数组的方法除了 forEach 之外,回调函数必须有返回值
    'array-callback-return': 'error',
    // 将var定义的变量视为块作用域, 禁止在块外使用(off, 禁止使用var)
    'block-scoped-var': 'off',
    // 变量名必须是camelCase风格的(关)
    'camelcase': 'off',
    // 注释的首字母必须大写(关)
    'capitalized-comments': 'off',
    // 在类的非静态方法中,必须存在对this的引用(关)
    'class-methods-use-this': 'off',
    // 禁止函数的循环复杂度超过20
    'complexity': [
      'error',
      {
        max: 20
      }
    ],
    // 禁止函数在不同分支返回不同类型的值(off)@reason 缺少 TypeScript 的支持,类型判断是不准确的
    'consistent-return': 'off',
    // 限制this的别名
    'consistent-this': 'off',
    // constructor中必须有super
    'constructor-super': 'error',
    // switch语句必须有default
    'default-case': 'off',
    // switch语句中的default必须在最后
    'default-case-last': 'error',
    // 有默认值的参数必须放在函数参数的末尾 (off)
    'default-param-last': 'off',
    // 禁止使用foo['bar'], 必须写成 foo.bar (off)
    'dot-notation': 'off',
    // 必须使用 === 或 !==,禁止使用 == 或 !=
    eqeqeq: ['error', 'always'],
    // 禁止方向错误的for循环 ?? 
    'for-direction': 'error',
    // 函数赋值给变量的时候,函数名必须与变量名一致
    'func-name-matching': [
      'error',
      'always',
      {
        includeCommonJSModuleExports: false
      }
    ],
    // 函数必须有名字(off)
    'func-names': 'off',
    // 必须只使用函数声明或只使用函数表达式
    'func-style': 'off',
    // getter 必须有返回值,并且禁止返回空
    'getter-return': 'off',
    // setter 和 getter必须写在一起
    'grouped-accessor-pairs': 'error',
    // for in 内部必须有 hasOwnProperty
    'guard-for-in': 'error',
    // 禁止使用指定的标识符
    'id-denylist': 'off',
    // 限制变量名长度
    'id-length': 'off',
    // 限制变量名必须匹配指定的正则表达式
    'id-match': 'off',
    // 变量必须在定义的时候赋值
    'init-declarations': 'off',
    // 单行注释必须写在上一行
    'line-comment-position': 'off',
    // 类的成员之间是否需要空行
    'lines-between-class-members': 'off',
    // 限制一个文件中类的数量
    'max-classes-per-file': 'off',
    // 代码块嵌套的深度禁止超过5层
    'max-depth': ['error', 5],
    // 限制一个文件最多的行数
    'max-lines': 'off',
    // 限制函数块中的代码行数
    'max-lines-per-function': 'off',
    // 回调函数嵌套禁止超过3层, 多了请用async await替代
    'max-nested-callbacks': ['error', 3],
    // 函数的参数禁止超过3个
    'max-params': ['error', 3],
    // 限制函数块中的语句数量
    'max-statements': ['off'],
    // 限制一行中的语句数量
    'max-statements-per-line': 'off',
    // 约束多行注释的格式(能写注释已经很不容易了,不需要限制太多)
    'multiline-comment-style': 'off',
    // new 后面的类名必须首字母大写
    'new-cap': [
      'error',
      {
        newIsCap: true,
        capIsNew: false,
        properties: true
      }
    ],
    // 禁止使用alert
    'no-alert': 'off'
    // 禁止使用Array构造函数时传入的参数超过一个(参数为一个时表示创建一个指定长度的数组,比较常用)
    'no-array-constructor': 'error'
    // 禁止将 async 函数作为 new Promise 的回调函数; 出现这种情况时,一般不需要使用 new Promise 实现异步了
    'no-async-promise-executor': 'error',
    // 禁止将 await 写在循环里, 因为这样就无法同时发送多个异步请求了
    'no-await-in-loop': 'off',
    // 禁止使用位运算
    'no-bitwise': 'off',
    // 禁止使用 caller 或 callee
    'no-caller': 'error',
    // switch 的 case 内有变量定义的时候, 必须使用大括号将case内变成一个代码块
    'no-case-declarations': 'error',
    // 禁止对已定义的class重新赋值
    'no-class-assign': 'error',
    // 禁止与负零进行比较
    'no-compare-neg-zero': 'error',
    // 禁止在测试表达式中使用赋值语句,除非这个赋值语句被括号包起来了
    'no-cond-assign': ['error', 'except-parens'],
    // 禁止使用console
    'no-console': 'off',
    // 禁止将常量作为分支条件判断中的测试表达式,但允许作为循环条件判断中的测试表达式
    'no-constant-condition': [
      'error',
      {
        checkLoops: false
      }
    ],
    // 禁止在构造函数中返回值
    'no-constructor-return': 'error',
    // 禁止使用continue
    'no-continue': 'off',
    // 禁止在正则表达式中出现 ctrl 键的 ASCII表示
    'no-control-regex': 'off',
    // 禁止使用 debugger
    'no-debugger': 'error',
    // 禁止对一个变量使用 delete
    'no-delete-var': 'off',
    // 禁止在正则表达式中出现形似除法操作符的开头,如 let a = /=foo/
    'no-div-regex': 'off',
    // 禁止在函数参数中出现重复名称的参数
    'no-dupe-args': 'off',
    // 禁止重复定义类的成员
    'no-dupe-class-members': 'error',
    // 禁止 if else 的条件判断中出现重复的条件
    'no-dupe-else-if': 'error',
    // 禁止在对象字面量中出现重复的键名
    'no-dupe-keys': 'error',
    // 禁止在 switch 语句中出现重复测试表达式的 case
    'no-duplicate-case': 'error',
    // 禁止重复导入模块
    'no-duplicate-imports': 'error'
    // 禁止在else内使用 return, 必须改为提前结束
    'no-else-return': 'off',
    // 禁止出现空代码块, 允许 catch 为空代码块
    'no-empty': [
      'error',
      {
        allowEmptyCatch: true
      }
    ],
    // 禁止在正则表达式中使用空的字符集
    'no-empty-character-class': 'error',
    // 不允许有空函数(有时需要将一个空函数设置为某个项的默认值)
    'no-empty-function': 'off',
    // 禁止解构赋值中出现空 {} 或 []
    'no-empty-pattern': 'error',
    // 禁止使用 foo == null, 必须使用 foo === null
    'no-eq-null': 'error',
    // 禁止使用 eval
    'no-eval': 'error'
    // 禁止将catch中的第一个参数error重新赋值
    'no-ex-assgin': 'error',
    // 禁止修改原生对象
    'no-extend-native': 'error',
    // 禁止出现没必要的 bind
    'no-extra-bind': 'error',
    // 禁止不必要的布尔类型转换
    'no-extra-boolean-cast': 'error',
    // 禁止出现没必要的label
    'no-extra-label': 'off',
    // switch case内必须有 break, return 或 throw, 空的 case 除外
    'no-fallthrouth': 'error',
    // 禁止将一个函数声明重新赋值
    'no-func-assign': 'error',
    // 禁止对全局变量赋值
    'no-global-assign': 'error',
    // 禁止使用 ~+ 等难以理解的类型转换, 仅允许使用 !!
    'no-implicit-coercion': [
      'error',
      {
        allow: ['!!']
      }
    ],
    // 禁止在全局作用域下定义变量或声明函数,模块化之后不会出现这种情况
    'no-implicit-globals': 'off',
    // 禁止在setTimeout 或 setInterval中传入字符串
    'no-implied-eval': 'error',
    // 禁止对导入的模块进行赋值
    'no-import-assign':'error',
    // 禁止在代码后添加单行注释
    'no-inline-comments': 'off',
    // 禁止在if代码块中出现函数声明
    'no-inner-declarations': ['error', 'both'],
    // 禁止在 regexp构造函数中出现非法的正则表达式
    'no-invalid-regexp': 'error',
    // 禁止在类之外的地方使用this, 只允许在class中使用this
    'no-invalid-this': 'error',
    // 禁止使用特殊空白符(比如全角空格),除非是出现在字符串、正则表达式或模板字符串中
    'no-irregular-whitespace': [
      'error',
      {
        skipStrings: true,
        skipComments: false,
        skipRegExps: true,
        skipTemplates: true
      }
    ],
    // 禁止使用 __iterator__
    'no-iterator': 'error',
    // 禁止label名称与已定义的变量重复
    'no-label-var': 'off',
    // 禁止使用label
    'no-labels': 'error',
    // 禁止使用没必要的 {} 作为代码块
    'no-lone-blocks': 'error',
    // 禁止 else 中只有一个单独的 if
    'no-lonely-if': 'off',
    // 禁止在循环内的函数内部出现循环体条件语句中定义的变量(let可以解决这个问题)
    'no-loop-func': 'off',
    // 禁止使用超出 js 精度范围的数字
    'no-loss-of-precision': 'error',
    // 禁止使用magic numbers
    'no-magic-numbers': 'off',
    // 禁止正则表达式中使用肉眼无法区分的特殊字符
    'no-misleading-character-class': 'error',
    // 禁止连续赋值
    'no-multi-assign': 'off',
    // 禁止使用 \ 来换行字符串 ??
    'no-multi-str': 'error',
    // 禁止 if 中有否定的表达式
    'no-negated-condition': 'off',
    // 禁止使用嵌套的三元表达式
    'no-nested-ternary': 'off',
    // 禁止直接 new 一个类而不赋值
    'no-new': 'error',
    // 禁止使用 new Function
    'no-new-func': 'error',
    // 禁止直接 new Object
    'no-new-object': 'error',
    // 禁止使用 new 来生成 Symbol
    'no-new-symbol': 'error',
    // 禁止使用 Math, JSON 或 Reflect 直接作为函数调用
    'no-obj-calls': 'error',
    // 禁止使用0开头的数字表示八进制数
    'no-octal': 'off',
    // 禁止使用八进制的转义符
    'no-octal-escape': 'off',
    // 禁止对函数的参数重新赋值
    'no-param-reassign': 'error',
    // 禁止使用 ++ 或 --
    'no-plusplus': 'off',
    // 禁止在Promise的回调函数中直接 return
    'no-promise-executor-return': 'error',
    // 禁止使用 __protp__
    'no-proto': 'error',
    // 禁止使用 hasOwnProperty, isPrototypeOf 或 propertyIsEnumerable
    'no-prototype-builtins': 'off',
    // 禁止重复定义变量
    'no-redeclare': 'off',
    // 禁止在正则表达式中出现连续的空格
    'no-regex-spaces': 'error',
    // 禁止导出指定的变量名
    'no-regex-spaces': 'error',
    // 禁止使用指定的全局变量
    'no-restricted-globals': 'off',
    // 禁止导入指定的模块
    'no-restricted-imports': 'off',
    // 禁止使用指定的对象属性
    'no-restricted-properties': 'off',
    // 禁止使用指定的语法
    'no-restricted-syntax': 'off',
    // 禁止在 return 语句里赋值
    'no-return-assign': ['error', 'always'],
    // 禁止在 return 语句里使用 await
    'no-return-await': 'off',
    // 禁止出现 location.href = 'javascript:void(0)'; @reason 有些场景下还是需要用到这个
    'no-script-url': 'off',
    // 禁止将自己赋值给自己
    'no-self-assign': 'error',
    // 禁止将自己与自己比较
    'no-self-compare': 'error',
    // 禁止使用逗号操作符
    'no-sequences': 'error',
    // 禁止 setter 有返回值
    'no-setter-return': 'error',
    // 禁止变量名与上层作用域内的已定义的变量重复
    // @reason 很多时候函数的形参和传参是同名的
    'no-shadow': 'off',
    // 禁止使用保留字作为变量名
    'no-shadow-restricted-names': 'error',
    // 禁止在数组中出现连续的逗号
    'no-sparse-arrays': 'error',
    // 禁止在普通字符串中出现模版字符串里的变量形式
    'no-template-curly-in-string': 'error',
    // 禁止使用三元表达式
    'no-ternary': 'off',
    // 禁止在 super 被调用之前使用 this 或 super
    'no-this-before-super': 'error',
    // 禁止 throw 字面量,必须 throw 一个 Error 对象
    'no-throw-literal': 'error',
    // 禁止使用未定义的变量
    'no-undef': 'error',
    // 禁止将 undefined 赋值给变量
    'no-undef-init': 'error',
    // 禁止使用 undefined
    'no-undefined': 'off',
    // 禁止变量名出现下划线
    'no-underscore-dangle': 'off',
    // 循环内必须对循环条件中的变量有修改
    'no-unmodified-loop-condition': 'error',
    /**
     * 必须使用 !a 替代 a ? false : true
     * @reason 后者表达的更清晰
     */
    'no-unneeded-ternary': 'off',
    // 禁止在 return, throw, break 或 continue 之后还有代码
    'no-unreachable': 'error',
    // 禁止在第一轮循环时就一定会退出循环的情况出现
    'no-unreachable-loop': 'error',
    /**
     * 禁止在 finally 中出现 return, throw, break 或 continue
     * @reason finally 中的语句会在 try 之前执行
     */
    'no-unsafe-finally': 'error',
    // 禁止在 in 或 instanceof 操作符的左侧变量前使用感叹号
    'no-unsafe-negation': 'error',
    // 禁止无用的表达式
    'no-unused-expressions': [
        'error',
        {
          allowShortCircuit: true,
          allowTernary: true,
          allowTaggedTemplates: true
        }
    ],
    /**
     * 禁止出现没用到的 label
     * @reason 已经禁止使用 label 了
     */
    'no-unused-labels': 'off',
    // 已定义的变量必须使用
    'no-unused-vars': [
        'error',
        {
          vars: 'all',
          args: 'none',
          ignoreRestSiblings: false,
          caughtErrors: 'none'
        }
    ],
    // 变量必须先定义后使用
    'no-use-before-define': [
        'error',
        {
          variables: false,
          functions: false,
          classes: false
        }
    ],
    // 禁止正则表达式中出现无用的回溯引用 @reason 某些回溯引用语法上没问题,但是会永远匹配到空字符串
    'no-useless-backreference': 'error',
    // 禁止出现没必要的 call 或 apply
    'no-useless-call': 'error',
    // 禁止在 catch 中仅仅只是把错误 throw 出去 @reason 这样的 catch 是没有意义的,等价于直接执行 try 里的代码
    'no-useless-catch': 'error',
    // 禁止出现没必要的计算键名
    'no-useless-computed-key': 'error',
    // 禁止出现没必要的字符串连接
    'no-useless-concat': 'error',
    // 禁止出现没必要的 constructor
    'no-useless-constructor': 'error',
    /**禁止出现没必要的转义
     * @reason 转义可以使代码更易懂
     */
    'no-useless-escape': 'off',
    // 禁止解构赋值时出现同样名字的的重命名,比如 let { foo: foo } = bar;
    'no-useless-rename': 'error',
    // 禁止没必要的 return
    'no-useless-return': 'off',
    // 禁止使用 var
    'no-var': 'error',
    // 禁止使用 void
    'no-void': 'error',
    // 禁止注释中出现 TODO 和 FIXME
    'no-warning-comments': 'off',
    // 禁止使用 with @reason 编译阶段就会报错了
    'no-with': 'off',
    // 必须使用 a = {b} 而不是 a = {b: b} @reason 有时后者可以使代码结构更清晰
    'object-shorthand': 'off',
    // 禁止变量申明时用逗号一次申明多个
    'one-var': ['error', 'never'],
    // 必须使用 x = x + y 而不是 x += y
    'operator-assignment': 'off',
    // 限制语句之间的空行规则,比如变量定义完之后必须要空行
    'padding-line-between-statements': 'off',
    // 申明后不再被修改的变量必须使用 const 来申明
    'prefer-const': 'off',
    // 必须使用解构赋值
    'prefer-destructuring': 'off',
    // 使用 ES2016 的语法 ** 替代 Math.pow
    'prefer-exponentiation-operator': 'off',
    /**使用 ES2018 中的正则表达式命名组
     * @reason 正则表达式已经较难理解了,没必要强制加上命名组
     */
    'prefer-named-capture-group': 'off',
    // 必须使用 0b11111011 而不是 parseInt()
    'prefer-numeric-literals': 'off',
    // 必须使用 ... 而不是 Object.assign,除非 Object.assign 的第一个参数是一个变量
    'prefer-object-spread': 'error',
    // Promise 的 reject 中必须传入 Error 对象,而不是字面量
    'prefer-promise-reject-errors': 'error',
    // 优先使用正则表达式字面量,而不是 RegExp 构造函数
    'prefer-regex-literals': 'error',
    // 必须使用 ...args 而不是 arguments
    'prefer-rest-params': 'off',
    // 必须使用 ... 而不是 apply,比如 foo(...args)
    'prefer-spread': 'off',
    // 必须使用模版字符串而不是字符串连接
    'prefer-template': 'off',
    // parseInt 必须传入第二个参数
    radix: 'error',
    /**
     * 禁止将 await 或 yield 的结果做为运算符的后面项
     * @reason 这样会导致不符合预期的结果
     * https://github.com/eslint/eslint/issues/11899
     * 在上面 issue 修复之前,关闭此规则
     */
    'require-atomic-updates': 'off',
    // async 函数中必须存在 await 语句
    'require-await': 'off',
    // 正则表达式中必须要加上 u 标志
    'require-unicode-regexp': 'off',
    // generator 函数内必须有 yield
    'require-yield': 'error',
    // 导入必须按规则排序
    'sort-imports': 'off',
    // 对象字面量的键名必须排好序
    'sort-keys': 'off',
    // 变量申明必须排好序
    'sort-vars': 'off',
    // 注释的斜线或 * 后必须有空格
    'spaced-comment': [
        'error',
        'always',
        {
          block: {
            exceptions: ['*'],
            balanced: true
          }
        }
    ],
    // 禁止使用 'strict';
    strict: ['error', 'never'],
    // 创建 Symbol 时必须传入参数
    'symbol-description': 'error',
    // 必须使用 isNaN(foo) 而不是 foo === NaN
    'use-isnan': 'error',
    // typeof 表达式比较的对象必须是 'undefined', 'object', 'boolean', 'number', 'string', 'function', 'symbol', 或 'bigint'
    'valid-typeof': 'error',
    // var 必须在作用域的最前面
    'vars-on-top': 'off',
    // 必须使用 if (foo === 5) 而不是 if (5 === foo)
    yoda: [
      'error',
      'never',
      {
        onlyEquality: true
      }
    ]
}

TypeScript规范

  • tsconfig.json
{
    "compilerOptions": {
        // 开启的特性
        //
        // 兼容 babel 模块导入的模式(不需要 * as)
        "esModuleInterop": true,
        // 支持引入 json 模块
        "resolveJsonModule": true,
        // React 项目需要配置此项
        "jsx": "react",
        // 禁止导入模块时大小写错误
        "forceConsistentCasingInFileNames": true,

        // 生成文件的配置
        //
        // 指定生成文件的 ECMAScript 版本
        "target": "es2018",
        // 指定生成哪个模块系统代码
        "module": "commonjs",
        // 决定如何处理模块
        "moduleResolution": "node",
        // 生成的文件的换行符
        "newLine": "lf",
        // 不生成输出
        "noEmit": true,

        // 严格模式,可选择性的开启,建议开启的越多越好
        //
        // 严格模式
        "strict": true,
        // 若有未使用的局部变量则抛错
        "noUnusedLocals": true,
        // 若有未使用的参数则抛错
        "noUnusedParameters": true,

        // stdout 输出
        //
        // 给错误和消息设置样式,使用颜色和上下文
        "pretty": true
    }
}
module.exports = {
    parser: '@typescript-eslint/parser',
    plugins: ['@typescript-eslint'],
    rules: {
        'react/sort-comp': 'off',
        /**
         * 重载的函数必须写在一起
         * @reason 增加可读性
         */
        '@typescript-eslint/adjacent-overload-signatures': 'error',
        /**
         * 限制数组类型必须使用 Array<T> 或 T[]
         * @reason 允许灵活运用两者
         */
        '@typescript-eslint/array-type': 'off',
        /**
         * 禁止对没有 then 方法的对象使用 await
         */
        '@typescript-eslint/await-thenable': 'off',
        /**
         * 禁止使用 // @ts-ignore // @ts-nocheck // @ts-check
         * @reason 这种注释本身就是对特殊代码的说明
         */
        '@typescript-eslint/ban-ts-comment': 'off',
        /**
         * 禁止使用类似 tslint:disable-next-line 这样的注释
         */
        '@typescript-eslint/ban-tslint-comment': 'off',
        /**
         * 禁止使用指定的类型
         */
        '@typescript-eslint/ban-types': 'off',
        /**
         * 类的只读属性若是一个字面量,则必须使用只读属性而不是 getter
         */
        '@typescript-eslint/class-literal-property-style': ['error', 'fields'],
        /**
         * 类型断言必须使用 as Type,禁止使用 <Type>,禁止对对象字面量进行类型断言(断言成 any 是允许的)
         * @reason <Type> 容易被理解为 jsx
         */
        '@typescript-eslint/consistent-type-assertions': [
            'error',
            {
                assertionStyle: 'as',
                objectLiteralTypeAssertions: 'never'
            }
        ],
        /**
         * 优先使用 interface 而不是 type
         * @reason interface 可以 implement, extend 和 merge
         */
        '@typescript-eslint/consistent-type-definitions': ['error', 'interface'],
        /**
         * 有默认值或可选的参数必须放到最后
         */
        'default-param-last': 'off',
        '@typescript-eslint/default-param-last': 'off',
        /**
         * 禁止使用 foo['bar'],必须写成 foo.bar
         * @reason 当需要写一系列属性的时候,可以更统一
         */
        'dot-notation': 'off',
        '@typescript-eslint/dot-notation': 'off',
        /**
         * 函数返回值必须与声明的类型一致
         * @reason 编译阶段检查就足够了
         */
        '@typescript-eslint/explicit-function-return-type': 'off',
        /**
         * 必须设置类的成员的可访问性
         * @reason 将不需要公开的成员设为私有的,可以增强代码的可理解性,对文档输出也很友好
         */
        '@typescript-eslint/explicit-member-accessibility': 'error',
        /**
         * 导出的函数或类中的 public 方法必须定义输入输出参数的类型
         */
        '@typescript-eslint/explicit-module-boundary-types': 'off',
        /**
         * 变量必须在定义的时候赋值
         */
        'init-declarations': 'off',
        '@typescript-eslint/init-declarations': 'off',
        /**
         * 类的成员之间是否需要空行
         * @reason 有时为了紧凑需要挨在一起,有时为了可读性需要空一行
         */
        'lines-between-class-members': 'off',
        '@typescript-eslint/lines-between-class-members': 'off',
        /**
         * 指定类成员的排序规则
         * @reason 优先级:
         * 1. static > instance
         * 2. field > constructor > method
         * 3. public > protected > private
         */
        '@typescript-eslint/member-ordering': [
            'error',
            {
                default: [
                    'public-static-field',
                    'protected-static-field',
                    'private-static-field',
                    'static-field',
                    'public-static-method',
                    'protected-static-method',
                    'private-static-method',
                    'static-method',
                    'public-instance-field',
                    'protected-instance-field',
                    'private-instance-field',
                    'public-field',
                    'protected-field',
                    'private-field',
                    'instance-field',
                    'field',
                    'constructor',
                    'public-instance-method',
                    'protected-instance-method',
                    'private-instance-method',
                    'public-method',
                    'protected-method',
                    'private-method',
                    'instance-method',
                    'method'
                ]
            }
        ],
        /**
         * 接口中的方法必须用属性的方式定义
         * @reason 配置了 strictFunctionTypes 之后,用属性的方式定义方法可以获得更严格的检查
         */
        '@typescript-eslint/method-signature-style': 'error',
        /**
         * 限制各种变量或类型的命名规则
         */
        '@typescript-eslint/naming-convention': 'off',
        /**
         * 禁止使用 Array 构造函数
         */
        'no-array-constructor': 'off',
        '@typescript-eslint/no-array-constructor': 'off',
        /**
         * 禁止滥用 toString 方法
         */
        '@typescript-eslint/no-base-to-string': 'off',
        /**
         * 禁止使用容易混淆的非空断言
         */
        '@typescript-eslint/no-confusing-non-null-assertion': 'off',
        /**
         * 禁止重复定义类的成员
         * @reason 编译阶段就会报错了
         */
        'no-dupe-class-members': 'off',
        '@typescript-eslint/no-dupe-class-members': 'off',
        /**
         * 禁止 delete 时传入的 key 是动态的
         */
        '@typescript-eslint/no-dynamic-delete': 'off',
        /**
         * 不允许有空函数
         * @reason 有时需要将一个空函数设置为某个项的默认值
         */
        'no-empty-function': 'off',
        '@typescript-eslint/no-empty-function': 'off',
        /**
         * 禁止定义空的接口
         */
        '@typescript-eslint/no-empty-interface': 'error',
        /**
         * 禁止使用 any
         */
        '@typescript-eslint/no-explicit-any': 'off',
        /**
         * 禁止多余的 non-null 断言
         */
        '@typescript-eslint/no-extra-non-null-assertion': 'off',
        /**
         * 禁止定义没必要的类,比如只有静态方法的类
         */
        '@typescript-eslint/no-extraneous-class': 'off',
        /**
         * 禁止调用 Promise 时没有处理异常情况
         */
        '@typescript-eslint/no-floating-promises': 'off',
        /**
         * 禁止对 array 使用 for in 循环
         */
        '@typescript-eslint/no-for-in-array': 'off',
        /**
         * 禁止使用 eval
         */
        '@typescript-eslint/no-implied-eval': 'off',
        /**
         * 禁止给一个初始化时直接赋值为 number, string 的变量显式的声明类型
         * @reason 可以简化代码
         */
        '@typescript-eslint/no-inferrable-types': 'error',
        /**
         * 禁止在类之外的地方使用 this
         * @reason 只允许在 class 中使用 this
         */
        'no-invalid-this': 'off',
        '@typescript-eslint/no-invalid-this': 'error',
        /**
         * 禁止使用无意义的 void 类型
         * @reason void 只能用在函数的返回值中
         */
        '@typescript-eslint/no-invalid-void-type': 'error',
        /**
         * 禁止使用超出 js 精度范围的数字
         */
        'no-loss-of-precision': 'off',
        '@typescript-eslint/no-loss-of-precision': 'error',
        /**
         * 禁止使用 magic numbers
         */
        'no-magic-numbers': 'off',
        '@typescript-eslint/no-magic-numbers': 'off',
        /**
         * 禁止在接口中定义 constructor,或在类中定义 new
         */
        '@typescript-eslint/no-misused-new': 'off',
        /**
         * 避免错误的使用 Promise
         */
        '@typescript-eslint/no-misused-promises': 'off',
        /**
         * 禁止使用 namespace 来定义命名空间
         * @reason 使用 es6 引入模块,才是更标准的方式。
         * 但是允许使用 declare namespace ... {} 来定义外部命名空间
         */
        '@typescript-eslint/no-namespace': [
            'error',
            {
                allowDeclarations: true,
                allowDefinitionFiles: true
            }
        ],
        /**
         * 禁止在 optional chaining 之后使用 non-null 断言(感叹号)
         * @reason optional chaining 后面的属性一定是非空的
         */
        '@typescript-eslint/no-non-null-asserted-optional-chain': 'error',
        /**
         * 禁止使用 non-null 断言(感叹号)
         * @reason 使用 non-null 断言时就已经清楚了风险
         */
        '@typescript-eslint/no-non-null-assertion': 'off',
        /**
         * 禁止给类的构造函数的参数添加修饰符
         * @reason 强制所有属性都定义到类里面,比较统一
         */
        '@typescript-eslint/no-parameter-properties': 'error',
        /**
         * 禁止使用 require
         * @reason 统一使用 import 来引入模块,特殊情况使用单行注释允许 require 引入
         */
        '@typescript-eslint/no-require-imports': 'error',
        /**
         * 禁止将 this 赋值给其他变量,除非是解构赋值
         */
        '@typescript-eslint/no-this-alias': [
            'error',
            {
                allowDestructuring: true
            }
        ],
        /**
         * 禁止 throw 字面量,必须 throw 一个 Error 对象
         */
        '@typescript-eslint/no-throw-literal': 'off',
        /**
         * 禁止使用类型别名
         */
        '@typescript-eslint/no-type-alias': 'off',
        /**
         * 测试表达式中的布尔类型禁止与 true 或 false 直接比较
         */
        '@typescript-eslint/no-unnecessary-boolean-literal-compare': 'off',
        /**
         * 条件表达式禁止是永远为真(或永远为假)的
         */
        '@typescript-eslint/no-unnecessary-condition': 'off',
        /**
         * 在命名空间中,可以直接使用内部变量,不需要添加命名空间前缀
         */
        '@typescript-eslint/no-unnecessary-qualifier': 'off',
        /**
         * 禁止范型的类型有默认值时,将范型设置为该默认值
         */
        '@typescript-eslint/no-unnecessary-type-arguments': 'off',
        /**
         * 禁止无用的类型断言
         */
        '@typescript-eslint/no-unnecessary-type-assertion': 'off',
        /**
         * 禁止将变量或属性的类型设置为 any
         */
        '@typescript-eslint/no-unsafe-assignment': 'off',
        /**
         * 禁止调用 any 类型的变量上的方法
         */
        '@typescript-eslint/no-unsafe-call': 'off',
        /**
         * 禁止获取 any 类型的变量中的属性
         */
        '@typescript-eslint/no-unsafe-member-access': 'off',
        /**
         * 禁止函数的返回值的类型是 any
         */
        '@typescript-eslint/no-unsafe-return': 'off',
        /**
         * 禁止无用的表达式
         */
        'no-unused-expressions': 'off',
        '@typescript-eslint/no-unused-expressions': [
            'error',
            {
                allowShortCircuit: true,
                allowTernary: true,
                allowTaggedTemplates: true
            }
        ],
        /**
         * 已定义的变量必须使用
         * @reason 编译阶段检查就足够了
         */
        'no-unused-vars': 'off',
        '@typescript-eslint/no-unused-vars': 'off',
        /**
         * 禁止已定义的变量未使用
         */
        '@typescript-eslint/no-unused-vars-experimental': 'off',
        /**
         * 禁止在定义变量之前就使用它
         * @reason 编译阶段检查就足够了
         */
        'no-use-before-define': 'off',
        '@typescript-eslint/no-use-before-define': 'off',
        /**
         * 禁止出现没必要的 constructor
         */
        'no-useless-constructor': 'off',
        '@typescript-eslint/no-useless-constructor': 'error',
        /**
         * 禁止使用 require 来引入模块
         * @reason no-require-imports 规则已经约束了 require
         */
        '@typescript-eslint/no-var-requires': 'off',
        /**
         * 使用 as const 替代 as 'bar'
         * @reason as const 是新语法,不是很常见
         */
        '@typescript-eslint/prefer-as-const': 'off',
        /**
         * 使用 for 循环遍历数组时,如果索引仅用于获取成员,则必须使用 for of 循环替代 for 循环
         * @reason for of 循环更加易读
         */
        '@typescript-eslint/prefer-for-of': 'error',
        /**
         * 使用函数类型别名替代包含函数调用声明的接口
         */
        '@typescript-eslint/prefer-function-type': 'error',
        /**
         * 使用 includes 而不是 indexOf
         */
        '@typescript-eslint/prefer-includes': 'off',
        /**
         * 枚举类型的值必须是字面量,禁止是计算值
         * @reason 编译阶段检查就足够了
         */
        '@typescript-eslint/prefer-literal-enum-member': 'off',
        /**
         * 禁止使用 module 来定义命名空间
         * @reason module 已成为 js 的关键字
         */
        '@typescript-eslint/prefer-namespace-keyword': 'error',
        /**
         * 使用 ?? 替代 ||
         */
        '@typescript-eslint/prefer-nullish-coalescing': 'off',
        /**
         * 使用 optional chaining 替代 &&
         */
        '@typescript-eslint/prefer-optional-chain': 'error',
        /**
         * 私有变量如果没有在构造函数外被赋值,则必须设为 readonly
         */
        '@typescript-eslint/prefer-readonly': 'off',
        /**
         * 函数的参数必须设置为 readonly
         */
        '@typescript-eslint/prefer-readonly-parameter-types': 'off',
        /**
         * 使用 reduce 方法时,必须传入范型,而不是对第二个参数使用 as
         */
        '@typescript-eslint/prefer-reduce-type-parameter': 'off',
        /**
         * 使用 RegExp#exec 而不是 String#match
         */
        '@typescript-eslint/prefer-regexp-exec': 'off',
        /**
         * 使用 String#startsWith 而不是其他方式
         */
        '@typescript-eslint/prefer-string-starts-ends-with': 'off',
        /**
         * 当需要忽略下一行的 ts 错误时,必须使用 @ts-expect-error 而不是 @ts-ignore
         * @reason 使用 @ts-expect-error 可以避免对不会报错的代码设置了 @ts-ignore
         */
        '@typescript-eslint/prefer-ts-expect-error': 'off',
        /**
         * async 函数的返回值必须是 Promise
         */
        '@typescript-eslint/promise-function-async': 'off',
        /**
         * 使用 sort 时必须传入比较函数
         */
        '@typescript-eslint/require-array-sort-compare': 'off',
        /**
         * async 函数中必须存在 await 语句
         */
        'require-await': 'off',
        '@typescript-eslint/require-await': 'off',
        /**
         * 使用加号时,两者必须同为数字或同为字符串
         */
        '@typescript-eslint/restrict-plus-operands': 'off',
        /**
         * 模版字符串中的变量类型必须是字符串
         */
        '@typescript-eslint/restrict-template-expressions': 'off',
        /**
         * 禁止在 return 语句里使用 await
         */
        'no-return-await': 'off',
        '@typescript-eslint/return-await': 'off',
        /**
         * 条件判断必须传入布尔值
         */
        '@typescript-eslint/strict-boolean-expressions': 'off',
        /**
         * 使用联合类型作为 switch 的对象时,必须包含每一个类型的 case
         */
        '@typescript-eslint/switch-exhaustiveness-check': 'off',
        /**
         * 禁止使用三斜杠导入文件
         * @reason 三斜杠是已废弃的语法,但在类型声明文件中还是可以使用的
         */
        '@typescript-eslint/triple-slash-reference': [
            'error',
            {
                path: 'never',
                types: 'always',
                lib: 'always'
            }
        ],
        /**
         * interface 和 type 定义时必须声明成员的类型
         */
        '@typescript-eslint/typedef': [
            'error',
            {
                arrayDestructuring: false,
                arrowParameter: false,
                memberVariableDeclaration: false,
                objectDestructuring: false,
                parameter: false,
                propertyDeclaration: true,
                variableDeclaration: false
            }
        ],
        /**
         * 方法调用时需要绑定到正确的 this 上
         */
        '@typescript-eslint/unbound-method': 'off',
        /**
         * 函数重载时,若能通过联合类型将两个函数的类型声明合为一个,则使用联合类型而不是两个函数声明
         */
        '@typescript-eslint/unified-signatures': 'error'
    }
};

Vue单文件规范

module.exports = {
    parser: 'vue-eslint-parser',
    parserOptions: {
        // 设置 js 的解析器为 babel-eslint
        // https://github.com/mysticatea/vue-eslint-parser#-options
        parser: 'babel-eslint',
        ecmaVersion: 2019,
        // ECMAScript modules 模式
        sourceType: 'module',
        ecmaFeatures: {
            // 不允许 return 语句出现在 global 环境下
            globalReturn: false,
            // 开启全局 script 模式
            impliedStrict: true,
            jsx: true
        },
        // 即使没有 babelrc 配置文件,也使用 babel-eslint 来解析
        requireConfigFile: false,
        // 仅允许 import export 语句出现在模块的顶层
        allowImportExportEverywhere: false
    },
    plugins: ['vue'],
    rules: {
        /**
         * 限制自定义组件的属性风格
         */
        'vue/attribute-hyphenation': 'off',
        /**
         * 标签属性必须按规则排序
         */
        'vue/attributes-order': 'error',
        /**
         * 变量名必须是 camelcase 风格的
         * @reason 很多 api 或文件名都不是 camelcase 风格的
         */
        'vue/camelcase': 'off',
        /**
         * 支持在模版中使用 eslint-disable-next-line 等注释
         */
        'vue/comment-directive': 'error',
        /**
         * 组件的 name 属性必须符合 PascalCase
         * @reason 这是官方建议的规范
         */
        'vue/component-definition-name-casing': ['error', 'PascalCase'],
        /**
         * 限制组件名的风格
         */
        'vue/component-name-in-template-casing': 'off',
        /**
         * 组件中必须按照 <script>, <template>, <style> 排序
         * @reason 这是官方建议的顺序
         */
        'vue/component-tags-order': [
            'error',
            {
                order: ['script', 'template', 'style']
            }
        ],
        /**
         * 必须使用 === 或 !==,禁止使用 == 或 !=
         */
        'vue/eqeqeq': ['error', 'always'],
        /**
         * 修复 no-unused-vars 不检查 jsx 的问题
         */
        'vue/jsx-uses-vars': 'error',
        /**
         * 组件名称必须和文件名一致
         */
        'vue/match-component-file-name': 'off',
        /**
         * 限制组件的 name 属性的值的风格
         */
        'vue/name-property-casing': 'off',
        /**
         * 计算属性禁止包含异步方法
         */
        'vue/no-async-in-computed-properties': 'error',
        /**
         * 禁止给布尔值 props 添加默认值
         * @reason 类型相关的约束交给 TypeScript
         */
        'vue/no-boolean-default': 'off',
        /**
         * 禁用已废弃的 scope 属性
         */
        'vue/no-deprecated-scope-attribute': 'error',
        /**
         * 使用 v-slot 替代已废弃的 slot
         */
        'vue/no-deprecated-slot-attribute': 'error',
        /**
         * 禁用已废弃的 slot-scope
         */
        'vue/no-deprecated-slot-scope-attribute': 'error',
        /**
         * 禁止重复的键名
         */
        'vue/no-dupe-keys': 'error',
        /**
         * 禁止出现重复的属性
         */
        'vue/no-duplicate-attributes': [
            'error',
            {
                allowCoexistClass: false,
                allowCoexistStyle: false
            }
        ],
        /**
         * 禁止解构赋值中出现空 {} 或 []
         */
        'vue/no-empty-pattern': 'error',
        /**
         * 禁止使用特殊空白符(比如全角空格),除非是出现在字符串、正则表达式、模版字符串中或 HTML 内容中
         */
        'vue/no-irregular-whitespace': [
            'error',
            {
                skipStrings: true,
                skipComments: false,
                skipRegExps: true,
                skipTemplates: true,
                skipHTMLTextContents: true
            }
        ],
        /**
         * 禁止出现语法错误
         */
        'vue/no-parsing-error': 'error',
        /**
         * 组件的 name 属性静止使用保留字
         */
        'vue/no-reserved-component-names': 'error',
        /**
         * 禁止覆盖保留字
         */
        'vue/no-reserved-keys': 'error',
        /**
         * 禁止使用指定的语法
         */
        'vue/no-restricted-syntax': 'off',
        /**
         * 组件的 data 属性的值必须是一个函数
         */
        'vue/no-shared-component-data': 'off',
        /**
         * 禁止在计算属性中对属性修改
         */
        'vue/no-side-effects-in-computed-properties': 'off',
        /**
         * 禁止使用 style 属性
         */
        'vue/no-static-inline-styles': 'off',
        /**
         * 禁止 <template> 使用 key 属性
         */
        'vue/no-template-key': 'off',
        /**
         * 模版中的变量名禁止与前一个作用域重名
         */
        'vue/no-template-shadow': 'off',
        /**
         * 禁止在 <textarea> 中出现模版语法 
         */
        'vue/no-textarea-mustache': 'error',
        /**
         * 当你的 vue 版本较老时,禁用还未支持的语法
         */
        'vue/no-unsupported-features': 'off',
        /**
         * 禁止定义在 components 中的组件未使用
         */
        'vue/no-unused-components': 'error',
        /**
         * 模版中已定义的变量必须使用
         */
        'vue/no-unused-vars': 'error',
        /**
         * 禁止在同一个元素上使用 v-if 和 v-for 指令
         */
        'vue/no-use-v-if-with-v-for': 'error',
        /**
         * 禁止使用 v-html
         */
        'vue/no-v-html': 'off',
        /**
         * 组件的属性必须为一定的顺序
         */
        'vue/order-in-components': 'error',
        /**
         * <template> <script> <style> 之间必须由空行
         * @reason 代码格式问题,最好由 Prettier 解决
         */
        'vue/padding-line-between-blocks': 'off',
        /**
         * props 必须用驼峰式
         */
        'vue/prop-name-casing': 'off',
        /**
         * <component> 必须有绑定的组件
         */
        'vue/require-component-is': 'error',
        /**
         * props 如果不是 required 的字段,必须有默认值
         * @reason 类型相关的约束交给 TypeScript
         */
        'vue/require-default-prop': 'off',
        /**
         * 必须直接使用 export default 导出组件
         */
        'vue/require-direct-export': 'off',
        /**
         * 组件必须包含 name 属性
         */
        'vue/require-name-property': 'off',
        /**
         * props 的取值必须是基本类型的构造函数,而不是字符串
         * @reason 类型相关的约束交给 TypeScript
         */
        'vue/require-prop-type-constructor': 'off',
        /**
         * prop 必须有类型限制
         * @reason 类型相关的约束交给 TypeScript
         */
        'vue/require-prop-types': 'off',
        /**
         * render 函数必须有返回值
         */
        'vue/require-render-return': 'error',
        /**
         * v-for 指令的元素必须有 v-bind:key
         */
        'vue/require-v-for-key': 'error',
        /**
         * prop 的默认值必须匹配它的类型
         * @reason 类型相关的约束交给 TypeScript
         */
        'vue/require-valid-default-prop': 'off',
        /**
         * 计算属性必须有返回值
         */
        'vue/return-in-computed-property': 'error',
        /**
         * props 的键名必须排好序
         */
        'vue/sort-keys': 'off',
        /**
         * class 的值必须按字母排序
         */
        'vue/static-class-names-order': 'off',
        /**
         * 禁止在模版中用 this
         */
        'vue/this-in-template': 'error',
        /**
         * 当一个节点上出现两个 v-on:click 时,其中一个必须为 exact
         */
        'vue/use-v-on-exact': 'error',
        /**
         * 使用缩写的 : 而不是 v-bind:
         */
        'vue/v-bind-style': 'error',
        /**
         * 禁止在 v-on 的值中调用函数
         */
        'vue/v-on-function-call': 'error',
        /**
         * 使用缩写的 @click 而不是 v-on:click
         */
        'vue/v-on-style': 'error',
        /**
         * 使用缩写的 #one 而不是 v-slot:one
         */
        'vue/v-slot-style': 'off',
        /**
         * template 的根节点必须合法
         */
        'vue/valid-template-root': 'error',
        /**
         * v-bind 指令必须合法
         */
        'vue/valid-v-bind': 'error',
        /**
         * v-bind:foo.sync 指令必须合法
         */
        'vue/valid-v-bind-sync': 'error',
        /**
         * v-cloak 指令必须合法
         */
        'vue/valid-v-cloak': 'error',
        /**
         * v-else 指令必须合法
         */
        'vue/valid-v-else': 'error',
        /**
         * v-else-if 指令必须合法
         */
        'vue/valid-v-else-if': 'error',
        /**
         * v-for 指令必须合法
         */
        'vue/valid-v-for': 'error',
        /**
         * v-html 指令必须合法
         */
        'vue/valid-v-html': 'error',
        /**
         * v-if 指令必须合法
         */
        'vue/valid-v-if': 'error',
        /**
         * v-model 指令必须合法
         */
        'vue/valid-v-model': 'error',
        /**
         * v-on 指令必须合法
         */
        'vue/valid-v-on': 'error',
        /**
         * v-once 指令必须合法
         */
        'vue/valid-v-once': 'error',
        /**
         * v-pre 指令必须合法
         */
        'vue/valid-v-pre': 'error',
        /**
         * v-show 指令必须合法
         */
        'vue/valid-v-show': 'error',
        /**
         * v-slot 指令必须合法
         */
        'vue/valid-v-slot': 'error',
        /**
         * v-text 指令必须合法
         */
        'vue/valid-v-text': 'error'
    }
};

参考地址

  1. Code Guide
  2. 百度FEX-CSS规范
  3. javascript-style-guide
  4. eslint-config

results matching ""

    No results matching ""