本文来自网易云社区
以前我们的项目编码风格一直比较混乱。前不久,我们在项目中使用了Babel,吃上了ES2015,顺便配上了ESLint。按照ESLint的rules,我们整理出一份自己的JavaScript代码规范。
配置
npminstall--save-dev eslint eslint-config-rgui
然后创建.eslintrc文件,内容如下:
{ "extends":"rgui", "env":{ "browser":true, "node":true}}
具体可以参考ESLint配置。
空白
要求使用4个空格作为缩进,禁止使用Tab。✎
indent,no-tabs,no-mixed-spaces-and-tabs
// ✗ badfunction(){console.log('Hello');}// ✗ badfunction(){——console.log('Hello');}// ✓ goodfunction(){console.log('Hello');}
强制使用Unix换行符\n,禁止使用Windows换行符\r\n✎
linebreak-style
禁止使用Unicode字节顺序标记(BOM)。✎
unicode-bom
要求文件末尾有且只有一个空行。✎
eol-last
// ✗ bad(function(global){// ...stuff...})(this);
// ✗ bad(function(global){// ...stuff...})(this);↵↵
// ✓ good(function(global){// ...stuff...})(this);↵
禁止连续出现多个空行。✎
no-multiple-empty-lines
// ✗ badconstvalue ='Hello';console.log(value);
// ✓ goodconstvalue ='Hello';console.log(value);
禁止块的内边缘出现空行。✎
padded-blocks
// ✗ badfunctionbar(){console.log(foo);}// ✓ goodfunctionbar(){console.log(foo);}
要求运行指令之后必须有一个空行。✎
lines-around-directive
// ✗ bad'use strict';letfoo;
// ✓ good'use strict';letfoo;
禁止行尾出现空格。✎
no-trailing-spaces
禁止连续出现多个空格。✎
no-multi-spaces
// ✗ badleta =1;if(foo ==='bar') {}a << bletarr = [1,2];a ? b: c;// ✓ goodleta =1;if(foo ==='bar') {}a << bletarr = [1,2];a ? b: c;
要求分号、逗号、冒号之后必须有一个空格。✎
semi-spacing,comma-spacing,key-spacing
// ✗ badconstarr = [1,2,3,4];constobj = { id:1,name:'Alice'};foo(a,b,c);for(leti =0;i <10;i++)// ✓ goodconstarr = [1,2];constobj = { id:1, name:'Alice'};foo(a, b, c);for(leti =0; i <10; i++)
禁止点号(属性、rest参数、扩展运算符)和单词之间有空格。✎
no-whitespace-before-property,rest-spread-spacing
// ✗ badfoo. bar. baz();fn(... args);[... arr,4,5,6];// ✓ goodfoo.bar.baz();fn(...args);[...arr,4,5,6];
要求一元运算符周围没有空格,等号、二元运算符、箭头符号周围有一个空格。✎
space-unary-ops,space-infix-ops,arrow-spacing
// ✗ badi ++;letx=-y*5;letmessage='Hello, '+name+'!';constfunc=(x)=>{};// ✓ goodi++;letx = -y *5;letmessage ='Hello, '+ name +'!';constfunc = (x) => {};
禁止在小括号(表达式、函数)和中括号(数组、属性)内边缘加空格,要求在大括号(对象、单行代码块)内边缘加一个空格。✎
space-in-parens,array-bracket-spacing,computed-property-spacing,object-curly-spacing,block-spacing
// ✗ badconstnum =3* (2+5);functionhello( name ){console.log('Hi,', name );}if( test ) { thing();}// ✓ goodconstnum =3* (2+5);functionhello(name){console.log('Hi,', name);}if(test) { thing();}// ✗ badconstarr = [1,2,3];const[ x, y ] = z;obj[ key ] ='test';user['name'] ='John';// ✓ goodconstarr = [1,2,3];const[x, y] = z;obj[key] ='test';user['name'] ='John';// ✗ badconstobj = {id:1, name:'Alice'};const{x, y} = z;functionfoo(){returntrue;}if(foo) { bar =0;}// ✓ goodconstobj = { id:1, name:'Alice'};const{ x, y } = z;functionfoo(){returntrue; }if(foo) { bar =0; }// ✗ badproduct.attr({price:10.6, tags: ['food','sweet']});product.attr( { price:10.6, tags: ['food','sweet'] } );// ✓ goodproduct.attr({ price:10.6, tags: ['food','sweet'] });
要求在大括号前放一个空格。✎
space-before-blocks
// ✗ badfunctiontest(){console.log('test');}// ✓ goodfunctiontest(){console.log('test');}// ✗ baddog.set('attr',{ age:'1 year', breed:'Bernese Mountain Dog',});// ✓ gooddog.set('attr', { age:'1 year', breed:'Bernese Mountain Dog',});
要求在关键字和小括号之间加一个空格,禁止在函数名和参数列表之间加空格。✎
keyword-spacing,func-call-spacing,space-before-function-paren
保持一致是最好的,你不需要在添加/删除函数名时,考虑要不要添加/删除空格。
// ✗ badif(isJedi) { fight ();}else{ chat ();}// ✓ goodif(isJedi) { fight();}else{ chat();}// ✗ badfunctionfight(){console.log ('Swooosh!');}run(function(){console.log ('Swooosh!');});// ✓ goodfunctionfight(){console.log('Swooosh!');}run(function(){console.log('Swooosh!');});
禁止出现空块语句或空函数,除非添加一个注释。
no-empty,no-empty-function
// ✗ badif(cond) {}while(cond) { }// ✓ goodif(cond) {// TODO}while(cond) {/* TODO */}// ✗ badfunctionfoo(){}constfoo =function(){};constfoo = () => {};// ✓ goodfunctionfoo(){/* noop */}constfoo =function(){/* noop */};constfoo = () => {/* noop */};
块
要求大括号风格使用:1tbs(one true brace style)格式,允许单行模式。✎
brace-style
// ✗ badfunctionfoo(){returntrue;}if(foo) { bar();}else{ baz();}try{ somethingRisky();}catch(e){ handleError();}// ✓ goodfunctionfoo(){returntrue;}if(foo) { bar();}else{ baz();}try{ somethingRisky();}catch(e) { handleError();}functionfunc(){returntrue; }if(foo) { bar(); }
要求遵循大括号约定:multi-or-nest方式,多行时使用大括号,单行时省略大括号。✎
curly
// ✗ badif(!obj) obj = { id:1, name:'alice', };while(cond)if(cond2) doSomething();elsedoSomethingElse();if(foo) { foo++;}while(cond) { doSomething();}for(leti =0; i < count; i++) { doSomething();}// ✓ goodif(!obj) { obj = { id:1, name:'alice', };}while(cond) {if(cond2) doSomething();elsedoSomethingElse();}if(foo) foo++;while(cond) doSomething();for(leti =0; i < count; i++) doSomething();
要求单行语句必须换行。✎
nonblock-statement-body-position
// ✗ badif(foo)return;while(cond) doSomething();for(leti =0; i < count; i++) doSomething();// ✓ goodif(foo)return;while(cond) doSomething();for(leti =0; i < count; i++) doSomething();
分号和逗号
强制使用分号,禁止多余的分号。✎
semi,no-extra-semi,no-unexpected-multiline
// ✗ bad(function(){constname ='Skywalker'returnname;;})()// ✓ good(function(){constname ='Skywalker';returnname;})();
禁止使用行首逗号。✎
comma-style
// ✗ badconststory = [ once , upon , aTime];// ✓ goodconststory = [ once, upon, aTime,];
禁止使用逗号操作符。
no-sequences
// ✗ badfoo = doSomething(), val;if(doSomething(), !!test);while(val = foo(), val <42);// ✓ gooddoSomething();foo = val;if(!!test);while((val = foo()) <42);
要求多行使用拖尾逗号,禁止单行使用拖尾逗号。✎
comma-dangle
这会使git diffs更简洁,使编辑器的上下移动快捷键更方便。不用担心IE8会报错,Babel等编译器会自动去除拖尾逗号。
// ✗ bad - git diff without trailing commaconsthero = { firstName:'Florence',- lastName:'Nightingale'+ lastName:'Nightingale',+ inventorOf: ['coxcomb chart','modern nursing']};// ✓ good - git diff with trailing commaconsthero = { firstName:'Florence', lastName:'Nightingale',+ inventorOf: ['coxcomb chart','modern nursing'],};
// ✗ badconsthero = { firstName:'Dana', lastName:'Scully'};constheroes = ['Batman','Superman'];// ✓ goodconsthero = { firstName:'Dana', lastName:'Scully',};constheroes = ['Batman','Superman',];// ✗ badconsthero = { firstName, lastName, };constarr = [1,2,3, ];// ✓ goodconsthero = { firstName, lastName };constarr = [1,2,3];
字符串
要求使用单引号包裹字符串,在需要插值或换行时才使用反引号,在内部单引号需要转义时才使用双引号。✎
quotes
// ✗ badconsthello ="Hello, Bob!";constelement = ``;const message = 'I don\'t like quotes.';// ✓ goodconst hello = 'Hello, Bob!';const element = ``;const message = "I don't like quotes.";
禁止不必要的字符拼接。
no-useless-concat
// ✗ badconsta ='some'+'string';consta ='1'+'0';// ✓ goodconstc ='somestring';consta ='10';
禁止使用不必要的转义符。
no-useless-escape
// ✗ badconstfoo ='\"This\" \i\s \'quoted\'';// ✓ goodconstfoo ='"This" is \'quoted\'';constfoo = `"This"is'quoted'`;
禁止使用多行字符串。
no-multi-str
// ✗ badconstmessage ='Hello \
world';// ✓ goodconstmessage = `Hello world`;
尽量使用模板字符串,禁止在模板字符串的大括号周围加空格。✎
prefer-template,template-curly-spacing
// ✗ badreturn'How are you, '+ name +'?';return['How are you, ', name,'?'].join();return`How are you, ${ name }?`;// ✓ goodreturn`How are you, ${name}?`;
对象和属性
要求点操作符和属性放在同一行。✎
dot-location
// ✗ bad$('#items'). find('.selected'). highlight(). end(). find('.open'). updateCount();// ✓ good$('#items') .find('.selected') .highlight() .end() .find('.open') .updateCount();$('#items').find('.selected').highlight().end().find('.open').updateCount();// ✗ badconstp = promise. then(function(){// code}).catch(function(){// code});// ✓ goodconstp = promise.then(function(){// code}).catch(function(){// code});
要求尽可能使用点号,且不回避关键字。✎
dot-notation
// ✗ badconstresult = luke['jedi'];// ✓ goodconstresult = luke.jedi;constresult = luke.class;constresult = luke[key];
禁止使用不必要的计算属性。✎
no-useless-computed-key
// ✗ badconstuser = { ['name']:'John Doe'};// ✓ goodconstuser = { name:'John Doe'};
要求使用对象属性的简写语法。✎
object-shorthand
// ✗ badconstatom = { value: value, add:function(value){returnatom.value + value; },};// ✓ goodconstatom = { value, add(value) {returnatom.value + value; },};
要求只给对象中需要的属性名加引号。✎
quote-props
// ✗ badconstbad = {'foo':3,'bar':4,'>5,};// ✓ goodconstgood = { foo:3, bar:4,'>5,};
运算符
强制使用===和==,禁止使用==和!=。
eqeqeq
该规则旨在消除非类型安全的相等操作符。例如以下语句均被认为是true:
[] == false
[] == ![]
3 == "03"
// ✗ badif(a == b)if(foo ==true)if(bananas !=1)if(value ==undefined)if(typeoffoo =='undefined')if('hello'!='world')if(0==0)if(true==true)if(foo ==null)// ✓ goodif(a === b)if(foo ===true)if(bananas !==1)if(value ===undefined)if(typeoffoo ==='undefined')if('hello'!=='world')if(0===0)if(true===true)if(foo ===null)
禁止出现Yoda条件,除非是在范围中使用。✎
yoda
// ✗ badif('red'=== color)if(true== flag)if(-1< str.indexOf(substr))// ✓ goodif(color ==='red')if(flag)if(0<= x && x <1)
要求把换行符放在运算符的前面。
operator-linebreak
// ✗ badletfullHeight = borderTop + innerHeight + borderBottom;if(someCodition || otherCondition) {// ...}// ✓ goodletfullHeight = borderTop + innerHeight + borderBottom;if(someCodition || otherCondition) {// ...}
本文来自网易云社区,经作者赵雨森授权发布。
原文:一份 ECMAScript 2015 的代码规范(上)
更多网易研发、产品、运营经验分享请访问网易云社区。