nodejs / node

Node.js JavaScript runtime ✨🐢🚀✨
https://nodejs.org
Other
107.43k stars 29.52k forks source link

Discussion: How should the Node executable + Node shared library be distributed? #24028

Closed empyrical closed 4 years ago

empyrical commented 5 years ago

One thing that came up in this issue was, if the default Node distributions were to ship with a shared build, how should it be structured?

Basically boils down to:

Discussion was pretty contentious and I think it is worth its own issue!

Trott commented 5 years ago

@nodejs/releasers might have opinions/insights?

refack commented 5 years ago

Personally I like this discussion, and I'm happy it pops up from time to time in various forms (https://github.com/nodejs/node/issues/14158, https://github.com/nodejs/node/pull/23202, https://github.com/nodejs/node/pull/9652, https://github.com/nodejs/node/pull/17604, https://github.com/nodejs/node/issues/8118, https://github.com/nodejs/help/issues/585). A few points I have about this.

  1. Decomposing the node binary into a loader and lib is possible today with ./configure --shared
  2. The single file binary has major benefits for deployment, and in eliminating dependency hell. It does however cause trouble for dependants (i.e. embeders and native addons).
  3. Testing and releasing another binary package for all platforms is a big task for the BuildWG, and might be a big hindrance for CI testing.

We could also consider a hybrid solution, a single and complete binary that during bootstrap checks for an overriding libnode.lib and dynamically loads it if found.

/CC @nodejs/delivery-channels

rvagg commented 5 years ago

IMO this is up to folks distributing Node. So @kapouer for instance might do a node -> libnode setup on Debian, so you have both. I don't imagine this is something that we should be doing on our end though. Folks coming to nodejs.org to download are expecting to get a usable package so they can run node. If you're wanting libnode then you're probably consuming something else, and that something else should be responsible for installing libnode or making sure it's installed on the system via a package manager. Applications that consume libnode are going to be optimizing for installability and usability and inserting us into that mix is unlikely to be acceptable. Imagine VS Code (or other popular Electron app) saying "to use this, first download and install Node.js". libnode is just an incidental, like libsqlite might be.

refack commented 5 years ago

Folks coming to nodejs.org to download are expecting to get a usable package so they can run node.

IIUC the suggestion is libnode + a thin loader. Among the arguments pro that were raised:

  1. It's more intuitive to link native-addons against a library then an executable
  2. A shared library is easier to version, and make sure native-addon binaries are matched to the right file by version.

And I might add that having a fragmented file structure makes for a simpler build flow (on change you only need to rebuild the single changed DLL, this definatly has dev-time benefits)

Aside: I'm bigly pro-monolith for the distributed binary, but IMO it's a good discussion to have. And I think this - image is Gaia's way to say she's also pro monolith.

mhdawson commented 5 years ago

@rvagg I think the thing you miss in the discussion is that unless we have a package which includes the shared library, that forces consumers to compile/build node. In addition to being something they may not want/need to do it likely makes getting support harder since they are not using a standard library provided by the community.

If you look at Java as an example, there are lots of applications that load Java as a Shared library and they do so by using the library provided in the standard downloads. No need to pull and build from source.

rvagg commented 5 years ago

Java's a bit different though, it's historically been provided closed-source so linking to it has required a binary. Node has always been easy to compile and embedders are already including compiling Node as part of their tooling. What I'd like to see are real examples of situations where having a Node shared library provided by us would be of benefit. In lieu of that, maybe some hypotheticals. I'm not seeing it aside from the Linux distribution case where they pathologically dynamically link everything possible. I really don't see a workflow for someone embedding Node where they say "before you use my great application, you first have to download and install Node" when they could very easily just build and embed their own libnode.so and make it part of their distribution. There's no licensing or even practical reason for embedders to make their users jump through additional hoops. You're even seeing a lot of applications built around Java distributing their own version of the JVM these days because licensing restrictions allow it and the history of "first get Java and/or make sure you have at least version X, before you can run my thing" is fading.

Here's probably the most popular end-user application still using the JVM:

minecraft_download minecraft_install

There's no separate JVM (IIRC there used to be), it's entirely integrated and it takes care of what JVM it has and keeping it up to date).

Show me an example of a popular, modern end-user application that embeds or uses a runtime that requires you to download the runtime separately. Users hate hoops, just let me install the one thing.

Hence, my argument here is that we'd be opting for complexity on our end with very low likelihood of any benefit for anyone.

IMO we'd be much better off focusing on ./configure --shared and fixing the problems in our code highlighted by https://github.com/rubys/node-embed

jasnell commented 4 years ago

There's been no further discussion in over a year. Closing