Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can we reduce dependency count to make this actiually minimal ? Readme says minimal dependencies but actually has 165 dependencies which is absolutely insane. #48

Open
Raynos opened this issue Aug 23, 2023 · 13 comments

Comments

@Raynos
Copy link

Raynos commented Aug 23, 2023

  • string.prototype.replaceall seems like an excessive dependency to use here when we can use regex replace with the g parameter. ( https://stackoverflow.com/a/17606289 ) there are alternative implementations that take 4 lines instead of 30 npm packages.
  • readable-stream ; this seems excessive, it's a large package and a duplicate of require('stream')

Leaving minimist as is seems ok, but I'd also inline all the argument parsing and go for zero dependencies. But at least I understand the purpose of it.

@Raynos
Copy link
Author

Raynos commented Aug 23, 2023

raynos at system76-pc  
~/soundxyz/test123
$ npm ls --depth 9999 | wc -l
167

The test package claims to have minimal dependencies but has 167 transitive dependencies because string.prototype.replaceall is the literal definition of dependency hell and over engineering.

@Raynos
Copy link
Author

Raynos commented Aug 23, 2023

test123@1.0.0 /home/raynos/soundxyz/test123
└─┬ test@3.3.0
  ├── minimist@1.2.8
  ├─┬ readable-stream@4.4.2
  │ ├─┬ abort-controller@3.0.0
  │ │ └── event-target-shim@5.0.1
  │ ├─┬ buffer@6.0.3
  │ │ ├── base64-js@1.5.1
  │ │ └── ieee754@1.2.1
  │ ├── events@3.3.0
  │ ├── process@0.11.10
  │ └─┬ string_decoder@1.3.0
  │   └── safe-buffer@5.2.1
  └─┬ string.prototype.replaceall@1.0.7
    ├─┬ call-bind@1.0.2
    │ ├── function-bind@1.1.1
    │ └── get-intrinsic@1.2.1 deduped
    ├─┬ define-properties@1.2.0
    │ ├─┬ has-property-descriptors@1.0.0
    │ │ └── get-intrinsic@1.2.1 deduped
    │ └── object-keys@1.1.1
    ├─┬ es-abstract@1.22.1
    │ ├─┬ array-buffer-byte-length@1.0.0
    │ │ ├── call-bind@1.0.2 deduped
    │ │ └── is-array-buffer@3.0.2 deduped
    │ ├─┬ arraybuffer.prototype.slice@1.0.1
    │ │ ├── array-buffer-byte-length@1.0.0 deduped
    │ │ ├── call-bind@1.0.2 deduped
    │ │ ├── define-properties@1.2.0 deduped
    │ │ ├── get-intrinsic@1.2.1 deduped
    │ │ ├── is-array-buffer@3.0.2 deduped
    │ │ └── is-shared-array-buffer@1.0.2 deduped
    │ ├── available-typed-arrays@1.0.5
    │ ├── call-bind@1.0.2 deduped
    │ ├─┬ es-set-tostringtag@2.0.1
    │ │ ├── get-intrinsic@1.2.1 deduped
    │ │ ├── has-tostringtag@1.0.0 deduped
    │ │ └── has@1.0.3 deduped
    │ ├─┬ es-to-primitive@1.2.1
    │ │ ├── is-callable@1.2.7 deduped
    │ │ ├─┬ is-date-object@1.0.5
    │ │ │ └── has-tostringtag@1.0.0 deduped
    │ │ └─┬ is-symbol@1.0.4
    │ │   └── has-symbols@1.0.3 deduped
    │ ├─┬ function.prototype.name@1.1.5
    │ │ ├── call-bind@1.0.2 deduped
    │ │ ├── define-properties@1.2.0 deduped
    │ │ ├── es-abstract@1.22.1 deduped
    │ │ └── functions-have-names@1.2.3
    │ ├── get-intrinsic@1.2.1 deduped
    │ ├─┬ get-symbol-description@1.0.0
    │ │ ├── call-bind@1.0.2 deduped
    │ │ └── get-intrinsic@1.2.1 deduped
    │ ├─┬ globalthis@1.0.3
    │ │ └── define-properties@1.2.0 deduped
    │ ├─┬ gopd@1.0.1
    │ │ └── get-intrinsic@1.2.1 deduped
    │ ├── has-property-descriptors@1.0.0 deduped
    │ ├── has-proto@1.0.1
    │ ├── has-symbols@1.0.3 deduped
    │ ├─┬ has@1.0.3
    │ │ └── function-bind@1.1.1 deduped
    │ ├─┬ internal-slot@1.0.5
    │ │ ├── get-intrinsic@1.2.1 deduped
    │ │ ├── has@1.0.3 deduped
    │ │ └─┬ side-channel@1.0.4
    │ │   ├── call-bind@1.0.2 deduped
    │ │   ├── get-intrinsic@1.2.1 deduped
    │ │   └── object-inspect@1.12.3 deduped
    │ ├─┬ is-array-buffer@3.0.2
    │ │ ├── call-bind@1.0.2 deduped
    │ │ ├── get-intrinsic@1.2.1 deduped
    │ │ └── is-typed-array@1.1.12 deduped
    │ ├── is-callable@1.2.7
    │ ├── is-negative-zero@2.0.2
    │ ├── is-regex@1.1.4 deduped
    │ ├─┬ is-shared-array-buffer@1.0.2
    │ │ └── call-bind@1.0.2 deduped
    │ ├─┬ is-string@1.0.7
    │ │ └── has-tostringtag@1.0.0 deduped
    │ ├─┬ is-typed-array@1.1.12
    │ │ └── which-typed-array@1.1.11 deduped
    │ ├─┬ is-weakref@1.0.2
    │ │ └── call-bind@1.0.2 deduped
    │ ├── object-inspect@1.12.3
    │ ├── object-keys@1.1.1 deduped
    │ ├─┬ object.assign@4.1.4
    │ │ ├── call-bind@1.0.2 deduped
    │ │ ├── define-properties@1.2.0 deduped
    │ │ ├── has-symbols@1.0.3 deduped
    │ │ └── object-keys@1.1.1 deduped
    │ ├─┬ regexp.prototype.flags@1.5.0
    │ │ ├── call-bind@1.0.2 deduped
    │ │ ├── define-properties@1.2.0 deduped
    │ │ └── functions-have-names@1.2.3 deduped
    │ ├─┬ safe-array-concat@1.0.0
    │ │ ├── call-bind@1.0.2 deduped
    │ │ ├── get-intrinsic@1.2.1 deduped
    │ │ ├── has-symbols@1.0.3 deduped
    │ │ └── isarray@2.0.5
    │ ├─┬ safe-regex-test@1.0.0
    │ │ ├── call-bind@1.0.2 deduped
    │ │ ├── get-intrinsic@1.2.1 deduped
    │ │ └── is-regex@1.1.4 deduped
    │ ├─┬ string.prototype.trim@1.2.7
    │ │ ├── call-bind@1.0.2 deduped
    │ │ ├── define-properties@1.2.0 deduped
    │ │ └── es-abstract@1.22.1 deduped
    │ ├─┬ string.prototype.trimend@1.0.6
    │ │ ├── call-bind@1.0.2 deduped
    │ │ ├── define-properties@1.2.0 deduped
    │ │ └── es-abstract@1.22.1 deduped
    │ ├─┬ string.prototype.trimstart@1.0.6
    │ │ ├── call-bind@1.0.2 deduped
    │ │ ├── define-properties@1.2.0 deduped
    │ │ └── es-abstract@1.22.1 deduped
    │ ├─┬ typed-array-buffer@1.0.0
    │ │ ├── call-bind@1.0.2 deduped
    │ │ ├── get-intrinsic@1.2.1 deduped
    │ │ └── is-typed-array@1.1.12 deduped
    │ ├─┬ typed-array-byte-length@1.0.0
    │ │ ├── call-bind@1.0.2 deduped
    │ │ ├─┬ for-each@0.3.3
    │ │ │ └── is-callable@1.2.7 deduped
    │ │ ├── has-proto@1.0.1 deduped
    │ │ └── is-typed-array@1.1.12 deduped
    │ ├─┬ typed-array-byte-offset@1.0.0
    │ │ ├── available-typed-arrays@1.0.5 deduped
    │ │ ├── call-bind@1.0.2 deduped
    │ │ ├── for-each@0.3.3 deduped
    │ │ ├── has-proto@1.0.1 deduped
    │ │ └── is-typed-array@1.1.12 deduped
    │ ├─┬ typed-array-length@1.0.4
    │ │ ├── call-bind@1.0.2 deduped
    │ │ ├── for-each@0.3.3 deduped
    │ │ └── is-typed-array@1.1.12 deduped
    │ ├─┬ unbox-primitive@1.0.2
    │ │ ├── call-bind@1.0.2 deduped
    │ │ ├── has-bigints@1.0.2
    │ │ ├── has-symbols@1.0.3 deduped
    │ │ └─┬ which-boxed-primitive@1.0.2
    │ │   ├─┬ is-bigint@1.0.4
    │ │   │ └── has-bigints@1.0.2 deduped
    │ │   ├─┬ is-boolean-object@1.1.2
    │ │   │ ├── call-bind@1.0.2 deduped
    │ │   │ └── has-tostringtag@1.0.0 deduped
    │ │   ├─┬ is-number-object@1.0.7
    │ │   │ └── has-tostringtag@1.0.0 deduped
    │ │   ├── is-string@1.0.7 deduped
    │ │   └── is-symbol@1.0.4 deduped
    │ └─┬ which-typed-array@1.1.11
    │   ├── available-typed-arrays@1.0.5 deduped
    │   ├── call-bind@1.0.2 deduped
    │   ├── for-each@0.3.3 deduped
    │   ├── gopd@1.0.1 deduped
    │   └── has-tostringtag@1.0.0 deduped
    ├─┬ get-intrinsic@1.2.1
    │ ├── function-bind@1.1.1 deduped
    │ ├── has-proto@1.0.1 deduped
    │ ├── has-symbols@1.0.3 deduped
    │ └── has@1.0.3 deduped
    ├── has-symbols@1.0.3
    └─┬ is-regex@1.1.4
      ├── call-bind@1.0.2 deduped
      └─┬ has-tostringtag@1.0.0
        └── has-symbols@1.0.3 deduped

@Raynos Raynos changed the title Can we reduce dependency count to make this more minimal ? Can we reduce dependency count to make this actiually minimal ? Readme says minimal dependencies but actually has 165 dependencies which is absolutely insane. Aug 23, 2023
@Raynos
Copy link
Author

Raynos commented Aug 23, 2023

I'm being a little bit unfair

aynos at system76-pc  
~/soundxyz/test123
$ npm ls --depth 9999 | grep -v deduped
test123@1.0.0 /home/raynos/soundxyz/test123
└─┬ test@3.3.0
  ├── minimist@1.2.8
  ├─┬ readable-stream@4.4.2
  │ ├─┬ abort-controller@3.0.0
  │ │ └── event-target-shim@5.0.1
  │ ├─┬ buffer@6.0.3
  │ │ ├── base64-js@1.5.1
  │ │ └── ieee754@1.2.1
  │ ├── events@3.3.0
  │ ├── process@0.11.10
  │ └─┬ string_decoder@1.3.0
  │   └── safe-buffer@5.2.1
  └─┬ string.prototype.replaceall@1.0.7
    ├─┬ call-bind@1.0.2
    │ ├── function-bind@1.1.1
    ├─┬ define-properties@1.2.0
    │ ├─┬ has-property-descriptors@1.0.0
    │ └── object-keys@1.1.1
    ├─┬ es-abstract@1.22.1
    │ ├─┬ array-buffer-byte-length@1.0.0
    │ ├─┬ arraybuffer.prototype.slice@1.0.1
    │ ├── available-typed-arrays@1.0.5
    │ ├─┬ es-set-tostringtag@2.0.1
    │ ├─┬ es-to-primitive@1.2.1
    │ │ ├─┬ is-date-object@1.0.5
    │ │ └─┬ is-symbol@1.0.4
    │ ├─┬ function.prototype.name@1.1.5
    │ │ └── functions-have-names@1.2.3
    │ ├─┬ get-symbol-description@1.0.0
    │ ├─┬ globalthis@1.0.3
    │ ├─┬ gopd@1.0.1
    │ ├── has-proto@1.0.1
    │ ├─┬ has@1.0.3
    │ ├─┬ internal-slot@1.0.5
    │ │ └─┬ side-channel@1.0.4
    │ ├─┬ is-array-buffer@3.0.2
    │ ├── is-callable@1.2.7
    │ ├── is-negative-zero@2.0.2
    │ ├─┬ is-shared-array-buffer@1.0.2
    │ ├─┬ is-string@1.0.7
    │ ├─┬ is-typed-array@1.1.12
    │ ├─┬ is-weakref@1.0.2
    │ ├── object-inspect@1.12.3
    │ ├─┬ object.assign@4.1.4
    │ ├─┬ regexp.prototype.flags@1.5.0
    │ ├─┬ safe-array-concat@1.0.0
    │ │ └── isarray@2.0.5
    │ ├─┬ safe-regex-test@1.0.0
    │ ├─┬ string.prototype.trim@1.2.7
    │ ├─┬ string.prototype.trimend@1.0.6
    │ ├─┬ string.prototype.trimstart@1.0.6
    │ ├─┬ typed-array-buffer@1.0.0
    │ ├─┬ typed-array-byte-length@1.0.0
    │ │ ├─┬ for-each@0.3.3
    │ ├─┬ typed-array-byte-offset@1.0.0
    │ ├─┬ typed-array-length@1.0.4
    │ ├─┬ unbox-primitive@1.0.2
    │ │ ├── has-bigints@1.0.2
    │ │ └─┬ which-boxed-primitive@1.0.2
    │ │   ├─┬ is-bigint@1.0.4
    │ │   ├─┬ is-boolean-object@1.1.2
    │ │   ├─┬ is-number-object@1.0.7
    │ └─┬ which-typed-array@1.1.11
    ├─┬ get-intrinsic@1.2.1
    ├── has-symbols@1.0.3
    └─┬ is-regex@1.1.4
      └─┬ has-tostringtag@1.0.0

raynos at system76-pc  
~/soundxyz/test123
$ npm ls --depth 9999 | grep -v deduped | wc -l
69

It's only 67 dependencies, not 167.

@ljharb
Copy link
Member

ljharb commented Aug 23, 2023

util.parseArgs exists now, so that seems like a viable way to replace minimist, at least.

@Raynos
Copy link
Author

Raynos commented Aug 23, 2023

Oh wow i didn't know that, I've been using horrible horrible code for a while now

const IS_DRY_RUN = process.argv.includes('--dry-run', 1);

// or 
  const maxSizeArg = argv.find(x => x.startsWith('--max-size='))
  const maxSize = maxSizeArg && maxSizeArg.split('=')[1]

@Raynos
Copy link
Author

Raynos commented Aug 23, 2023

Although util.parseArgs does not match nodejs 14 so it breaks compat. Where as require('stream') is pretty stable since nodejs 14.

The readable-stream package was more a streams 1 / 2 / 3 ; for nodejs 0.8 0.10 0.12 4.0 artifact.

@juliangruber
Copy link
Member

juliangruber commented Aug 24, 2023

  • please refrain from judgements like "insane", we all have different ways to write programs
  • I agree the dependency tree of string.prototype.replaceall could be optimized. I have chosen it because i expect it to behave as close to the original as possible, with any kind of argument types provided
    • if we drop node 14 support (out of maintanance) we can remove it
    • otherwise, finding a replacement that is 100% correct could be tricky
  • +1 to using util.parseArgs, and creating a ponyfill for older node versions
  • we're using readable-stream because some imports reach deep into its files, impossible (or risky) with core
> require('stream/lib/internal/streams/operators')
Uncaught Error: Cannot find module 'stream/lib/internal/streams/operators'

@benjamingr
Copy link
Member

replaceAll exists Natively in Node.js 16+ which itself is soon EoL, we should just use the native versions probably.

@ljharb
Copy link
Member

ljharb commented Aug 24, 2023

@juliangruber re string.prototype.replaceall, i doubt it can be while retaining the same robustness, back compat, and correctness, but i'm certainly open to PRs.

@aduh95

This comment was marked as duplicate.

@Raynos
Copy link
Author

Raynos commented Aug 25, 2023

Great, then I see a path towards this package having zero dependencies. which is exciting.

@benjamingr
Copy link
Member

@Raynos now would be a good time to say that PRs are welcome :)

@Raynos
Copy link
Author

Raynos commented Aug 28, 2023

I'll open a PR if I get time or it becomes my problem.

Right now my problem is that I use ava and that's a big problem. using test would be a step in the right direction, need to implement a codemod to auto port all the tests 😢

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants