个人整理前端开发规范+代码自动格式化

2,809 阅读30分钟

目录

1.命名规则

1-1 项目命名

 全部采用小写方式,已连字符分隔

 例:my-project-name

1-2 目录命名

 同项目命名一致

 有复数结构,采用复数命名

 例:compnents,images,data-models

1-3 JS文件命名

 同项目命名一致

 例:account-model.js

1-4 CSS,SCSS等文件命名

 同项目名一致

 例:retina-sprites.scss

1-5 HTML文件命名

 同项目名一致

 例:error-report.html

2.HTML

2-1 语法

 。缩进使用soft tab -- 两个空格

 。嵌套节点应该缩进

 。属性上使用双引号 不要使用单引号

     例:<h1 class="hello-word">

 。属性名全小写,用连字符多分隔符

     例:<h1 class="hello-word">

 。所有标签必须有关闭动作

     例:<img />

 。 不允许使用行内样式,全部采用class 代替

     例: <div style="width:100px"/>

3.CSS,SCSS,Less

不允许使用纯Css,或stylus 原因:css 容易造成样式冲突,styleslint 不支持stylus 格式化

  • 缩进使用 soft tab(两个空格)

3-2 分号

  • 每个属性后必须要加分号
.element {
  height: 100px;
}

3-3 空格

  • 冒号前不用,冒号后用
/*允许*/
.nav-header {
  width: 400px;
}
/*不允许*/
.nav-header {
  width :400px;
}
  • 类名后用
.nav-header {
  width: 400px;
}
  • 间隔符前后用

, > + ~都是间隔符, !important作为整体,在前用

.nav-header > .title {
  width: 400px !important;
}

3-4 空行

  • }后跟一个空行
.element {
  ...
}

.dialog {
  ...
}

3-5 换行

  • {前不换行,后换行
  • }前换行
/* not good */
.element
{color: red; background-color: black;}

/* good */
.element {
    color: red;
    background-color: black;
}

3-6 注释

除插件 koroFileHeader 注释外,行内注释使用 // ,其他统一使用 /* */这种注释

3-7 引号

统一使用双引号

3-8 命名

  • 使用小写单词
  • 多个单词间使用中划线 -
  • 不允许出现无意义字母命名,如 a b c

3-9 属性声明顺序

  • 相关的属性声明按右边的顺序做分组处理,组之间需要有一个空行。
.declaration-order {
  display: block;
  float: right;

  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 100;

  border: 1px solid #e5e5e5;
  border-radius: 3px;
  width: 100px;
  height: 100px;

  font: normal 13px "Helvetica Neue", sans-serif;
  line-height: 1.5;
  text-align: center;
  
  color: #333;
  background-color: #f5f5f5;

  opacity: 1;
}

3-10 颜色

  • 颜色16进制用小写字母;

  • 颜色16进制尽量用简写。

3-11 属性简写

除margin和padding外的属性避免使用简写

/* not good */
.element {
    transition: opacity 1s linear 2s;
}

/* good */
.element {
    transition-delay: 2s;
    transition-timing-function: linear;
    transition-duration: 1s;
    transition-property: opacity;
}

3-12 媒体查询

  • 尽量将媒体查询的规则靠近与他们相关的规则,不要将他们一起放到一个独立的样式文件中,或者丢在文档的最底部,这样做只会让大家以后更容易忘记他们。
.element {
    ...
}

.element-avatar{
    ...
}

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

    .element-avatar {
        ...
    }
}

3-13 SCSS相关

提交的代码中不要有 @debug

声明顺序:

  • @extend
  • 不包含 @content@include
  • 包含 @content@include
  • 自身属性
  • 嵌套规则

@import 引入的文件不需要开头的'_'和结尾的'.scss';

嵌套最多不能超过5层;

@extend 中使用placeholder选择器;

去掉不必要的父级引用符号'&'。

/* not good */
@import "_dialog.scss";

/* good */
@import "dialog";

/* not good */
.fatal {
    @extend .error;
}

/* good */
.fatal {
    @extend %error;
}

/* not good */
.element {
    & > .dialog {
        ...
    }
}

/* good */
.element {
    > .dialog {
        ...
    }
}

3-14 杂项

  • 定义公用组件时,样式不允许使用 !important

4.JavaScript

4-1 缩进

 使用soft tab - 两个空格

4-2 单行长度

 不能超过80,eslint 自动检测

4-3 分号

 以下几种需要分号

   例:变量 、表达式,return,throw,break

4-4 空行

以下几种情况需要空行,eslint 会自动添加空行,不必关注

。变量声明后

。注释前

。代码块后

4-5 换行

 换行地方,行末必须有 ‘,’  或者运算符 ;

4-6 单行注释

双斜杠后必须跟一个空格,缩进与下一段代码保持一致

if (condition) {

   // if you made it here

   allowed();

}

let zhangsan = "zhangsan"; // on space after code

4-7 多行注释

最少三行 ,* 后跟一个空格

使用场景:难于理解代码 、可能存在错误代码,业务逻辑强的代码 必须添加注释

例:

 /*

  *  one space after ....

 */

 let x = 1;

4-8 文档注释

必须使用多行注释

4-9 引号

 eslint 会自动添加,不必关注

4-10 变量声明

  • 命名方式:小驼峰

  • 命名规范:前缀名词

  • 命名建议:语义化

    变量声明要根据上下文环境语义化声明,不能使用无任何语义的关键词或者数字来表示变量

    除了一些约定俗成的简写,正常情况下尽量不使用简写声明变量

    需要做到看到变量名称,就知道这个变量是用来做什么的

    例:
        // bad
        let setCount = 10
        let input1 = document.querySelector('#username')
        let isUserActive = true

        // good
        let maxCount = 10
        let inputUser = document.querySelector('#username')
        let userActive = true

4-11 常量声明

  • 使用大写字母和下划线来组合命名,下划线用以分割单词

        例:
            const MAX_COUNT = 10
            const API_ROOT = 'http://www.baidu.com'
    

