Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
180 changes: 180 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ React-specific guidelines described at [RingCentral React Style Guide](https://g
1. [Language statements and features](#language-statements-and-features)
1. [Spaces and alignments](#spaces-and-alignments)
1. [Naming](#naming)
1. [External libraries](#external-libraries)

## Overview

Expand Down Expand Up @@ -825,3 +826,182 @@ export class MyCompositeComponent {
}
}
```

## External libraries

### Prefer native js vs lodash
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a good section, i like it. my common feedback - please add few words regarding to polyfills. Otherwise it looks unsafely to swapping to native methods.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

one more - is adding a few words when lodash is preferred, say reduce an Object, or find via object, is a shorthand's we prefer.

_.reduce({foo: 'FOO', bar: 'BAR'}, callback, {});
_.find( [{baz: 10}, {baz: 30}, {baz: 50}], {foo: 30});

Copy link
Contributor Author

@ledamint ledamint Jan 4, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we will leave only bad cases to not divide all lodash functionality to good or bad? I described popular and often used methods. In cases above, we can use Object.(keys|values|entries) and after use array methods.

Copy link
Contributor

@DmitryKorlas DmitryKorlas Jan 4, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we have to provide a list of all bad technics we have to replace to native alternatives. Regarding to using two methods vs one: using two methods vs one is not a good choice. We have to make our code simple and do not introduce extra boilerplate code. Lodash is created for this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a rare case where you need reduce to object and I think it's nice to directly show where is a plain array or where is an object which you need to use as an array. You use one short method with particular cases and your code remains strict, native and without external modules except using external functionality which eats any type


> Reason: lodash is a great library which contains a lot of useful functions but the modern js has the short identical part of this functionality so some lodash functions are excess alternative.

> Don't forget to check necessary browsers compatibility and turn on polyfills if it's needed.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A good note, I like it. I guess it would be better to clarify which variants is dangerous and add a link to MDN for every such method. We have to notify a users of this document.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest to not create a compatibility map, all developers understand about using different functionality and should think about each method itself depending which browser support is needed for an application

```javascript
// BAD
_.each([1, 2, 3], callback);
// GOOD
[1, 2, 3].forEach(callback);
```
```javascript
// BAD
_.filter([1, 2, 3], callback);
// GOOD
[1, 2, 3].filter(callback);
```
```javascript
// BAD
_.compact([1, 2, 3, 0, false, '']);
// GOOD
[1, 2, 3, 0, false, ''].filter(Boolean);
```
```javascript
// BAD
_.map([1, 2, 3], callback);
// GOOD
[1, 2, 3].map(callback);
```
```javascript
// BAD
_.every([1, 2, 3], callback);
// GOOD
[1, 2, 3].every(callback);
```
```javascript
// BAD
_.some([1, 2, 3], callback);
// GOOD
[1, 2, 3].some(callback);
```
```javascript
// BAD
_.reduce([1, 2, 3], callback, 0);
// GOOD
[1, 2, 3].reduce(callback, 0);
```
```javascript
// BAD
_.concat([1, 2, 3], [4, 5, 6]);
// GOOD
[1, 2, 3].concat([4, 5, 6]);
```
```javascript
// BAD
_.indexOf([1, 2, 3], 1);
// GOOD
[1, 2, 3].indexOf(1);
```
```javascript
// BAD
_.includes([1, 2, 3], 1);
// GOOD
[1, 2, 3].includes(1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Array.prototype.includes is not a cross browser and still not supported in IE11. Native variant is only preferred when polyfill is included. Otherwise it dangerous and we should not recommend it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will add a attention about polyfills

```
```javascript
// BAD
const first = _.first([1, 2, 3]);
// GOOD
const [first] = [1, 2, 3];
```
```javascript
// BAD
_.join([1, 2, 3], '-');
// GOOD
[1, 2, 3].join('-');
```
```javascript
// BAD
_.reverse([1, 2, 3]);
// GOOD
[1, 2, 3].reverse();
```
```javascript
// BAD
_.uniq([1, 2, 3, 3, 2]);
// GOOD
[...new Set([1, 2, 3, 3, 2])];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one does not looks better vs lodash variant. _.uniq is more clear and shortener. Also, Set has cross browser limitations.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Native and one line, easy to understand or to google purpose if not. I suggest it's a nice choice, IE should die, thinking about it is an atavism in 2k19. It will be attention about polyfills

```
```javascript
// BAD
_.isArray([1, 2, 3]);
// GOOD
Array.isArray([1, 2, 3]);
```
```javascript
// BAD
_.size([1, 2, 3]);
// GOOD
[1, 2, 3].length;
```
```javascript
// BAD
_.isEmpty([]);
// GOOD
[].length === 0;
````
```javascript
// BAD
_.bind(func, this);
// GOOD
func.bind(this);
```
```javascript
// BAD
_.isNaN(value);
// GOOD
Number.isNaN(value);
```
```javascript
// BAD
_.isUndefined(value);
// GOOD
value === undefined;
```
```javascript
// BAD
_.isEmpty(object);
// GOOD
Object.keys(object).length === 0;
```
```javascript
// BAD
const foo = _.assign({}, object1, object2);
// GOOD
const foo = {
...object1,
...object2,
};
```
```javascript
// BAD
const others = _.omit({a: 1, b: 2, c: 3, d: 4}, ['a', 'c']);
// GOOD
const {a, c, ...others} = {a: 1, b: 2, c: 3, d: 4};
```
```javascript
// BAD
_.isEmpty(object);
// GOOD
Object.keys(object).length === 0;
````
```javascript
// BAD
_.keys(object);
// GOOD
Object.keys(object);
```
```javascript
// BAD
_.values(object);
// GOOD
Object.values(object);
```
```javascript
// BAD
_.entries(object);
// GOOD
Object.entries(object);
```
```javascript
// BAD
_.trim(' 123 ');
// GOOD
' 123 '.trim();
```
4 changes: 2 additions & 2 deletions eslint-config-ringcentral/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ module.exports = {
},
sourceType: 'module'
},
plugins: ['react', 'import', 'ringcentral'],
extends: ['eslint:recommended', 'plugin:ringcentral/all'],
plugins: ['react', 'import', 'ringcentral', 'you-dont-need-lodash-underscore'],
extends: ['eslint:recommended', 'plugin:ringcentral/all', 'plugin:you-dont-need-lodash-underscore/all-warn'],
globals: {
chai: true,
expect: true,
Expand Down
6 changes: 4 additions & 2 deletions eslint-config-ringcentral/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,14 @@
"eslint": ">=4.1.1",
"eslint-plugin-import": "^2.16.0",
"eslint-plugin-react": "^7.1.0",
"eslint-plugin-ringcentral": "~1.0.5"
"eslint-plugin-ringcentral": "~1.0.5",
"eslint-plugin-you-dont-need-lodash-underscore": "^6.4.0"
},
"peerDependencies": {
"eslint": ">=4.1.1",
"eslint-plugin-import": "^2.16.0",
"eslint-plugin-react": "^7.1.0",
"eslint-plugin-ringcentral": "~1.0.5"
"eslint-plugin-ringcentral": "~1.0.5",
"eslint-plugin-you-dont-need-lodash-underscore": "^6.4.0"
}
}