Live data from Hacker News

Kill Your Dependencies

mikeperham.com

31–40 of 229 posts

Re: Kill Your Dependencies

#31

This is a great read that can be applied to node.js very much. I've seen apps that include 10, maybe 20 dependencies but when you flatten out the full dependency tree? Thousands. It's incredible and if one of those dependencies screws up semantic versioning or just screws up in general it can be a nightmare to debug and fix. This is why every 1.0 product I work on I include every dependency that speeds up my developm…

This sadly also happens in some Linux repositories that add too many dependencies to a few key packages.

On NixOS, last time I tried, installing mutt ended up bringing python as well.

Re: Kill Your Dependencies

#32
This is a huge mistake if applied without care. Building things from scratch necessarily will introduce more bugs, more maintenance costs and leave you with a codebase that suffers from a lack of maturity.

Re: Kill Your Dependencies

#34

A lot of apps (old-timey Windows apps, for example) have this philosophy, leading them to reinvent things like crypto and image decoding. Naturally, this leads to tons of bugs, including security bugs. I would revise this to: Don't bring in more code than you need. But if the choice is between writing something yourself and using someone else's well-tested, heavily-used library, always go for the latter.

> Don't bring in more code than you need. I see it as a sliding scale. If I'm parsing 1 string with the same date format into 1 object, I'm not going to pull in some general purpose time parsing library - I'll write the 10 lines of code myself, a few unit tests, and be happy. If in the future I start having to deal with different date strings and some need to do more than just throw up a single date on a page somewhe…

You could also use the third party library for your unit tests.

Re: Kill Your Dependencies

#35
post #27

I find dependencies to be a very good indicator for how my code should be modularized. That is, rather than pulling a boatload of dependencies into "the application", pull a couple dependencies into a module, and then depend on the module. It makes it very easy for dependencies to be a "well, it gets the job done for now, and I can reimplement that myself if that changes" sort of thing.

I found this approach to work well for me as well. It has payed off many times. I try to wrap most of my dependencies so that if I later feel like I need to pick some low-hanging fruit I can implement some of the functionality internally while maintaining the original api.

Re: Kill Your Dependencies

#36
This reminds me of an example I ran into yesterday. I haven't used webpack yet but I saw a question on SO of someone wanting to use some package called glslify. I thought I'd take a look and maybe learn webpage in the process.

From the description all glslify does is look for files with the extensions .glsl, .frag, and .vert and lets you get their contents with `content = require(filename)`.

Sounds like it would be at most 10-30 lines of code. Nope

    npm install --save glslify-loader
    webpack-glsl-test@1.0.0 /Users/gregg/temp/webpack-glsl-test
    └─┬ glslify-loader@1.0.2 
      └─┬ glslify@2.3.1 
        ├─┬ bl@0.9.5 
        │ └─┬ readable-stream@1.0.33 
        │   ├── core-util-is@1.0.2 
        │   ├── isarray@0.0.1 
        │   └── string_decoder@0.10.31 
        ├─┬ glsl-resolve@0.0.1 
        │ ├── resolve@0.6.3 
        │ └── xtend@2.2.0 
        ├─┬ glslify-bundle@2.0.4 
        │ ├─┬ glsl-inject-defines@1.0.3 
        │ │ └── glsl-token-inject-block@1.0.0 
        │ ├── glsl-token-defines@1.0.0 
        │ ├── glsl-token-depth@1.1.2 
        │ ├─┬ glsl-token-descope@1.0.2 
        │ │ ├── glsl-token-assignments@2.0.1 
        │ │ └── glsl-token-properties@1.0.1 
        │ ├── glsl-token-scope@1.1.2 
        │ ├── glsl-token-string@1.0.1 
        │ └── glsl-tokenizer@2.0.2 
        ├─┬ glslify-deps@1.2.5 
        │ ├── events@1.1.0 
        │ ├─┬ findup@0.1.5 
        │ │ ├── colors@0.6.2 
        │ │ └── commander@2.1.0 
        │ ├── graceful-fs@4.1.3 
        │ ├── inherits@2.0.1 
        │ └─┬ map-limit@0.0.1 
        │   └─┬ once@1.3.3 
        │     └── wrappy@1.0.1 
        ├── minimist@1.2.0 
        ├── resolve@1.1.7 
        ├─┬ static-module@1.3.0 
        │ ├─┬ concat-stream@1.4.10 
        │ │ ├── readable-stream@1.1.13 
        │ │ └── typedarray@0.0.6 
        │ ├─┬ duplexer2@0.0.2 
        │ │ └── readable-stream@1.1.13 
        │ ├─┬ escodegen@1.3.3 
        │ │ ├── esprima@1.1.1 
        │ │ ├── estraverse@1.5.1 
        │ │ ├── esutils@1.0.0 
        │ │ └─┬ source-map@0.1.43 
        │ │   └── amdefine@1.0.0 
        │ ├─┬ falafel@1.2.0 
        │ │ ├── acorn@1.2.2 
        │ │ ├── foreach@2.0.5 
        │ │ └── object-keys@1.0.9 
        │ ├─┬ has@1.0.1 
        │ │ └── function-bind@1.0.2 
        │ ├── object-inspect@0.4.0 
        │ ├─┬ quote-stream@0.0.0 
        │ │ ├── minimist@0.0.8 
        │ │ └─┬ through2@0.4.2 
        │ │   └─┬ xtend@2.1.2 
        │ │     └── object-keys@0.4.0 
        │ ├── shallow-copy@0.0.1 
        │ ├─┬ static-eval@0.2.4 
        │ │ └─┬ escodegen@0.0.28 
        │ │   ├── esprima@1.0.4 
        │ │   └── estraverse@1.3.2 
        │ └─┬ through2@0.4.2 
        │   └─┬ xtend@2.1.2 
        │     └── object-keys@0.4.0 
        ├── through2@0.6.5 
        └── xtend@4.0.1 
> 4 meg of source files

---

update: I think maybe I misunderstood the description. glslify actually parses GLSL and re-writes it in various ways so maybe this is a bad example.

I've seen other though. Like 40k+ lines of deps for an ANSI color library or 200k+ lines deps and native node plugins for launching a browser from node.

Re: Kill Your Dependencies

#37

A lot of apps (old-timey Windows apps, for example) have this philosophy, leading them to reinvent things like crypto and image decoding. Naturally, this leads to tons of bugs, including security bugs. I would revise this to: Don't bring in more code than you need. But if the choice is between writing something yourself and using someone else's well-tested, heavily-used library, always go for the latter.

As an architect, you need to be able to do a cost/benefit analysis of each option. That is what software architects do, why they have experience. For example:

  How much time will it take to implement each option?
  How much time will it take in the future to support it?
  What security risk does each option incur?
  What is the risk of the project being abandoned?
  What is the risk of the project changing in non-backwards compatible ways?
  What are the performance characteristics of each option?
NIH is a disease, but so is import-mania. With experience, you can make a good decision.

Re: Kill Your Dependencies

#38

This is a huge mistake if applied without care. Building things from scratch necessarily will introduce more bugs, more maintenance costs and leave you with a codebase that suffers from a lack of maturity.

I don't think the sentiment is 'implement everything from scratch', but rather that if something exists natively try to use that instead of pulling in other dependencies, like in the http client example.

Re: Kill Your Dependencies

#39
post #21

A lot of apps (old-timey Windows apps, for example) have this philosophy, leading them to reinvent things like crypto and image decoding. Naturally, this leads to tons of bugs, including security bugs. I would revise this to: Don't bring in more code than you need. But if the choice is between writing something yourself and using someone else's well-tested, heavily-used library, always go for the latter.

This is pretty much what Rob Pike advocates in Go: "A little copying is better than a little dependency." http://go-proverbs.github.io/

I pretty squarely disagree with Rob Pike on that one. Copying is how you introduce bugs and insulate yourself from upstream bugfixes. I'm suggesting that you should try to remove code first, add a dependency on well-trusted code if that doesn't work, and only copy/reinvent as a last resort.

Re: Kill Your Dependencies

#40

This reminds me of an example I ran into yesterday. I haven't used webpack yet but I saw a question on SO of someone wanting to use some package called glslify. I thought I'd take a look and maybe learn webpage in the process. From the description all glslify does is look for files with the extensions .glsl, .frag, and .vert and lets you get their contents with `content = require(filename)`. Sounds like it would be a…

I think there's an important difference between code used by a tool you employ, and dependencies you're actually bringing into your app that will be around at runtime. Your example seems like the former.
Post reply on HN