4-12 underfined

禁止使用underfined 作为变量判断条件,推荐使用typeOf,或字符串“underfined”进行判断

例:

 bad    if (persion === underfined) {}   good  if (typeOf persion === "underfined") {}

4.13 eslint相关

4.13.1 no-alert

禁止使用alert confirm prompt

JavaScript的alertconfirmprompt功能被广泛认为是刺耳的UI元素,应该由更适合的定制UI实现替换。此外,alert经常在调试代码时使用,在部署到生产之前应该将其删除。

alert("here!");
规则细节

此规则旨在捕获应该删除的调试代码,并弹出应该用不那么突兀的自定义用户界面替换的UI元素。因此,当它遇到它会发出警告alertprompt以及confirm未阴影函数调用。

此规则的错误代码示例:

/*eslint no-alert: "error"*/

alert("here!");

confirm("Are you sure?");

prompt("What's your name?", "John Doe");

此规则的正确代码示例:

/*eslint no-alert: "error"*/

customAlert("Something happened!");

customConfirm("Are you sure?");

customPrompt("Who are you?");

function foo() {
    var alert = myCustomLib.customAlert;
    alert();
}
4.13.2 no-class-assign

禁止给类赋值

"extends": "eslint:recommended"配置文件中的属性启用此规则。

ClassDeclaration 创建一个变量,我们可以修改该变量。

/*eslint-env es6*/

class A { }
A = 0;

但是修改在大多数情况下是一个错误。

规则细节

该规则旨在标记修改类声明的变量。

此规则的错误代码示例:

/*eslint no-class-assign: "error"*/
/*eslint-env es6*/

class A { }
A = 0;
/*eslint no-class-assign: "error"*/
/*eslint-env es6*/

A = 0;
class A { }
/*eslint no-class-assign: "error"*/
/*eslint-env es6*/

class A {
    b() {
        A = 0;
    }
}
/*eslint no-class-assign: "error"*/
/*eslint-env es6*/

let A = class A {
    b() {
        A = 0;
        // `let A` is shadowed by the class name.
    }
}

此规则的正确代码示例:

/*eslint no-class-assign: "error"*/
/*eslint-env es6*/

let A = class A { }
A = 0; // A is a variable.
/*eslint no-class-assign: "error"*/
/*eslint-env es6*/

let A = class {
    b() {
        A = 0; // A is a variable.
    }
}
/*eslint no-class-assign: 2*/
/*eslint-env es6*/

class A {
    b(A) {
        A = 0; // A is a parameter.
    }
}
4.13.3 no-cond-assign

禁止在条件表达式中使用赋值语句

配置文件中的"extends": "eslint:recommended"属性启用此规则。

在条件语句中,将比较运算符(如==)作为赋值运算符(例如=)输错是非常容易的。例如:

// Check the user's job title
if (user.jobTitle = "manager") {
    // user.jobTitle is now incorrect
}

在条件语句中使用赋值运算符是有正当理由的。但是,可能很难判断具体的任务是否是故意的。

规则细节

这条规则不允许在试验条件不明确赋值运算符ifforwhile,和do...while语句。

4.13.4 no-console

禁止使用console

"extends": "eslint:recommended"配置文件中的属性启用此规则。

在设计为在浏览器中执行的JavaScript中,避免使用方法被认为是最佳做法console。这些消息被认为是用于调试目的,因此不适合发送给客户端。一般来说,使用电话console在被推送到生产之前应该被剥离。

console.log("Made it here.");
console.error("That shouldn't have happened.");
规则细节

此规则禁止调用console对象的方法。

此规则的错误代码示例:

/*eslint no-console: "error"*/

console.log("Log a debug level message.");
console.warn("Log a warn level message.");
console.error("Log an error level message.");

此规则的正确代码示例:

/*eslint no-console: "error"*/

// custom console
Console.log("Hello world!");
选项

该规则有一个例外的对象选项:

  • "allow"有一个允许console对象的方法的字符串数组

带有示例选项的此规则的其他正确代码示例{ "allow": ["warn", "error"] }

/*eslint no-console: ["error", { allow: ["warn", "error"] }] */

console.warn("Log a warn level message.");
console.error("Log an error level message.");
何时不使用它

但是,如果您使用的是Node.js,console则用于向用户输出信息,因此不会严格用于调试目的。如果您正在开发Node.js,那么您很可能不希望启用此规则。

另一种可能不使用此规则的情况是,如果您想强制进行控制台调用而不是控制台覆盖。例如:

/*eslint no-console: ["error", { allow: ["warn"] }] */
console.error = function (message) {
  throw new Error(message);
};

根据no-console上述示例中的规则,ESLint将报告一个错误。对于上述示例,您可以禁用该规则:

// eslint-disable-next-line no-console
console.error = function (message) {
  throw new Error(message);
};

// or

console.error = function (message) {  // eslint-disable-line no-console
  throw new Error(message);
};

但是,您可能不想手动添加eslint-disable-next-lineeslint-disable-line。您可以通过以下no-restricted-syntax规则达到只接收控制台调用错误的效果:

{
    "rules": {
        "no-restricted-syntax": [
            "error",
            {
                "selector": "CallExpression[callee.object.name='console'][callee.property.name=/^(log|warn|error|info|trace)$/]",
                "message": "Unexpected property on console object was called"
            }
        ]
    }
}
4.13.5 no-const-assign

禁止修改const声明的变量

配置文件中的"extends": "eslint:recommended"属性启用此规则。

我们不能修改使用const关键字声明的变量。它会引发运行时错误。

在非 ES2015环境下,它可能仅仅被忽略。

规则细节

此规则旨在标记修改使用const关键字声明的变量。

此规则的错误代码示例:

/*eslint no-const-assign: "error"*/
/*eslint-env es6*/

const a = 0;
a = 1;
/*eslint no-const-assign: "error"*/
/*eslint-env es6*/

const a = 0;
a += 1;
/*eslint no-const-assign: "error"*/
/*eslint-env es6*/

const a = 0;
++a;

此规则的正确代码示例:

/*eslint no-const-assign: "error"*/
/*eslint-env es6*/

const a = 0;
console.log(a);
/*eslint no-const-assign: "error"*/
/*eslint-env es6*/

for (const a in [1, 2, 3]) { // `a` is re-defined (not modified) on each loop step.
    console.log(a);
}
/*eslint no-const-assign: "error"*/
/*eslint-env es6*/

for (const a of [1, 2, 3]) { // `a` is re-defined (not modified) on each loop step.
    console.log(a);
}
何时不使用它

如果您不希望收到有关修改使用const关键字声明的变量的通知,则可以安全地禁用此规则。

4.13.6 no-constant-condition

禁止在条件中使用常量表达式 if(true) if(1)

配置文件中的"extends": "eslint:recommended"属性启用此规则。

作为测试条件的常量表达式(例如,文字)可能是特定行为的拼写错误或开发触发器。例如,以下代码看起来好像尚未准备好进行生产。

if (false) {
    doSomethingUnfinished();
}
规则细节

此规则在下列测试条件中不允许使用常量表达式:

  • ifforwhile,或do...while语句

  • ?: 三元表达

此规则的错误代码示例:

/*eslint no-constant-condition: "error"*/

if (false) {
    doSomethingUnfinished();
}

if (void x) {
    doSomethingUnfinished();
}

for (;-2;) {
    doSomethingForever();
}

while (typeof x) {
    doSomethingForever();
}

do {
    doSomethingForever();
} while (x = -1);

var result = 0 ? a : b;

此规则的正确代码示例:

/*eslint no-constant-condition: "error"*/

if (x === 0) {
    doSomething();
}

for (;;) {
    doSomethingForever();
}

while (typeof x === "undefined") {
    doSomething();
}

do {
    doSomething();
} while (x);

var result = x !== 0 ? a : b;
选项

checkLoops

默认设置为true。设置此选项false允许循环中的常量表达式。

正确代码的例子,当checkLoopsfalse

4.13.7 no-debugger

禁止使用debugger

配置文件中的"extends": "eslint:recommended"属性启用此规则。

在命令行上的--fix选项可以自动修复一些被这条规则反映的问题。

debugger语句用于通知执行的 JavaScript 环境停止执行,并在代码中的当前位置启动调试器。随着现代调试和开发工具的出现,这已经失宠。生产代码绝对不应该包含debugger,因为它会导致浏览器停止执行代码并打开适当的调试器。

规则细节

此规则不允许debugger声明。

此规则的错误代码示例:

/*eslint no-debugger: "error"*/

function isTruthy(x) {
    debugger;
    return Boolean(x);
}

此规则的正确代码示例:

/*eslint no-debugger: "error"*/

function isTruthy(x) {
    return Boolean(x); // set a breakpoint at this line
}
何时不使用它

如果您的代码仍处于开发阶段,并且不想担心会剥离debugger语句,请关闭此规则。在部署之前测试代码时,您通常会希望将其重新打开。

4.13.8 no-dupe-keys

在创建对象字面量时不允许键重复 {a:1,a:1}

配置文件中的"extends": "eslint:recommended"属性启用此规则。

对象文字中具有相同键的多个属性可能会导致应用程序出现意外行为。

var foo = {
    bar: "baz",
    bar: "qux"
};
规则细节

此规则不允许在对象文字中使用重复键。

此规则的错误代码示例:

/*eslint no-dupe-keys: "error"*/

var foo = {
    bar: "baz",
    bar: "qux"
};

var foo = {
    "bar": "baz",
    bar: "qux"
};

var foo = {
    0x1: "baz",
    1: "qux"
};

此规则的正确代码示例:

/*eslint no-dupe-keys: "error"*/

var foo = {
    bar: "baz",
    quxx: "qux"
};
4.13.9 no-dupe-args

函数参数不能重复

配置文件中的"extends": "eslint:recommended"属性启用此规则。

如果在一个函数定义中有多个参数具有相同的名称,则最后一个匹配项会“遮蔽”前面的匹配项。重复的名称可能是打字错误。

规则细节

此规则不允许在函数声明或表达式中使用重复的参数名称。它不适用于箭头函数或类方法,因为解析器报告错误。

如果 ESLint 在严格模式下解析代码,解析器(而不是此规则)会报告错误。

此规则的错误代码示例:

/*eslint no-dupe-args: "error"*/

function foo(a, b, a) {
    console.log("value of the second a:", a);
}

var bar = function (a, b, a) {
    console.log("value of the second a:", a);
};

此规则的正确代码示例:

/*eslint no-dupe-args: "error"*/

function foo(a, b, c) {
    console.log(a, b, c);
}

var bar = function (a, b, c) {
    console.log(a, b, c);
};
4.13.10 no-duplicate-case

switch中的case标签不能重复

配置文件中的"extends": "eslint:recommended"属性启用此规则。

如果一个switch语句在case子句中有重复的测试表达式,程序员可能会复制一个case子句,但忘记更改测试表达式。

规则细节

此规则不允许在switch语句的case子句中使用重复的测试表达式。

此规则的错误代码示例:

/*eslint no-duplicate-case: "error"*/

var a = 1,
    one = 1;

switch (a) {
    case 1:
        break;
    case 2:
        break;
    case 1:         // duplicate test expression
        break;
    default:
        break;
}

switch (a) {
    case one:
        break;
    case 2:
        break;
    case one:         // duplicate test expression
        break;
    default:
        break;
}

switch (a) {
    case "1":
        break;
    case "2":
        break;
    case "1":         // duplicate test expression
        break;
    default:
        break;
}

此规则的正确代码示例:

/*eslint no-duplicate-case: "error"*/

var a = 1,
    one = 1;

