DEV Community

Denys Potapov
Denys Potapov

Posted on

npm hack to remove unused transitive dependencies

Image description

Unused dependencies can be a pain in javascript project. For example your use foo package in your project. And foo package depends on bar package. Sometimes code from bar is unused in your project, but there is no way to remove it.

I've created an empty dry-uninstall package to «solve» an issue with unused transitive dependencies:

{
  "overrides": {
    "foo": {
      "bar": "npm:dry-uninstall"
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

It uses hack in overrides section of package.json to replace bar dependency of foo with an empty index.js:

module.exports = {};
Enter fullscreen mode Exit fullscreen mode

Reasoning

The main reasons why this could help are:

  1. Bundle size. When tree-shaking does not work for some reasons.

  2. Simplified Build. There was a long time when installing mongodb required kerberos package. That itself required to build native add-on modules, and it can be painful.

  3. Security. Replace the vulnerable packages, to be sure that the code is never used.

  4. License Issues.

Sample: Removing momentjs package from simple-node-logger

You've created a minimal project that uses simple-node-logger, simple multi-level logger for console and files:

// index.js
const SimpleLogger = require('simple-node-logger');
const appender = new SimpleLogger.appenders.ConsoleAppender();

const manager = new SimpleLogger();
manager.addAppender(appender);

const log = manager.createLogger();
log.info('this is a simplelog statement');
Enter fullscreen mode Exit fullscreen mode

Check the size of bundle (~383 KB)

    esbuild index.js --bundle --platform=node --outfile=index.dist.js

      index.dist.js  383.7kb
Enter fullscreen mode Exit fullscreen mode

Removing momentjs

Update timestamp format code to remove the momentjs dependency:

// index.js
appender.formatter = function(entry) {
    const fields = this.formatEntry( entry, appender);

    return fields.join( appender.separator );
};
appender.formatTimestamp = (ts) => {
    return ts.toString();
};
Enter fullscreen mode Exit fullscreen mode

Override momentjs with dry-uninstall in package.json

{
  "dependencies": {
    "simple-node-logger": "^21.8.12"
  },
  "overrides": {
    "moment": "npm:dry-uninstall@0.3.0"
  }
}
Enter fullscreen mode Exit fullscreen mode

Check the size of bundle (~241 KB)

    esbuild index.js --bundle --platform=node --outfile=index.dist.js

      index.dist.js  241.7kb
Enter fullscreen mode Exit fullscreen mode

Saved around 140 kb, not bad.

Top comments (0)