Open mikeal opened 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.
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.
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 :)
@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.
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.
@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.
Oh, well, yeah, I think we should do the latter regardless :)
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.
<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.
@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.
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 &
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"
.
Or, you know, using the engines
field, because that's what it was designed for.
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.
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.
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.
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
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.
more relevant binaries-on-npm hax https://www.npmjs.com/package/atom-shell (view source)
+1 to using the engines field for something useful. XD
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