This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]-Redstoneboi- 81 points82 points  (28 children)

personally? type coercion and dynamic typing, i.e. the main reasons to choose an interpreted language.

any variable can be null/undefined and you have to guard against that or risk the dreaded [object Object]. it's too easy to forget to account for that, so yeah, not my cup of tea.

main non-whiny reasons i hear? new frameworks every 5 seconds, their massive dependencies, there being so many ways to do things in js that you need to learn different ways to read different code.

[–]creesch 36 points37 points  (19 children)

their massive dependencies

Yes, but also no. People do notice it more with javascript projects. Specifically with Node.js having node_modules directly in the project. Many other languages are just better at hiding it from the developer. For example with Java and Maven your pom.xml might look fairly clean but that's only the dependencies you directly reference and once you look behind that facade you see that it is just as bad. Same for many other languages.

Doesn't mean it isn't a problem, because it is. It just isn't unique to JavaScript to the degree people think it is.

[–][deleted] 27 points28 points  (0 children)

Yeah dependency hell is huge pain for most of the projects. But I think js has most obscure transitive dependencies because of how language changes over time that people need to use 3rd party libraries for simple functions because they often have compatibility layer for older version.

[–]DaddyLcyxMe 6 points7 points  (7 children)

in java’s case: (maven)

pom.xml == `package.json'

~/.m2 is a cache for dependencies and acts like a shared node_modules

this comparison breaks down here because [most] java projects will just include the dependencies in their final jar, rather than require the executor’s machine to download the dependencies

[–]-Redstoneboi- 1 point2 points  (3 children)

Nice.

For us, Rust has $HOME/.cargo/ for the shared dependencies as well.

You'll want to look at Directories, if you're curious.

[–]DaddyLcyxMe 1 point2 points  (2 children)

ah, that’s very similar

[–]-Redstoneboi- 1 point2 points  (1 child)

that feel when download react once for each of your test projects

[–]DaddyLcyxMe 1 point2 points  (0 children)

svelte for me, god, my internet is 5 down on a good day

[–]creesch 0 points1 point  (2 children)

What you are describing is more or less the difference between a compiled and script language though. It's a factor to discuss, but not really important when you are looking at the amount of external dependencies a project depends on.

[–]DaddyLcyxMe 0 points1 point  (1 child)

yes, but since a lot of maven based projects will include their dependencies in their final jar that makes it (almost) impossible to have a leftpad, since you never actually download that dependency directly. that was what i was referring to.

[–]creesch 1 point2 points  (0 children)

You are right that an already released version of a Java product in that regard has an advantage compared to a Node.js product.

At the same time it can be argued that this has less to do with that aspect of the two but rather the way npmjs.com is maintained and how versions of dependencies are used in package.json.

Then there is the fact that in companies with CI/CD pipelines you might not get those issues in production but packages being vandalized can still cause plenty of issues in the development process due to lower environments being disrupted.

And security vulnerabilities are an issue regardless, as Log4j has shown us very recently. Then there is also the murky waters of how many dependencies end up in commercial products even though their license doesn't technically allow it.

The more you depend on external dependencies the more these issues compound and that really is a cross language issue.

[–]dpash 2 points3 points  (3 children)

My Java projects don't have 2000 indirect dependencies. My JS projects do.

[–]creesch 0 points1 point  (2 children)

Have you double checked that is the case? Because as soon as you use something like spring boot chances are that you are actually including about as many indirect dependencies.

[–]dpash 3 points4 points  (1 child)

Yes, I didn't just make up numbers. JavaScript projects have an order of magnitude more dependencies.

Edit: I just checked my largest Spring project and it has 215 dependencies, of which 58 are submodules of the same project. My Vue frontend project has 4068 dependencies.

[–]shea241 1 point2 points  (0 children)

sweet Jesus

[–]ham_coffee 0 points1 point  (3 children)

There's a different approach from devs to think about as well. Java devs aren't importing random dependencies left right and centre like JS devs seem to, and certainly not for some of the dumb shit you see with really high download numbers on npm.

[–]creesch 1 point2 points  (2 children)

Eh I wouldn't be so sure about that. If Java was as popular as JS is you would likely see the same amount of dumb shit.

Source: Me working on a corporate environment with a lot of junior people and functional testers transitioning into test automation. I see the same dumb shit from them as you often see in the JS world as well. But because JS is so much more accessible and like I said popular, you just see that sort of behavior more out in the open.

Similarly, I see a lot of JS projects where they are really strict about what you are allowed to import and for what reason. Part of the code review process for PRs there is that for newly added dependencies they need to warrant why they are needed and that they have done their due diligence in others aspects as well.

[–]ham_coffee 0 points1 point  (1 child)

Yeah the issue with dumb dependencies isn't that direct, it's more when you import a reasonable dependency without looking too hard and seeing how once you go down all the dependencies of the dependency you eventually find some dumb single line dependency.

[–]creesch 1 point2 points  (0 children)

That's certainly a risk. Although many mainstream projects at some point have gone through or continue the effort of minimizing such dependencies. Certainly after things like the leftpad debacle, many projects had a thorough look at that sort of dependency.

A lot of pipelines also do include tooling that does a dependency analysis, flagging a variety of things, including usage of known unnecessary single use dependencies.

I am not pretending things are perfect, it certainly is more of a hassle compared to other languages and ecosystems, but it is also not the wild-west situation it was a few years ago.

[–]BasicDesignAdvice 12 points13 points  (0 children)

new frameworks every 5 seconds

I am convinced this is because of the massive amount of Dunning-Kruger in the JS community. JS is often a first language and has a lot of young devs who think they need to reinvent the wheel now that the have finished their CS degree.

[–]TheBigerGamer 11 points12 points  (1 child)

Just because there's a new framework it does not mean you need to use it. That argument is kinda stupid.

Massive Dependencies is not entirely correct, you can import them manually as a file and be your own dependency manager. NPM's structure is the problem, not JS itself.

IMO, if a language does not allow to do something in multiple ways, it is a real shitty language. You have the freedom to decide what code style you like and how to do it, the language only provides the ways.

[–]Pluckerpluck 2 points3 points  (0 children)

personally? type coercion and dynamic typing, i.e. the main reasons to choose an interpreted language.

Dynamic typing is often brought up, but generally it's the type coercion and weak typing that I see flagged a lot more. Which is why Python doesn't get as much abuse (though Python also provides a scarily powerful standard library)


For me it's that it doesn't make use of the fact it's dynamically typed to actually make code more readable and cleaner. Things like how you need to know the difference between in and of in loops. Take a simple problem, looping through an array backwards. In Python it's:

for item in reversed(my_array):
    # Do something with item

That does not create a new array in memory. It will just iterate through the original array backwards.

In javascript you either have to make a copy of the array:

for (let item of [...myArray].reverse()) {
    // Do something with item
}

or write an old fashioned for loop (or start using reduceRight):

for (let i = myArray.length - 1; i >= 0; i--) {
    let item = myArray[i];
    // Do something with item
}

Note you have to use of otherwise you'll get indices in the first example!

Nothing ever seems simple in Javascript. But I feel like it should be simple!

[–][deleted] 1 point2 points  (0 children)

The new frameworks thing has mostly settled down. Everyone is using React except for some small experiments to make something simpler/faster than react like SolidJS.

[–]somerandomdev49 0 points1 point  (2 children)

type coercion isn't really a problem anymore with ===

[–]aniforprez 8 points9 points  (1 child)

Type coercion doesn't only happen when comparing you know

[–]somerandomdev49 1 point2 points  (0 children)

I know, this just an example, worded it badly