Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
dwiyatci committed Oct 3, 2016
0 parents commit 9448b76
Show file tree
Hide file tree
Showing 4 changed files with 215 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Created by .ignore support plugin (hsz.mobi)

.idea
Binary file added 400.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
72 changes: 72 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Cumulocity lodash 4.x Migration (and Style) Guide

## Preferable Functional Methods
Conventionally speaking, we should favor lodash methods over their native and/or Angular counterparts.

> Why?
- [lodash blows away the performance of native functional methods.](http://benmccormick.org/2014/11/12/underscore-vs-lodash/)
- lodash has more features for those functional methods such as _chaining_ and _iteratee shorthand_.
- lodash provides compatibility consistency for browser which hasn't really natively supported these functions yet (read: IE).
- lodash enables us to produce code in better clarity (and of course – improve style consistency :wink:), e.g. compare: `Object.hasOwnProperty` vs `_.has`, `angular.forEach` vs `_.forEach`.

![http://cloud.highcharts.com/images/utusen/0/400.pdf](400.png)


Here are the two equivalence tables (note that the lists maybe incomplete, I only extract the common ones we use in our code):

### Native
| Native method | lodash method |
| --- | --- |
| `Function.prototype.bind` | `_.bind` |
| `Array.prototype.forEach` | `_.forEach` |
| `Array.prototype.map` | `_.map` |
| `Array.prototype.filter` | `_.filter` |
| `Array.prototype.reduce` | `_.reduce` |
| `Object.hasOwnProperty` | `_.has` |
| `Object.keys` | `_.keys` |
| `Object.values` | `_.values` |

### Angular
| Angular method | lodash method |
| --- | --- |
| `angular.bind` (beware that Angular [`.bind`](https://docs.angularjs.org/api/ng/function/angular.bind) function signature expects different arguments order) | `_.bind` |
| `angular.copy` | `_.cloneDeep` |
| `angular.equals` | `_.isEqual` |
| `angular.extend` | `_.assign` |
| `angular.forEach` | `_.forEach` |
| `angular.identity` | `_.identity` |
| `angular.isArray` | `_.isArray` |
| `angular.isDate` | `_.isDate` |
| `angular.isDefined` | `!_.isUndefined` |
| `angular.isElement` | `_.isElement` |
| `angular.isFunction` | `_.isFunction` |
| `angular.isNumber` | `_.isNumber` |
| `angular.isObject` | `_.isObject` |
| `angular.isString` | `_.isString` |
| `angular.isUndefined` | `_.isUndefined` |
| `angular.merge` | `_.merge` |
| `angular.noop` | `_.noop` |

## Preferable lodash Functional Method Aliases
In our code, lodash functional method aliases have been used inconsistently. :disappointed: So, please help yourself to make it more consistent!

| Alias | Favorable alias |
| --- | --- |
| `_.all` | `_.every` |
| `_.any` | `_.some` |
| `_.each` | `_.forEach` |
| `_.extend` (beware that lodash 4.x [`.extend`](https://lodash.com/docs/4.16.2#assignIn) behaves differently and **not** an alias for `.assign`) | `_.assign` |
| `_.unique` | `_.uniq` |
| `_.chain` | `_()` (yup, prefer implicit chaining. Also, beware that in implicit chaining, the wrapper [methods that are not chainable](https://lodash.com/docs/4.16.2#lodash) will end the chaining without the need of calling `.value()`, e.g. `.forEach`, `.reduce`) |

## Breaking Changes in 4.x (Method Removals and Renames)
[R.T.F. Changelog](https://github.com/lodash/lodash/wiki/Changelog#v400). :shipit:

Known to be used in our project are:
- `_.include` -> `_.includes`
- `_.contains` -> `_.includes`
- `_.pluck` -> `_.map` with iteratee shorthand
- `_.where` -> `_.filter` with iteratee shorthand
- `_.first` -> `_.head`
- `_.invoke` -> `_.invokeMap`
- `_.rest` -> `_.tail`
140 changes: 140 additions & 0 deletions migrate-lodash.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
const _ = require('lodash');
const replace = require('replace');

const replacementSpecs = [
{
regex: 'Object[.]hasOwnProperty',
replacement: '_.has',
},
{
regex: 'Object[.]keys',
replacement: '_.keys',
},
{
regex: 'Object[.]values',
replacement: '_.values',
},
{
regex: 'angular[.]copy',
replacement: '_.cloneDeep',
},
{
regex: 'angular[.]equals',
replacement: '_.isEqual',
},
{
regex: 'angular[.]extend',
replacement: '_.assign',
},
{
regex: 'angular[.]forEach',
replacement: '_.forEach',
},
{
regex: 'angular[.]identity',
replacement: '_.identity',
},
{
regex: 'angular[.]isArray',
replacement: '_.isArray',
},
{
regex: 'angular[.]isDate',
replacement: '_.isDate',
},
{
regex: 'angular[.]isDefined',
replacement: '!_.isUndefined',
},
{
regex: 'angular[.]isElement',
replacement: '_.isElement',
},
{
regex: 'angular[.]isFunction',
replacement: '_.isFunction',
},
{
regex: 'angular[.]isNumber',
replacement: '_.isNumber',
},
{
regex: 'angular[.]isObject',
replacement: '_.isObject',
},
{
regex: 'angular[.]isString',
replacement: '_.isString',
},
{
regex: 'angular[.]isUndefined',
replacement: '_.isUndefined',
},
{
regex: 'angular[.]merge',
replacement: '_.merge',
},
{
regex: 'angular[.]noop',
replacement: '_.noop',
},
{
regex: '_[.]all',
replacement: '_.every',
},
{
regex: '_[.]any',
replacement: '_.some',
},
{
regex: '_[.]each',
replacement: '_.forEach',
},
{
regex: '_[.]extend',
replacement: '_.assign',
},
{
regex: '_[.]unique',
replacement: '_.uniq',
},
{
regex: '_[.]chain',
replacement: '_',
},
{
regex: '_[.]include',
replacement: '_.includes',
},
{
regex: '_[.]contains',
replacement: '_.includes',
},
{
regex: '_[.]pluck',
replacement: '_.map',
},
{
regex: '_[.]where',
replacement: '_.filter',
},
{
regex: '_[.]first',
replacement: '_.head',
},
{
regex: '_[.]invoke',
replacement: '_.invokeMap',
},
{
regex: '_[.]rest',
replacement: '_.tail',
},
];

_.forEach(replacementSpecs, replacementSpec => replace({
regex: replacementSpec.regex,
replacement: replacementSpec.replacement,
paths: ['/Users/glenn/cumulocity/cumulocity-ui/app/scripts'],
recursive: true,
}));

0 comments on commit 9448b76

Please sign in to comment.