Security News
Fluent Assertions Faces Backlash After Abandoning Open Source Licensing
Fluent Assertions is facing backlash after dropping the Apache license for a commercial model, leaving users blindsided and questioning contributor rights.
eslint-config-netsells
Advanced tools
This repository contains the defacto-standard eslint configuration used on all Netsells projects, both internally and client.
Add the config to your project dependencies:
yarn add netsells/eslint-config-netsells eslint@^4.10.0
Extend the config in your project. For example, a .eslintrc
file in your project root:
{
"extends": "netsells"
}
Add the eslint-loader to your project:
yarn add eslint-loader
Add the loader into your workflow. The following example will force the linter to be ran before other loaders such as babel compilation. This means we lint the raw ES6 code rather than the transpiled ES5 output:
{
module: {
rules: [
{
test: /.(vue|js)$/,
loader: 'eslint-loader',
enforce: 'pre',
exclude: /node_modules/,
},
],
},
},
Requires trailing commas when the last element or property is in a different line than the closing ]
or }
and disallows trailing commas when the last element or property is on the same line as the closing ]
or }
. This makes git diffs a lot cleaner with single line changes rather than two.
let object = { a: 'b', c: 'd', };
let object = {
a: 'b',
c: 'd'
};
let array = ['a', 'b', 'c',];
let array = [
'a',
'b',
'c'
];
let object = { a: 'b', c: 'd' };
let object = {
a: 'b',
c: 'd',
};
let array = ['a', 'b', 'c'];
let array = [
'a',
'b',
'c',
];
Requires the dot to be located before the property rather than after the object
const item = object.
property;
const item = object
.property;
const item = object.property;
disallow empty block statements
if (foo) {
}
while (foo) {
}
switch(foo) {
}
try {
doSomething();
} catch(ex) {
} finally {
}
if (foo) {
// empty
}
while (foo) {
/* empty */
}
try {
doSomething();
} catch (ex) {
// continue regardless of error
}
try {
doSomething();
} finally {
/* continue regardless of error */
}
Disallow empty functions
function foo () {}
let foo = function () {};
let foo = () => {};
let obj = {
foo: function () {},
foo () {},
};
class A {
constructor() {}
foo() {}
}
function foo () {
// do nothing.
}
let foo = function () {
// any clear comments.
};
let foo = () => {
bar();
};
let obj = {
foo: function () {
// do nothing.
},
foo () {
// do nothing.
},
};
class A {
constructor () {
// do nothing.
}
foo () {
// do nothing.
}
}
Require a space before function parenthesis
function foo () {
// ...
}
let bar = function () {
// ...
};
class Foo {
constructor () {
// ...
}
}
let foo = {
bar () {
// ...
}
};
var foo = async() => 1
function foo() {
// ...
}
let bar = function() {
// ...
};
class Foo {
constructor() {
// ...
}
}
let foo = {
bar() {
// ...
}
};
var foo = async() => 1
Disallow mixed spaces and tabs for indentation
function add(x, y) {
// --->..return x + y;
return x + y;
}
function main() {
// --->var x = 5,
// --->....y = 7;
var x = 5,
y = 7;
}
function add(x, y) {
// --->return x + y;
return x + y;
}
Discourage code typed like yoda would speak
if ('red' === color) {
// ...
}
if (true == flag) {
// ...
}
if (5 > count) {
// ...
}
if (-1 < str.indexOf(substr)) {
// ...
}
if (5 & value) {
// ...
}
if (value === 'red') {
// ...
}
if (x < -1 || 1 < x) {
// ...
Disallow eval() function
let obj = { x: 'foo' },
key = "x",
value = eval("obj." + key);
(0, eval)("var a = 0");
let foo = eval;
foo("var a = 0");
// This `this` is the global object.
this.eval("var a = 0");
window.eval("var a = 0");
global.eval("var a = 0");
let obj = { x: 'foo' },
key = "x",
value = obj[key];
class A {
foo() {
// This is a user-defined method.
this.eval("var a = 0");
}
eval() {
}
}
Requires JSDoc definitions for all functions and classes.
methods: {
updateUser (id, data) {
return fetch(`/users/${id}`, {
method: 'POST',
body: JSON.stringify(opts),
});
},
}
methods: {
/**
* Update the user with the given id via the API
*
* @param {Number} id - id of user
* @param {Object} data - userdata object
*
* @returns {Promise}
*/
updateUser (id, data) {
return fetch(`/users/${id}`, {
method: 'POST',
body: JSON.stringify(opts),
});
},
}
Discourages using var
for creating variables and requires using let
or const
instead
var count = posts.length;
const count = posts.length;
or, if the value can be changed
let count = posts.length;
if (additionalPosts.length) {
count += additionalPosts.length;
}
Disallows using alert() function in production. Will throw a warning if the node env is not set to production (allows an alert-driven development).
if (error) {
alert(error);
}
Disallows using the console in production. Will throw a warning if the node env is not set to production.
if (error) {
console.log(error);
}
Encourages stopping mixing different types of variables for the sake of cleaner and more readable code.
// Boolean
const b = !!foo;
const b = ~foo.indexOf('.');
// Number
const n = +foo;
const n = 1 * foo;
// Strings
const s = '' + foo;
const s = `` + foo;
foo += '';
foo += ``;
// Boolean
const b = Boolean(foo);
const b = foo.includes('.');
// Number
const n = Number(foo);
const n = parseFloat(foo);
const n = parseInt(foo, 10);
// Strings
const s = String(foo);
foo = String(foo);
arrows on arrow functions should have a space before and after.
(a)=>{};
()=> {};
() =>{};
(a)=> {};
(a) =>{};
(a) => {}
Throw a warning when a regular string contains a text which looks like an ES6 template literal placeholder
const greeting = "Hello, ${name}";
const greeting = `Hello, ${name}`;
Encourage using template literals instead of '+' operator on strings
const greeting = 'Hello, ' + this.name;
const greeting = `Hello, ${this.name}`;
Forces using dot notation exclusively for getting object properties.
const a = foo['bar'];
const a = foo.bar;
const b = 'Hello';
const c = foo[b];
Disallow duplicate imports.
import { merge } from 'module';
import something from 'another-module';
import { find } from 'module';
import { merge, find } from 'module';
import something from 'another-module';
Disallows importing lodash - people should import only the lodash sub-modules they need.
import _ from 'lodash';
import flatten from 'lodash/flatten';
@throws Error
Disallow referencing this
within a template.
<template>
<div>{{ this.foo }}</div>
</template>
<template>
<div>{{ foo }}</div>
</template>
@throws Error
Enforce a rational order of Vue component data.
export default {
// Options / Misc
'name',
'delimiters',
'functional',
'model',
// Options / Assets
'components',
'directives',
'filters',
// Options / Composition
'parent',
'mixins',
'extends',
'provide',
'inject',
// Context
'el',
'template',
'props',
'propsData',
'data',
'computed',
'watch',
'LIFECYCLE_HOOKS',
'methods',
'render',
'renderError',
};
@throws Error
Enforce a consistent continuous indent of 4 spaces for both tags and tag attributes.
<template>
<div>
<my-component
:foo="bar"
:abc="xyz"
</my-component>
</div>
</template>
<template>
<div>
<my-component
:foo="bar"
:abc="xyz"
</my-component>
</div>
</template>
@throws Error
Force attributes to be hyphenated rather than camelCase.
<my-component :customAttribute="true"></my-component>
<my-component :custom-attribute="true"></my-component>
@throws Error
Error on duplicate keys to avoid conflicting and overwriting of values.
export default {
props: {
foo: String,
},
computed: {
foo: {
get () {}
},
},
data: {
foo: null,
},
methods: {
foo () {},
},
}
@throws Error
Force the shorthand syntax for event binding.
<my-component v-on:change="updateValue"></my-component>
<my-component @change="updateValue"></my-component>
@throws Error
Force the shorthand syntax for the v-bind directive.
<my-component v-bind:foo="bar"></my-component>
<my-component :foo="bar"></my-component>
@throws Error
Remove multiple spaces in a row between attributes which are not used for indentation.
<div class="foo"
:style="bar" />
<div
class="foo"
:style="bar"
/>
@throws Error
Allow only kebab-case (hyphenated) component names.
export default {
name: 'MyComponent',
}
export default {
name: 'my-component',
}
@throws Error
Enforce a single space around values in mustache echo statements.
<div>{{foo}}</div>
<div>{{ foo }}</div>
<div>{{ foo }}</div>
@throws Error
Enforce a double quotes on tag attributes.
<div class='foo'></div>
<div class=foo></div>
<div class="foo"></div>
@throws Error
Limit the max number of attributes per line. Single line tags can have a maximum of 3 attributes per line. After which each attribute should be broken down onto individual lines.
<my-component foo="bar" baz="qux" abc="123" xyz="321"></my-component>
<my-component
foo="bar" baz="qux"
><my-component>
<my-component foo="bar" baz="qux" abc="123"></my-component>
<my-component
foo="bar"
baz="qux"
abc="123"
xyz="321"
></my-component>
@throws Warning
Encourage providing default values for props.
props: {
a: Number,
b: [Number, String],
c: {
type: Number,
},
d: {
type: Number,
required: false,
},
}
props: {
a: {
type: Number,
required: true,
},
b: {
type: Number,
default: 0,
},
c: {
type: Number,
default: 0,
required: false,
},
}
@throws Warning
Encourage long-form prop definitions with at minimum a declared data type.
props: ['status'],
props: {
status: String,
}
props: {
status: {
type: String,
},
}
@throws Warning
It is considered a very bad practice to introduce side effects inside computed properties. It makes the code unpredictable and hard to understand. Discourage computed properties from mutating state.
computed: {
fullName () {
this.firstName = 'lorem'; // <- side effect
return `${this.firstName} ${this.lastName}`;
},
reversedArray () {
return this.array.reverse(); // <- side effect
},
}
computed: {
fullName () {
return `${this.firstName} ${this.lastName}`;
},
reversedArray () {
return this.array.slice(0).reverse();
},
}
@throws Error
When duplicate attributes exist, only the last one is used. Disallow duplicates for attributes other than special bindings such as class and style.
<my-component
:foo="bar"
foo="xyz"
></my-component>
<my-component
class="bar"
:class="{ foo: true }"
abc="xyz"
></my-component>
@throws Error
Make sure computed properties return a value.
computed: {
foo () {
},
}
computed: {
foo () {
return 'bar';
},
}
@throws Error
Make sure scope variables are used.
<template>
<ol v-for="i in 5"><!-- "i" is defined but never used. -->
<li>item</li>
</ol>
</template>
<template>
<ol v-for="i in 5">
<li>{{ i }}</li><!-- "i" is defined and used. -->
</ol>
</template>
@throws Error
Component data must be returned as a new instance via a function rather than a plain object.
export default {
data: {
foo: 'bar',
},
}
export default {
data () {
return {
foo: 'bar',
}
},
}
--
@throws Warning
All imports and vars that are included within code must be used.
let foo = 'bar';
function fooBar() {
//code
}
//End of file
let foo = 'bar';
function fooBar() {
return `${foo}bar`;
//code
}
//End of file
@throws Warning
Equality operators must now be type-safe - as is considered best practice in coding.
if (x == y) {
// code
}
if ("" == text) {
//code
}
if (obj.stuff != undefined) {
// code
}
if (x === y) {
// code
}
if ("" === text) {
// code
}
if (obj.stuff !== undefined) {
// code
}
@throws Warning
Prevents a return statement being called before an else. But also, in this instance, as we have allowElseIf set to false, else statements will also not be allowed in code.
function foo() {
if (x) {
return a;
} else if (y) {
return b;
} else {
return c;
}
}
function foo() {
if (x) {
return a;
}
if (y) {
return b;
}
return c;
}
@throws Warning
Prevents using floating decimals
const num = .5;
const ber = 2.;
const wang = -.7;
const num = 0.5;
const ber = 2.0;
const wang = -0.7;
@throws Warning
Curly brace conventions must follow a strict formatted pattern.
if (foo) return;
while (bar)
baz();
if (foo) {
baz();
} else qux();
if (foo) {
return;
}
while (bar) {
baz();
}
if (foo) {
baz();
} else {
qux();
}
--
@throws Warning
Discourages the assignment of variables in conditional statements
Allows assignment within params by default
const x;
if (x = 0) {
const b = 1;
}
// Practical example that is similar to an error
function setHeight(someNode) {
"use strict";
do {
someNode.height = "100px";
} while (someNode = someNode.parentNode);
}
const x;
if (x === 0) {
const b = 1;
}
// Practical example that wraps the assignment in parentheses
function setHeight(someNode) {
"use strict";
do {
someNode.height = "100px";
} while ((someNode = someNode.parentNode));
}
// Practical example that wraps the assignment and tests for 'null'
function setHeight(someNode) {
"use strict";
do {
someNode.height = "100px";
} while ((someNode = someNode.parentNode) !== null);
}
@throws Error
Forces user to use ES6 arrow function expressions
foo(function(a) {
return a;
});
foo(function() {
return this.a;
}.bind(this));
foo((a) => {
return a;
});
foo(() => {
return this.a;
});
@throws Warning
If an if statement is the only statement in the else block, it is clearer to use an else if.
if (foo) {
// ...
} else {
if (bar) {
// ...
}
}
if (condition) {
// ...
} else {
if (anotherCondition) {
// ...
}
}
if (condition) {
// ...
} else if (anotherCondition) {
// ...
} else {
// ...
}
@throws Warning
If a variable is set using 'let' and then never updated a warning will be issued as 'const' is preferred in this instance.
let a = 3;
console.log(a);
let a;
a = 1;
return a;
for (let i in [1, 2, 3]) {
console.log(i);
}
const a = 3;
console.log(a);
for (const i in [1, 2, 3]) {
console.log(i);
}
let a;
a = 1;
a = 2;
return a;
let a;
if (true) {
a = 1;
}
If you disagree with any rules in this linter, or feel additional rules should be added, please open an issue on this project to initiate an open dialogue with all team members. Please bear in mind this is a public repository.
FAQs
Eslint config for the Netsells organisation
We found that eslint-config-netsells demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Fluent Assertions is facing backlash after dropping the Apache license for a commercial model, leaving users blindsided and questioning contributor rights.
Research
Security News
Socket researchers uncover the risks of a malicious Python package targeting Discord developers.
Security News
The UK is proposing a bold ban on ransomware payments by public entities to disrupt cybercrime, protect critical services, and lead global cybersecurity efforts.