Skip to content

Commit

Permalink
refactor(lodash): Removes most of the lodash dependencies in favor of…
Browse files Browse the repository at this point in the history
… native js (#117)

* refactor(lodash): Removes most of the lodash dependencies in favor of native js

Most of these lodash dependencies have a native replacement. The only reason they seem to have been used was to wrap the natives with safe checks and returns.

For example the use of `_forEach(list, () => ...)` is a safe version of:

```
(list || []).forEach((item) => ...);
```

Lodash protects against undefined, null. Others such as _.map also protect by returning an empty map so that chaining is safely allowed, some es6 doesn't allow native.

* Version bump to 2.1.0 in prep of release
  • Loading branch information
acolchado authored Apr 1, 2024
1 parent 29fe5f0 commit 57c0be5
Show file tree
Hide file tree
Showing 9 changed files with 102 additions and 90 deletions.
46 changes: 2 additions & 44 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 1 addition & 8 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "spur-ioc",
"description": "Dependency Injection library for Node.js",
"version": "2.0.1",
"version": "2.1.0",
"main": "./src/Injector",
"scripts": {
"lint": "eslint .",
Expand Down Expand Up @@ -52,13 +52,6 @@
"dependencies": {
"lodash.assign": "4.2.0",
"lodash.bindall": "4.4.0",
"lodash.compact": "3.0.1",
"lodash.foreach": "4.5.0",
"lodash.get": "4.4.2",
"lodash.isfunction": "3.0.9",
"lodash.isobject": "3.0.2",
"lodash.keys": "4.2.0",
"lodash.map": "4.6.0",
"require-all": "3.0.0"
},
"devDependencies": {
Expand Down
26 changes: 15 additions & 11 deletions src/ContainerManagement.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
const _forEach = require('lodash.foreach');
const _get = require('lodash.get');
const _isFunction = require('lodash.isfunction');
const _isObject = require('lodash.isobject');
const Dependency = require('./Dependency');
const Utils = require('./Utils');

const rall = /.+/;

module.exports = {

getDependencySourceHint(dependency) {
if (_isFunction(dependency)) {
return _get(dependency, 'name') || '<anonymous function>';
if (Utils.isFunction(dependency)) {
return dependency.name || '<anonymous function>';
}

if (_isObject(dependency)) {
return _get(dependency, 'constructor.name') || '<object>';
if (Utils.isObject(dependency)) {
return (dependency.constructor && dependency.constructor.name)
? dependency.constructor.name
: '<object>';
}

return `<${typeof dependency}>`;
Expand Down Expand Up @@ -74,13 +73,18 @@ module.exports = {
},

shouldIgnoreDependency(dependency) {
return Boolean(_get(dependency, 'spurIocIgnore', false));
const spurIocIgnore = (dependency && dependency.spurIocIgnore)
? dependency.spurIocIgnore
: false;

return Boolean(spurIocIgnore);
},

merge(otherInjector, suppressWarning = false) {
const dependencies = otherInjector.dependencies;
const dependencies = otherInjector.dependencies || {};
const names = Object.keys(dependencies) || [];

_forEach(dependencies, (value, name) => {
names.forEach((name) => {
const dependency = dependencies[name];
this.addConstructedDependency(name, dependency, suppressWarning);
});
Expand Down
3 changes: 1 addition & 2 deletions src/DependencyResolver.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
const _bindAll = require('lodash.bindall');
const _keys = require('lodash.keys');
const CallChain = require('./CallChain');

class DependencyError {
Expand Down Expand Up @@ -82,7 +81,7 @@ class DependencyResolver {
}

resolveRegex(regex) {
const deps = _keys(this.container.dependencies)
const deps = (Object.keys(this.container.dependencies) || [])
.filter((key) => { // eslint-disable-line
return regex.test(key) && key !== '$injector' && key !== this.container.privateInjectorName();
});
Expand Down
10 changes: 5 additions & 5 deletions src/FunctionArgumentsParser.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
const _map = require('lodash.map');
const _compact = require('lodash.compact');

const NEWLINE = /\n/g;
const AT = /_at_/g;
const ARROW_ARG = /^([^(]+?)=>/;
Expand All @@ -21,11 +18,14 @@ class FunctionArgumentsParser {

argsDeclaration[1].split(FN_ARG_SPLIT).forEach(function (arg) {
arg.replace(FN_ARG, function(name) {
args.push(name);
const cleanName = (name || '').trim();
if (cleanName.length > 0) {
args.push(cleanName);
}
});
});

return _compact(_map(args, (p) => p.trim()));
return args;
}

extractArgs(fn) {
Expand Down
4 changes: 2 additions & 2 deletions src/Logger.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
const _bindAll = require('lodash.bindall');
const _forEach = require('lodash.foreach');

class Level {
constructor(level, name, ascii, exit = false) {
Expand Down Expand Up @@ -38,7 +37,8 @@ class Logger {
}

addLoggingMethods() {
_forEach(LEVELS, (value, name) => {
const names = Object.keys(LEVELS) || [];
names.forEach((name) => {
if (Object.prototype.hasOwnProperty.call(LEVELS, name)) {
this[name] = LEVELS[name].log;
}
Expand Down
32 changes: 14 additions & 18 deletions src/RegistrationManagement.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
const requireAll = require('require-all');
const path = require('path');
const _forEach = require('lodash.foreach');
const _isFunction = require('lodash.isfunction');
const _isObject = require('lodash.isobject');
const requireAll = require('require-all');

const Utils = require('./Utils');
const fileFilterExpression = require('./FileFilterExpression');

const hasOwnProp = function (source, propertyName) {
return Object.prototype.hasOwnProperty.call(source, propertyName);
};

module.exports = {
registerFolder(rootDir, dir) {
const dirname = path.resolve(rootDir, dir);
Expand All @@ -21,28 +15,30 @@ module.exports = {
return this;
},

registerLibMap(libs) {
_forEach(libs, (value, name) => {
if (hasOwnProp(libs, name)) {
registerLibMap(libs = {}) {
const names = Object.keys(libs) || [];
names.forEach((name) => {
if (Utils.hasOwnProp(libs, name)) {
const lib = libs[name];
if (_isFunction(lib)) {
if (Utils.isFunction(lib)) {
this.addResolvableDependency(name, lib);
} else if (_isObject(lib)) {
} else if (Utils.isObject(lib)) {
this.registerLibMap(lib);
}
}
});
return this;
},

registerFolders(rootDir, dirs) {
_forEach(dirs, (dir) => this.registerFolder(rootDir, dir));
registerFolders(rootDir, dirs = []) {
dirs.forEach((dir) => this.registerFolder(rootDir, dir));
return this;
},

registerDependencies(dependencies) {
_forEach(dependencies, (value, name) => {
if (hasOwnProp(dependencies, name)) {
registerDependencies(dependencies = {}) {
const names = Object.keys(dependencies) || [];
names.forEach((name) => {
if (Utils.hasOwnProp(dependencies, name)) {
const lib = dependencies[name];
this.addDependency(name, lib);
}
Expand Down
14 changes: 14 additions & 0 deletions src/Utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module.exports = {
hasOwnProp(source, propertyName) {
return Object.prototype.hasOwnProperty.call(source, propertyName);
},

isFunction(value) {
return typeof value === 'function';
},

isObject(value) {
const type = typeof value;
return value != null && (type === 'object' || type === 'function');
}
};
48 changes: 48 additions & 0 deletions test/unit/Utils.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
const Utils = require('../../src/Utils');

describe('Utils', function () {
describe('hasOwnProp', () => {
it('should return true if the source object has the specified property', () => {
const source = { name: 'John', age: 30 };
const propertyName = 'name';
const result = Utils.hasOwnProp(source, propertyName);
expect(result).toBe(true);
});

it('should return false if the source object does not have the specified property', () => {
const source = { name: 'John', age: 30 };
const propertyName = 'address';
const result = Utils.hasOwnProp(source, propertyName);
expect(result).toBe(false);
});
});

describe('isFunction', () => {
it('should return true if the value is a function', () => {
const value = () => {};
const result = Utils.isFunction(value);
expect(result).toBe(true);
});

it('should return false if the value is not a function', () => {
const value = 'Hello, World!';
const result = Utils.isFunction(value);
expect(result).toBe(false);
});
});

describe('isObject', () => {
it('should return true if the value is an object', () => {
const value = { name: 'John', age: 30 };
const result = Utils.isObject(value);
expect(result).toBe(true);
});

it('should return false if the value is not an object', () => {
const value = 'Hello, World!';
const result = Utils.isObject(value);
expect(result).toBe(false);
});
});

});

0 comments on commit 57c0be5

Please sign in to comment.