switch (a) {
    case 1:
        break;
    case 2:
        break;
    case 3:
        break;
    default:
        break;
}

switch (a) {
    case one:
        break;
    case 2:
        break;
    case 3:
        break;
    default:
        break;
}

switch (a) {
    case "1":
        break;
    case "2":
        break;
    case "3":
        break;
    default:
        break;
}
4.13.11 no-else-return

如果if语句里面有return,后面不能跟else语句

在命令行上的--fix选项可以自动修复一些被这条规则反映的问题。

如果一个if块包含一个return语句,else块就变得不必要了。它的内容可以放在块的外面。

function foo() {
    if (x) {
        return y;
    } else {
        return z;
    }
}
规则细节

此规则旨在突出显示if包含 return 语句后的不必要代码块。因此,当它遇到else一连串的ifs 时,它会发出警告,所有这些都包含一个return声明。

选项

该规则有一个对象选项:

{
    "no-else-return": ["error", { "allowElseIf": true }],
    // or
    "no-else-return": ["error", { "allowElseIf": false }]
}
  • allowElseIf: true(默认)允许返回后的else if

  • allowElseIf: false禁止返回后的else if

allowElseIf: true

此规则的错误代码示例:

/*eslint no-else-return: "error"*/

function foo() {
    if (x) {
        return y;
    } else {
        return z;
    }
}

function foo() {
    if (x) {
        return y;
    } else if (z) {
        return w;
    } else {
        return t;
    }
}

function foo() {
    if (x) {
        return y;
    } else {
        var t = "foo";
    }

    return t;
}

function foo() {
    if (error) {
        return 'It failed';
    } else {
        if (loading) {
            return "It's still loading";
        }
    }
}

// Two warnings for nested occurrences
function foo() {
    if (x) {
        if (y) {
            return y;
        } else {
            return x;
        }
    } else {
        return z;
    }
}

此规则的正确代码示例:

/*eslint no-else-return: "error"*/

function foo() {
    if (x) {
        return y;
    }

    return z;
}

function foo() {
    if (x) {
        return y;
    } else if (z) {
        var t = "foo";
    } else {
        return w;
    }
}

function foo() {
    if (x) {
        if (z) {
            return y;
        }
    } else {
        return z;
    }
}

function foo() {
    if (error) {
        return 'It failed';
    } else if (loading) {
        return "It's still loading";
    }
}

allowElseIf: false

此规则的错误代码示例:

/*eslint no-else-return: ["error", {allowElseIf: false}]*/

function foo() {
    if (error) {
        return 'It failed';
    } else if (loading) {
        return "It's still loading";
    }
}

此规则的正确代码示例:

/*eslint no-else-return: ["error", {allowElseIf: false}]*/

function foo() {
    if (error) {
        return 'It failed';
    }

    if (loading) {
        return "It's still loading";
    }
}
4.13.12 no-empty

块语句中的内容不能为空

"extends": "eslint:recommended"配置文件中的属性启用此规则。

空块语句虽然不是技术上的错误,但通常是由于未完成的重构而发生的。阅读代码时会造成混淆。

规则细节

该规则不允许空块语句。 该规则忽略包含注释的块语句(例如,在一个空catch或最后一个try语句块中,以指示无论错误如何,执行都应该继续)。

此规则的错误代码示例:

/*eslint no-empty: "error"*/

if (foo) {
}

while (foo) {
}

switch(foo) {
}

try {
    doSomething();
} catch(ex) {

} finally {

}

此规则的正确代码示例:

/*eslint no-empty: "error"*/

if (foo) {
    // empty
}

while (foo) {
    /* empty */
}

try {
    doSomething();
} catch (ex) {
    // continue regardless of error
}

try {
    doSomething();
} finally {
    /* continue regardless of error */
}
选项

该规则有一个例外的对象选项:

  • "allowEmptyCatch": true允许空catch子句(即不包含注释)

allowEmptyCatch

此规则的附加正确代码示例包含以下{ "allowEmptyCatch": true }选项:

/* eslint no-empty: ["error", { "allowEmptyCatch": true }] */
try {
    doSomething();
} catch (ex) {}

try {
    doSomething();
}
catch (ex) {}
finally {
    /* continue regardless of error */
}
何时不使用它

如果您有意使用空块语句,则可以禁用此规则。

4.13.13 no-eq-null

禁止对null使用==或!=运算符

null没有类型检查运算符(==!=)的情况相比,可能会产生意想不到的结果,因为比较结果不仅仅是null一个undefined值,而是一个值。

if (foo == null) {
  bar();
}
规则细节

no-eq-null规则旨在通过确保比较null仅匹配null而不是另外来减少潜在的错误和不需要的行为undefined。因此,使用==和时它会将比较标记为空!=

此规则的错误代码示例:

/*eslint no-eq-null: "error"*/

if (foo == null) {
  bar();
}

while (qux != null) {
  baz();
}

此规则的正确代码示例:

/*eslint no-eq-null: "error"*/

if (foo === null) {
  bar();
}

while (qux !== null) {
  baz();
}
4.13.14 no-eval

禁止使用eval

JavaScript的eval()功能是潜在的危险,经常被滥用。eval()在不受信任的代码上使用可以打开一个程序,最多可以进行多种不同的注入攻击 eval()在大多数情况下的使用可以取代对问题更好的替代方法。

var obj = { x: "foo" },
    key = "x",
    value = eval("obj." + key);
规则细节

该规则旨在通过禁止使用eval()函数来防止潜在的危险,不必要的和慢速的代码。因此,无论何时使用该eval()功能,它都会发出警告。

此规则的错误代码示例:

/*eslint no-eval: "error"*/

var obj = { x: "foo" },
    key = "x",
    value = eval("obj." + key);

(0, eval)("var a = 0");

var foo = eval;
foo("var a = 0");

// This `this` is the global object.
this.eval("var a = 0");

浏览器环境设置为true时,此规则的其他不正确代码示例:

