nodejs / NG

Next Generation JavaScript IO Platform
103 stars 12 forks source link

Localized io.js install. #2

Open mikeal opened 9 years ago

mikeal commented 9 years ago

This has come up in a few threads and is something @rauchg has been on about for a while.

For applications, should people set their required version of the platform in package.json and have npm install and run it all locally?

Upsides/Downsides?

@othiym23

chrisdickinson commented 9 years ago

At present, the platform is an implicit "iojs": "*" dep that each package in the tree has that must be resolved to a single version number.

Is the desire of this feature request to make that dependency explicit, and then have npm determine that number and install the correct version? I.e., how good does dedupe need to be for this to happen? Does npm become nvm? What happens when packages disagree on platform requirements – if we leave it up to the package author, the potential for setting a bad value is huge, as is the downside if they do.

mikeal commented 9 years ago

This isn't an existing feature of npm. It would look something like:

{"iojs":"1.4.0",
 "name": "myapp",
 "dependencies": {...} }

When you run npm install it will pull down iojs 1.4.0 and install it in to a subfolder. Now when you do npm start it'll run with the local version of iojs, not the globally installed one.

chrisdickinson commented 9 years ago

When you run npm install it will pull down iojs 1.4.0 and install it in to a subfolder. Now when you do npm start it'll run with the local version of iojs, not the globally installed one.

But only for the top-level package? If so, then I'm pretty much okay with this as it's just npm absorbing nvm as a feature; if it was doing more complicated negotiation of a common io.js version between packages (like I suggested above) I'd be a little bit more worried :)

mikeal commented 9 years ago

@chrisdickinson right, only for the top level package, that's why I was using the term application rather than package. Clearly we have to globalize the platform and vm to a system process, this is just a way to do that without globalizing it for the entire operating system.

domenic commented 9 years ago

So this really is just about rolling nvm into npm, interesting. I mean, I guess +1 from me, although ultimately it's the npm team's call whether they want to spend time on that feature.

mikeal commented 9 years ago

@domenic the reason I bring it up here is that if there is wide enough acceptance that this is a good idea we can build on top of this to potentially localize versions of a standard library, if we were so inclined.

domenic commented 9 years ago

Oh, well, yeah, I think we should do the latter regardless :)

rauchg commented 9 years ago

Definitely should be embraced. A large number of developers that spend a significant amount of time working with Node have a tool like nvm or n installed.

And also because it provides much-needed encapsulation for binaries.

rauchg commented 9 years ago

<argument about containers solving this problem />

Each container is hundreds of MBs in size, and an additional toolchain to install. This problem can be solved with the file-system tweaks in the same way that we made node_modules local instead of global.

mikeal commented 9 years ago

@rauchg in addition, I think there are entirely valid use cases where people want to run multiple processes on a single machine for different micro-services and would want them to run on different versions of the platform. doing that now is a pain in the ass, this would help.

rauchg commented 9 years ago

Definitely. Which is why addressing the /usr/bin/env node situation is the next logical step. Binaries need to be wrapped to actually summon the right version of node/iojs whatever overriding the inherently-global shebang declaration.

Then you just do:

$ npm install -g micro_service_1 micro_service_2
$ nohup micro_service_1 &
$ nohup micro_service_2 &
othiym23 commented 9 years ago

I have no objection to this as a feature, but there is little if no room for working on this in the npm roadmap for the foreseeable future, so it's a feature that would have be built by the TC or community.

As a tiny bikeshed (mostly because I can't help myself), something like "platform": "iojs@^2.43.18" seems a lot less brittle than "io.js": "19.12.1".

othiym23 commented 9 years ago

Or, you know, using the engines field, because that's what it was designed for.

rvagg commented 9 years ago

I know I'm not going to be popular with npm folk but there's probably scope to explore a package manager NG here too. Even just something like a replacement for npm install without all the huge complexity.

iarna commented 9 years ago

Today you can already do:

"dependencies": { "iojs-bin": "^1.2.0" }

Thanks to a clever hack from @aredridel (node-bin is also available as a dep.)

It works pretty much exactly is @mikeal describes, except without having to change npm. But since I like paving cow paths, that seems like a fine idea to me.

That is, anything run from a lifecycle script or via npm start will run with the specified version of iojs/node, in preference to the system version.

aredridel commented 9 years ago

As far as paving cow-paths goes, that package would be a lot more elegant if it could express its platform-dependent dependency in npm. How we handle platform-specific binaries in general could play out here.

joshhartigan commented 9 years ago

I'm not a 'proper' member of the io.js community so I could be getting something wrong here, but if the plans are for io.js to eventually merge into node, wouldn't it better to have a key of "node": "*" rather than "io.js": "*"?

edit: or "platform": "*" as @othiym23 suggested

aredridel commented 9 years ago

As a hack, I created the iojs-bin and node-bin packages; because we don't have architecture-specific dependencies, I added a preinstall script that runs another npm install to install the actual binary for the correct architecture (I've punted on Windows for now)

The magic is https://github.com/aredridel/iojs-bin/blob/iojs-v1/package.json#L7 and the index.js in that package that spits out the right package name for the sub-install.

It relies on specific behavior of npm that probably won't change but isn't entirely documented -- the order and timing of linking bins in -- but works as it is.

If we had architecture-specific dependencies, we could do this a bit more cleanly and declaratively, but this works remarkably well. iojs ends up just being another dependency -- anything that runs npm is good enough to install an app that requires iojs.

PS. Don't use -g to install iojs-bin. The magic smokes leaks out and you have to put out the fire.

max-mapper commented 9 years ago

more relevant binaries-on-npm hax https://www.npmjs.com/package/atom-shell (view source)

jfhbrook commented 9 years ago

+1 to using the engines field for something useful. XD