/*eslint no-eval: "error"*/
/*eslint-env browser*/

window.eval("var a = 0");

当节点环境设置为true时,此规则的附加不正确代码示例:

/*eslint no-eval: "error"*/
/*eslint-env node*/

global.eval("var a = 0");

此规则的正确代码示例:

/*eslint no-eval: "error"*/
/*eslint-env es6*/

var obj = { x: "foo" },
    key = "x",
    value = obj[key];

class A {
    foo() {
        // This is a user-defined method.
        this.eval("var a = 0");
    }

    eval() {
    }
}
选项

此规则有一个允许间接调用eval的选项。 间接调用eval比直接调用eval更不危险,因为它们不能动态更改范围。 正因为如此,它们也不会对性能造成直接影响。

{
    "no-eval": ["error", {"allowIndirect": true}] // default is false
}

此规则的错误代码示例包含以下{"allowIndirect": true}选项:

/*eslint no-eval: "error"*/

var obj = { x: "foo" },
    key = "x",
    value = eval("obj." + key);

此规则的正确代码示例包含以下{"allowIndirect": true}选项:

/*eslint no-eval: "error"*/

(0, eval)("var a = 0");

var foo = eval;
foo("var a = 0");

this.eval("var a = 0");
/*eslint no-eval: "error"*/
/*eslint-env browser*/

window.eval("var a = 0");
/*eslint no-eval: "error"*/
/*eslint-env node*/

global.eval("var a = 0");
已知限制
  • 即使eval不是全局的,该规则也会警告每个eval()。 此行为是为了检测直接评估的调用。 如:module.exports = function(eval){//如果这个eval的值是内置的eval函数,这是//直接eval的调用。 eval(“var a = 0”);};
  • 此规则无法捕获重命名全局对象。 如:var foo = window; foo.eval(“var a = 0”);
4.13.15 no-ex-assign

禁止给catch语句中的异常参数赋值

"extends": "eslint:recommended"配置文件中的属性启用此规则。

如果catch语句中的某个子句try意外(或故意)将另一个值分配给异常参数,则不可能引用该错误。由于没有任何arguments对象可以提供对这些数据的替代访问权限,因此赋值参数是绝对有破坏性的。

规则细节

此规则不允许在catch子句中重新分配例外。

此规则的错误代码示例:

/*eslint no-ex-assign: "error"*/

try {
    // code
} catch (e) {
    e = 10;
}
4.13.16 no-extend-native

禁止扩展native对象

在 JavaScript 中,您可以扩展任何对象,包括内置或“本机”对象。有时候人们会改变这些本地对象的行为,破坏代码中其他部分的假设。

例如,在这里我们覆盖了一个内建的方法,它会影响所有的对象,甚至是其他的内建对象。

// seems harmless
Object.prototype.extra = 55;

// loop through some userIds
var users = {
    "123": "Stan",
    "456": "David"
};

// not what you'd expect
for (var id in users) {
    console.log(id); // "123", "456", "extra"
}

避免这个问题的常见建议是将for循环内部包裹起来users.hasOwnProperty(id)。但是,如果此规则在您的代码库中严格执行,则无需采取这一步骤。

规则细节

不允许直接修改内建对象的原型。

此规则的错误代码示例:

/*eslint no-extend-native: "error"*/

Object.prototype.a = "a";
Object.defineProperty(Array.prototype, "times", { value: 999 });
选项

该规则接受一个exceptions选项,该选项可用于指定允许扩展名的内建列表。

异常

示例选项的正确代码示例{ "exceptions": ["Object"] }

/*eslint no-extend-native: ["error", { "exceptions": ["Object"] }]*/

Object.prototype.a = "a";
已知限制

此规则报告任何以下不太明显的方法来修改内置对象的原型

5.编辑器配置和构建检查

统一编辑器 ,一下规范目前仅支持vs vode,后面优化支持webstrom,一下配置更改,请重启编辑器窗口以免造成配置失效

5-1 依赖安装

(以下依赖推荐全安装) 卸载依赖或安装依赖建议重新启动窗口

// 必须安装
ESLint Dirk (Baeumer8)
Prettier - Code formatter (Esben Petersen)
Vetur (Pine Wu)
stylelint (stylelint )
// 推荐安装


// stylus 依赖 (不要安装,除非你使用stylus)
stylus (AlanCezarAraujo)
language-stylus (sysoev)
Manta's Stylus Supremacy (Anantachai Saothong)

// scss 依赖
SCSS Style Tag (nikoc)
SCSS IntelliSense (mrmlnc)
Sass (Syler)

// git 依赖
Git History (Don Jayamanne)
GitLens — Git supercharged (Eric Amodio)

// html 依赖
Auto Close Tag (Jun Han)
Auto Rename Tag (Jun Han)
HTML Snippets  (Mohamed Abusaid)
HTML CSS Support (ecmel)
open in browser (TechER)
Path Autocomplete (Mihai Vilcu)
Path Intellisense (Christian Kohler)

// js 依赖
JavaScript (ES6) code snippets  (charalampos karypidis)
Debugger for Chrome (Microsoft4)
lodash (oysun)

// 其他 依赖
Chinese (Simplified) Language Pack for Visual Studio Code (Microsoft4)
koroFileHeader (OBKoro1)
vscode-icons (VSCode Icons Team)
markdownlint (David Anson)
Docker (Microsoft4)

5-2 编辑器配置

文件 --> 首选项 --> 设置 --> setting.json

{
  // vscode默认启用了根据文件类型自动设置tabsize的选项
  "editor.detectIndentation": false,
  // 重新设定tabsize
  "editor.tabSize": 2,
  // #每次保存的时候自动格式化 
  "editor.formatOnSave": true,
  // #每次保存的时候将代码按eslint格式进行修复
  "eslint.autoFixOnSave": true,
  // 添加 vue 支持
  "eslint.validate": [
    "javascript",
    "javascriptreact",
    "html",
    {
      "language": "vue",
      "autoFix": true
    }
  ],
  /*  #使用带引号替代双引号  */
  "prettier.singleQuote": true,
  //  #让函数(名)和后面的括号之间加个空格
  "javascript.format.insertSpaceBeforeFunctionParenthesis": true,
  // 样式配置
  "stylusSupremacy.insertColons": false, // 是否插入冒号
  "stylusSupremacy.insertSemicolons": false, // 是否插入分好
  "stylusSupremacy.insertBraces": false, // 是否插入大括号
  "stylusSupremacy.insertNewLineAroundBlocks": false,
  "css.validate": false,
  "less.validate": false,
  "scss.validate": true,
  "prettier.tabWidth": 2,
  /* 其他系统配置 */
  "workbench.iconTheme": "vscode-icons",
  "explorer.confirmDelete": false,
  "search.followSymlinks": false,
  "git.enableSmartCommit": true,
  "vsicons.dontShowNewVersionMessage": true,
  "git.autofetch": true,
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true
  },
  /*  默认控制台cmd */
  "terminal.integrated.shell.windows": "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
  "files.autoSave": "off",
  "[vue]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  /* 自动注释配置 */
  "fileheader.customMade": { //此为头部注释
    "Description": "",
    "Version": "2.0",
    "Autor": "wuwei3",
    "Date": "Do not edit",
    "LastEditors": "",
    "LastEditTime": "Do not edit"
  },
  "fileheader.cursorMode": { //此为函数注释
    "description": "",
    "param": "",
    "return": "",
  },
  /* gitlent 配置 */
  "gitlens.advanced.messages": {
    "suppressCommitHasNoPreviousCommitWarning": true,
    "suppressCommitNotFoundWarning": true,
    "suppressFileNotUnderSourceControlWarning": true,
    "suppressGitVersionWarning": true,
    "suppressLineUncommittedWarning": true,
    "suppressNoRepositoryWarning": true,
    "suppressResultsExplorerNotice": true,
    "suppressShowKeyBindingsNotice": true
  },
  "workbench.startupEditor": "newUntitledFile",
  "git.confirmSync": false,
}

5-3 项目配置

eslint 配置

根目录添加eslint 文件 如需动态修改请查看中文官网 cn.eslint.org/docs/rules/

  • 没有可以新建:.eslintignore 自定义添加忽略格式化文件

    /build/
    /config/
    /dist/
    /*.js
    
  • 没有可以新建:.eslintrc.js 自定义格式化规则 (待优化中)

    module.exports = {
      env: {
        // Environments,指定代码的运行环境。不同的运行环境,全局变量不一样,指明运行环境这样ESLint就能识别特定的全局变量。同时也会开启对应环境的语法支持,例如:es6。
        browser: true,
        es6: true,
        node: true
      },
      extends: ['eslint:recommended', 'plugin:vue/essential'],
      globals: {
        Atomics: 'readonly',
        SharedArrayBuffer: 'readonly'
      },
      parserOptions: {
        ecmaVersion: 2018,
        sourceType: 'module',
        parser: 'babel-eslint'
      },
      plugins: ['vue'],
      rules: {
        'no-alert': 2, //禁止使用alert confirm prompt
        'no-array-constructor': 2, //禁止使用数组构造器
        'no-bitwise': 0, //禁止使用按位运算符
        'no-caller': 1, //禁止使用arguments.caller或arguments.callee
        'no-catch-shadow': 2, //禁止catch子句参数与外部作用域变量同名
        'no-class-assign': 2, //禁止给类赋值
        'no-cond-assign': 2, //禁止在条件表达式中使用赋值语句
        'no-console': 0, //禁止使用console
        'no-const-assign': 2, //禁止修改const声明的变量
        'no-constant-condition': 2, //禁止在条件中使用常量表达式 if(true) if(1)
        'no-continue': 0, //禁止使用continue
        'no-control-regex': 2, //禁止在正则表达式中使用控制字符
        'no-debugger': 0, //禁止使用debugger
        'no-delete-var': 2, //不能对var声明的变量使用delete操作符
        'no-div-regex': 1, //不能使用看起来像除法的正则表达式/=foo/
        'no-dupe-keys': 2, //在创建对象字面量时不允许键重复 {a:1,a:1}
        'no-dupe-args': 2, //函数参数不能重复
        'no-duplicate-case': 2, //switch中的case标签不能重复
        'no-else-return': 2, //如果if语句里面有return,后面不能跟else语句
        'no-empty': 2, //块语句中的内容不能为空
        'no-empty-character-class': 2, //正则表达式中的[]内容不能为空
        'no-eq-null': 2, //禁止对null使用==或!=运算符
        'no-eval': 1, //禁止使用eval
        'no-ex-assign': 2, //禁止给catch语句中的异常参数赋值
        'no-extend-native': 2, //禁止扩展native对象
        'no-extra-bind': 2, //禁止不必要的函数绑定
        'no-extra-boolean-cast': 2, //禁止不必要的bool转换
        'no-extra-parens': 0, //禁止非必要的括号
        'no-extra-semi': 2, //禁止多余的冒号
        'no-fallthrough': 1, //禁止switch穿透
        'no-floating-decimal': 2, //禁止省略浮点数中的0 .5 3.
        'no-func-assign': 2, //禁止重复的函数声明
        'no-implicit-coercion': 1, //禁止隐式转换
        'no-implied-eval': 2, //禁止使用隐式eval
        'no-inline-comments': 0, //禁止行内备注
        'no-inner-declarations': [2, 'functions'], //禁止在块语句中使用声明(变量或函数)
        'no-invalid-regexp': 2, //禁止无效的正则表达式
        'no-invalid-this': 2, //禁止无效的this,只能用在构造器,类,对象字面量
        'no-irregular-whitespace': 0, //不能有不规则的空格
        'no-iterator': 2, //禁止使用__iterator__ 属性
        'no-label-var': 2, //label名不能与var声明的变量名相同
        'no-labels': 2, //禁止标签声明
        'no-lone-blocks': 2, //禁止不必要的嵌套块
        'no-lonely-if': 2, //禁止else语句内只有if语句
        'no-loop-func': 1, //禁止在循环中使用函数(如果没有引用外部变量不形成闭包就可以)
        'no-mixed-requires': [0, false], //声明时不能混用声明类型
        'no-mixed-spaces-and-tabs': [2, false], //禁止混用tab和空格
        'linebreak-style': [0, 'windows'], //换行风格
        'no-multi-spaces': 1, //不能用多余的空格
        'no-multi-str': 2, //字符串不能用\换行
        'no-multiple-empty-lines': [1, { max: 2 }], //空行最多不能超过2行
        'no-native-reassign': 2, //不能重写native对象
        'no-negated-in-lhs': 2, //in 操作符的左边不能有!
        'no-nested-ternary': 0, //禁止使用嵌套的三目运算
        'no-new': 1, //禁止在使用new构造一个实例后不赋值
        'no-new-func': 1, //禁止使用new Function
        'no-new-object': 2, //禁止使用new Object()
        'no-new-require': 2, //禁止使用new require
        'no-new-wrappers': 2, //禁止使用new创建包装实例,new String new Boolean new Number
        'no-obj-calls': 2, //不能调用内置的全局对象,比如Math() JSON()
        'no-octal': 2, //禁止使用八进制数字
        'no-octal-escape': 2, //禁止使用八进制转义序列
        'no-param-reassign': 2, //禁止给参数重新赋值
        'no-path-concat': 0, //node中不能使用__dirname或__filename做路径拼接
        'no-plusplus': 0, //禁止使用++,--
        'no-process-env': 0, //禁止使用process.env
        'no-process-exit': 0, //禁止使用process.exit()
        'no-proto': 2, //禁止使用__proto__属性
        'no-redeclare': 2, //禁止重复声明变量
        'no-regex-spaces': 2, //禁止在正则表达式字面量中使用多个空格 /foo bar/
        'no-restricted-modules': 0, //如果禁用了指定模块,使用就会报错
        'no-return-assign': 1, //return 语句中不能有赋值表达式
        'no-script-url': 0, //禁止使用javascript:void(0)
        'no-self-compare': 2, //不能比较自身
        'no-sequences': 0, //禁止使用逗号运算符
        'no-shadow': 2, //外部作用域中的变量不能与它所包含的作用域中的变量或参数同名
        'no-shadow-restricted-names': 2, //严格模式中规定的限制标识符不能作为声明时的变量名使用
        'no-spaced-func': 2, //函数调用时 函数名与()之间不能有空格
        'no-sparse-arrays': 2, //禁止稀疏数组, [1,,2]
        'no-sync': 0, //nodejs 禁止同步方法
        'no-ternary': 0, //禁止使用三目运算符
        'no-trailing-spaces': 1, //一行结束后面不要有空格
        'no-this-before-super': 0, //在调用super()之前不能使用this或super
        'no-throw-literal': 2, //禁止抛出字面量错误 throw "error";
        'no-undef': 0, //不能有未定义的变量
        'no-undef-init': 2, //变量初始化时不能直接给它赋值为undefined
        'no-undefined': 2, //不能使用undefined
        'no-unexpected-multiline': 2, //避免多行表达式
        'no-underscore-dangle': 0, //标识符不能以_开头或结尾
        'no-unneeded-ternary': 2, //禁止不必要的嵌套 var isYes = answer === 1 ? true : false;
        'no-unreachable': 2, //不能有无法执行的代码
        'no-unused-expressions': 0, //禁止无用的表达式
        'no-unused-vars': [2, { vars: 'all', args: 'after-used' }], //不能有声明后未被使用的变量或参数
        'no-use-before-define': 0, //未定义前不能使用
        'no-useless-call': 2, //禁止不必要的call和apply
        'no-void': 2, //禁用void操作符
        'no-var': 0, //禁用var,用let和const代替
        'no-warning-comments': [
          1,
          { terms: ['todo', 'fixme', 'xxx'], location: 'start' }
        ], //不能有警告备注
        'no-with': 2, //禁用with
        'array-bracket-spacing': [2, 'never'], //是否允许非空数组里面有多余的空格
        'arrow-parens': 0, //箭头函数用小括号括起来
        'arrow-spacing': 0, //=>的前/后括号
        'accessor-pairs': 0, //在对象中使用getter/setter
        'block-scoped-var': 0, //块语句中使用var
        'brace-style': [1, '1tbs'], //大括号风格
        'callback-return': 1, //避免多次调用回调什么的
        camelcase: 2, //强制驼峰法命名
        'comma-dangle': [0, 'never'], //对象字面量项尾不能有逗号
        'comma-spacing': 0, //逗号前后的空格
        'comma-style': [2, 'last'], //逗号风格,换行时在行首还是行尾
        complexity: [0, 11], //循环复杂度
        'computed-property-spacing': [0, 'never'], //是否允许计算后的键名什么的
        'consistent-return': 0, //return 后面是否允许省略
        'consistent-this': [2, 'that'], //this别名
        'constructor-super': 0, //非派生类不能调用super,派生类必须调用super
        curly: [2, 'all'], //必须使用 if(){} 中的{}
        'default-case': 2, //switch语句最后必须有default
        'dot-location': 0, //对象访问符的位置,换行的时候在行首还是行尾
        'dot-notation': [0, { allowKeywords: true }], //避免不必要的方括号
        'eol-last': 0, //文件以单一的换行符结束
        eqeqeq: 2, //必须使用全等
        'func-names': 0, //函数表达式必须有名字
        'func-style': [0, 'declaration'], //函数风格,规定只能使用函数声明/函数表达式
        'generator-star-spacing': 0, //生成器函数*的前后空格
        'guard-for-in': 0, //for in循环要用if语句过滤
        'handle-callback-err': 0, //nodejs 处理错误
        'id-length': 0, //变量名长度
        indent: 'off', // 缩进长度
        'init-declarations': 0, //声明时必须赋初值
        'key-spacing': [0, { beforeColon: false, afterColon: true }], //对象字面量中冒号的前后空格
        'lines-around-comment': 0, //行前/行后备注
        'max-depth': [0, 4], //嵌套块深度
        'max-len': [0, 80, 4], //字符串最大长度
        'max-nested-callbacks': [0, 2], //回调嵌套深度
        'max-params': [0, 3], //函数最多只能有3个参数
        'max-statements': [0, 10], //函数内最多有几个声明
        'new-cap': 0, //函数名首行大写必须使用new方式调用,首行小写必须用不带new方式调用
        'new-parens': 2, //new时必须加小括号
        'newline-after-var': 2, //变量声明后是否需要空一行
        'object-curly-spacing': [0, 'never'], //大括号内是否允许不必要的空格
        'object-shorthand': 0, //强制对象字面量缩写语法
        'one-var': 0, //连续声明
        'operator-assignment': [0, 'always'], //赋值运算符 += -=什么的
        'operator-linebreak': [0, 'after'], //换行时运算符在行尾还是行首
        'padded-blocks': 0, //块语句内行首行尾是否要空行
        'prefer-const': 0, //首选const
        'prefer-spread': 0, //首选展开运算
        'prefer-reflect': 0, //首选Reflect的方法
        quotes: [0, 'single'], //引号类型 `` "" ''
        'quote-props': [0, 'always'], //对象字面量中的属性名是否强制双引号
        radix: 2, //parseInt必须指定第二个参数
        'id-match': 0, //命名检测
        'require-yield': 0, //生成器函数必须有yield
        semi: [2, 'always'], //语句强制分号结尾
        'semi-spacing': [0, { before: false, after: true }], //分号前后空格
        'sort-vars': 0, //变量声明时排序
        'space-after-keywords': [0, 'always'], //关键字后面是否要空一格
        'space-before-blocks': [0, 'always'], //不以新行开始的块{前面要不要有空格
        'space-before-function-paren': [0, 'always'], //函数定义时括号前面要不要有空格
        'space-in-parens': [0, 'never'], //小括号里面要不要有空格
        'space-infix-ops': 0, //中缀操作符周围要不要有空格
        'space-unary-ops': [0, { words: true, nonwords: false }], //一元运算符的前/后要不要加空格
        'spaced-comment': 0, //注释风格要不要有空格什么的
        strict: 2, //使用严格模式
        'use-isnan': 2, //禁止比较时使用NaN,只能用isNaN()
        'valid-jsdoc': 0, //jsdoc规则
        'valid-typeof': 2, //必须使用合法的typeof的值
        'vars-on-top': 2, //var必须放在作用域顶部
        'wrap-iife': [2, 'inside'], //立即执行函数表达式的小括号风格
        'wrap-regex': 0, //正则表达式字面量用小括号包起来
        yoda: [2, 'never'] //禁止尤达条件
      }
    };
    
    
stylelint 配置

根目录添加stylelint文件 如需动态修改请查看中文官网 stylelint.io/

注意:stylelint 不支持stylus预处理器,其他都可以

  • 没有可以新建:.stylelintignore 自定义添加忽略格式化文件
// 项目根目录 例
src/assets/css/*.css
  • 没有可以新建:.stylelintrc.js 自定义格式化规则 (待优化中)

    module.exports = {
        extends: 'stylelint-config-standard',
        rules: {
            'rule-empty-line-before': 'never',
            'selector-list-comma-newline-after': 'never-multi-line',
            'string-quotes': 'single',
            indentation: 2,
            'selector-pseudo-element-colon-notation': 'single',
            'no-descending-specificity': null,
            'value-list-comma-newline-before': 'always-multi-line',
            'value-list-comma-space-after': 'always',
            'value-list-comma-space-before': 'never-single-line',
            'color-named': 'always-where-possible',
            'function-blacklist': ['/^rgb/', '/^hsl/', 'gray']
        }
    };
    
    

5-4 git 代码提交校验

务必安装,遇到提交不了,请查看日志并对照 eslint.bootcss.com/docs/rules/ 解决,不允许私自改动

.eslintrc 文件配置

例: 以下依赖都要安装 可以直接复制到 pack.json -- > devDependencies 然后npm i
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint",
    "lint:staged": "lint-staged"
  },
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged"
    }
  },
  "lint-staged": {
    "src/**/*.{jsx,txs,ts,js,vue}": [
      "eslint --fix",
      "stylelint --config  ./.stylelintrc --fix",
      "git add"
    ]
  },
  "pre-commit": "lint:staged",
  "devDependencies": {
      "husky": "^4.2.3",
      "lint-staged": "^10.0.8",
      "pre-commit": "^1.2.2",
      "stylelint": "^13.2.1",
      "stylelint-config-standard": "^20.0.0",
      "stylelint-order": "^4.0.0",
  }
  

5-4 无法格式化补充

如果无法格式化,请查看根目录pack.json是否有以下依赖,没有请安装

例: 以下依赖都要安装 可以直接复制到 pack.json -- > devDependencies 然后npm i
  "@vue/eslint-config-prettier": "^5.0.0",
    "babel-eslint": "^10.0.1",
    "eslint": "^5.16.0",
    "eslint-plugin-prettier": "^3.1.0",
    "eslint-plugin-vue": "^5.0.0",

vue 项目启动开启eslint 校验 推荐

修改vue.config.js,没有择新建
例:
    module.exports = {
      // eslint-loader 是否在保存的时候检查 开发环境报错,不影响线上环境
      lintOnSave: process.env.NODE_ENV !== 'production',
  }

6. 参考项目

git.iflytek.com/dashboard/p… 内置以上配置,没有权限请找耿良江/郭术愿。

谢谢