Skip to content
This repository has been archived by the owner on Dec 6, 2023. It is now read-only.

Read node version from package.json #10

Open
airtonix opened this issue Mar 3, 2015 · 41 comments
Open

Read node version from package.json #10

airtonix opened this issue Mar 3, 2015 · 41 comments

Comments

@airtonix
Copy link

airtonix commented Mar 3, 2015

Perhaps I'm missing something, but why not use the package.json? why are we creating another meta file that duplicates a piece of information about node that can already be stored in the package.json?

@ljharb
Copy link

ljharb commented Mar 3, 2015

That field is a) information-only, and b) identifies what something is supported with. That field can't be easily used to test a new version.

@wbyoung
Copy link
Owner

wbyoung commented Mar 4, 2015

I'm open to the idea of using another field in package.json to specify the version. As @ljharb mentions, it shouldn't be the engines. But I would want to replace (deprecate) the use of the .node-version file to keep the tool simple and also make sure it easily supports all use cases.

Here are some use cases that come to mind:

  1. A project/folder that doesn't actually use npm, simply uses node in some way.
  2. Having a project where you want a .node-version file that isn't version controlled. While this probably isn't the majority use case, it still seems like a nice to have.
  3. Writing a build/test script that changes the version being used by overwriting the .node-version file. This could be achieved instead by having that same script simply change the version used with the actual tool instead of using avn.
  4. Writing a build/test script that needs to read the node version being used, but is written in a language (like bash) that doesn't easily read JSON files. This could easily be considered to be that script writer's problem.

Another argument against this would be keeping things similar to the ruby tools, but there's not really a strongly compelling reason to do that.

At this point, I think it makes sense to stick with the .node-version file, but I still have an open mind about it and would love to start a dialog with anyone who wants to discuss.

@ghost
Copy link

ghost commented Mar 26, 2015

@ljharb, with regard to (a), isn't the engines property an actionable piece of information that allows platforms like Heroku to execute a series of processes that make the project associated with the package.json file usable?

Wouldn't the engines property allow a tool like avn to execute an action (such as nvm use x.y.z) to make the project associated with the package.json usable (such as actions, like building node modules, that require a supported version of Node).

As for (b), could you explain the deficiencies in the engines property that prevent it's use for testing? (For example, my impression is that once I'm in a folder that contains a package.json file with the Node version set to 0.10.x, that I'm not prevented from running nvm use 0.12 to test that it's compatible. I simply assume some risk that I may not have a good experience.)

@wbyoung
Copy link
Owner

wbyoung commented Jul 14, 2015

If #17 is completed, this may be less likely to change. It would complicate the code base to support .nvmrc as well as package.json.

@wbyoung wbyoung changed the title Why not zoidberg? Read node version from package.json Jul 14, 2015
@mockdeep
Copy link

mockdeep commented Dec 1, 2015

This would be handy. It's a little annoying having to keep the node version for our project up to date in 2 places. One simple pass would be to ignore it if an exact version is not specified.

@wbyoung
Copy link
Owner

wbyoung commented Dec 1, 2015

@mockdeep the only concern now is that avn searches for files containing version information. That function would need to be updated to scan for package.json and only consider it to be a file for versioning info if it contains engines. The function must be fast as it's invoked for every directory change.

Also, we would need to handle the file differently when it's read.

I'm open to these changes, and would want to decide if engines was truly the right property to read from, but that should be an easy adjustment once the code is written. PR welcome! 😄

@eiriklv
Copy link

eiriklv commented Dec 2, 2015

I just wanted to chime in on this;

We already use "engines": { "node": "x.x.x" } to make heroku install the correct node version for all our apps. If platforms are already doing this - why can't your local machine do that (with this tool)? It just seems redundant and error prone to have to maintain two separate fields/files that will always be identical.

@eiriklv
Copy link

eiriklv commented Dec 2, 2015

Other than that - love this - great work! :)

@ljharb
Copy link

ljharb commented Dec 2, 2015

@eiriklv engines takes a semver range, so it can match any number of node versions, not necessarily just one.

@eiriklv
Copy link

eiriklv commented Dec 2, 2015

@ljharb isn't that a good thing? :-)

@eiriklv
Copy link

eiriklv commented Dec 2, 2015

My point is - when this works really well on Heroku - why shouldn't it work great anywhere else..?

@eiriklv
Copy link

eiriklv commented Dec 2, 2015

Is the issue here shortcomings of the tool (that it only supports a specific version)?

@wbyoung
Copy link
Owner

wbyoung commented Dec 2, 2015

@eiriklv no shortcomings with avn, but the way that it works is to look at the installed versions that are available on the machine rather than attempting to install the latest.

So if you specify >= 0.12 <5.0 in engines and one developer has 0.12 installed while another has 4.2.2, they'll be using different versions when developing.

I don't consider this a problem — that's just how it works at the moment. Currently avn should allow you to specify a semver range in the .node-version file (though it's not documented & I don't believe it's tested either). So arguably, avn already exposes the possibility of developers using different versions.

I don't see the problem with a semver range in engines — it's a choice that teams can make. We can default to reading .node-version for projects that need a semver range, but want devs to use the same version when working on the project. Also, I feel the issue of which version gets used can be addressed via documentation.

@eiriklv
Copy link

eiriklv commented Dec 2, 2015

My main point here is - why add another (duplicate) reference to the node version when you already specify it in "engines". I don't want to have to keep things in sync :-)

@eiriklv
Copy link

eiriklv commented Dec 2, 2015

The optimal solution would be that avn would tell n or nvm to install/use the latest available version in the specified semver range

Edit: And thus behaving the same way on your local machine as on Heroku (as an example)
Edit2: Or am I missing the intention of this tool?

@wbyoung
Copy link
Owner

wbyoung commented Dec 3, 2015

@eiriklv that's more or less the intention, but without support from n and nvm, this tool won't be able to handle something like >= 0.12 <5.0. It can't just say n '<5.0', for instance.

It selects the lasted available version that's installed locally, not that's available out on the internet.

It could fetch a list of known node versions, but it would then require a network connection which has two issues:

  1. That's really slow when you cd into a directory
  2. This tool should work when you're not connected to a network (attempting to get a list of node versions, but fall back to using the best one installed feels like a bad/inconsistent user experience)

@ljharb
Copy link

ljharb commented Dec 3, 2015

Note that nvm, while it does not support semver ranges, does support partial identifiers - ie, x or x.y or x.y.z. Also, most of the commands only look locally - just ls-remote and install talk to the network.

@mockdeep
Copy link

mockdeep commented Dec 3, 2015

I'd be okay with choosing the most recent matching version that is installed. If people put a range, then they are responsible for dealing with the inconsistencies across versions themselves. Instead of installing it can just say "no compatible version of node installed" or the like. rvm does something along those lines:

ruby-1.8.7-head is not installed.
To install do: 'rvm install ruby-1.8.7-head'

@Kikobeats
Copy link

What is the status of this?

I was going to open an issue related with setup a default version if node-version file is not present, but this solution is better to force you have a good package.json.

@wbyoung
Copy link
Owner

wbyoung commented Jan 20, 2016

@Kikobeats this is still in the discussion phase — implementing this will require a decent number of changes. It also requires that we make decisions that are logical and appropriate for the community. Feel free to weigh in on the points discussed so far and continue the discussion.

@Kikobeats
Copy link

I think that is the right way. Now node devs need to handle with different node versions and is horrible the current workflow.

Could be implemented with backward compatibility: if .node-version file is detected, then use the version declared; in other case try to read the version of the package.json. I feel that only is necessary add read package step in the algorithm.

less is more!

@haoqunjiang
Copy link

So what is the status of this issue now?

It's been a year since it was opened.

@wbyoung
Copy link
Owner

wbyoung commented Mar 23, 2016

@sodatea still discussing, but I'm leaning toward it being a good idea.

I'm happy to accept a PR, but we still do need to figure out what key it should look for in package.json.

@Kikobeats
Copy link

I'm using nodengine for this purpose, more simple 😄

@rusty-key
Copy link

Is package.json still not supported?

I'm happy to accept a PR, but we still do need to figure out what key it should look for in package.json.

@wbyoung, what would be wrong with "engines"->"node". What are the other options?

@ljharb
Copy link

ljharb commented Feb 5, 2019

That’s a range, not a single version.

@rusty-key
Copy link

@ljharb doesn't .node-version work the same way?

@ljharb
Copy link

ljharb commented Feb 5, 2019

I believe that’s typically a single version. nvmrc is a “version-ish” which can be a range, but is expected to resolve to a single version. npm install has the expectstion that it will select the latest available matching version; i don’t think nvm use` or similar necessarily would have the same intuition.

@rusty-key
Copy link

I don't get it. What do you mean by "typically a single version"? To me it has exactly the same meaning as "engines" fields in packages.json — it specifies node versions that are compatible with my project.
What other meaning it can have? What would be the case when you specify one version in .node-version and other in package.json?

@ljharb
Copy link

ljharb commented Feb 7, 2019

The engines field is a semver range; it can describe >= 0.10 or < 11 or ^3 || ^4 || ^6 etc - when you type it, you’re explicitly including all versions that fit in that range; you’re not trying to point to a single one.

nvmrc is a specifier that points to a single version implicitly. When you type it, you’re referring to a range of possible versions, but your intention is that it resolves to a single one.

Conceptually, these are for two very different purposes, and the engines field isn’t a concept that directly maps to “a single node version to install”.

@rusty-key
Copy link

Maybe the problem is that we are talking about different stuff? I am not really familiar with nvmrc because I am using n, anv-n and .node-version.

The engines field is a semver range; it can describe >= 0.10 or < 11 or ^3 || ^4 || ^6 etc - when you type it, you’re explicitly including all versions that fit in that range; you’re not trying to point to a single one.

Sorry, I still don't get it. Wherever you use it, you'll end up with one resolved version of node, no?

https://docs.npmjs.com/files/package.json#engines
You can specify the version of node that your stuff works on

So I use it to specify version of node that my stuff works on. Then, for example, when my CI tries to build my stuff, it can look into this field and check wether version of node is ok and if not.

Now, I need to do the same thing, but for all developers who works on my stuff. I use .node-version. Because I want my CI to build the same stuff as we are working on, I will use the same range as I specified in package.json. Otherwise, it is possible, that succusessful local builds will become failed builds on CI.

What am I missing?

@ljharb
Copy link

ljharb commented Feb 7, 2019

(nvmrc and node-version are the same, conceptually)

@ljharb
Copy link

ljharb commented Feb 7, 2019

Yes, you certainly can take a range and end up with one resolved version - this isn’t a technical barrier, it’s a conceptual one. The mental model of “engines” is simply not appropriate to apply to “which node version should i be using with the project by default” because they are distinct concepts.

It’s certainly valid for you to chose to make them have identical texts (not that node-version of nvmrc should be semver; they’re a subset) - but that doesn’t mean that choice should be foisted on everyone else (iow, the things i put in the engines field for my packages should never be used to select which version to use, so this tool shouldn’t do that)

@rusty-key
Copy link

How are you using it? You are using narrower range or specific version in .node-version that is included in engines range?

The mental model of “engines” is simply not appropriate to apply to “which node version should i be using with the project by default” because they are distinct concepts.

I don't see what causes this conclusion. In official docs I see nothing about mental model of this field. It only says:

You can specify the version of node that your stuff works on

To me, it means:
"You can choose whatever version from this range, this app will work with it".

@rusty-key
Copy link

rusty-key commented Feb 7, 2019

I mean, if I am specifying versions of Node which my app supports, it would be strange that I am prohibiting some of them from using in development. No?

@ljharb
Copy link

ljharb commented Feb 7, 2019

@Bessonov that’s both full of a bunch of false claims and also off topic for the thread; let’s not get into that.

@ljharb
Copy link

ljharb commented Feb 7, 2019

@rusty-key nope. Babel 7 requires node 6+, for example, but i have packages using it that support back to node 0.10. I also have a repo where we have binary deps that require node 8 for dev, but the package works fine in production from 0.10 - 11.

@rusty-key
Copy link

Works fine and guaranteed to work fine are not the same. If I specify "engine", I give you some kind of guarantee that my package works with these node versions. It still can work with other versions, but I cannot be sure for some reasons.

Anyway, even if we decide that version file and engines field have different mental models (which I am still not convinced in 😄), I don't see how it prevents avn from using engines too. It could be a simple precedence rule: if there are no version files around, use any version that satisfies engines. Would that work?

@ljharb
Copy link

ljharb commented Feb 8, 2019

I don’t think that would be correct, no - i think the engines field is to declare compatibility, and can’t ever be correctly used to determine version switching absent an additional signal.

@tbntdima
Copy link

tbntdima commented Nov 7, 2019

Hey guys, are there any udpates on this?

@wbyoung
Copy link
Owner

wbyoung commented Nov 7, 2019

@DmitriyAA I'm still at a point of not feeling convinced either way as to whether it's a good idea or a bad one.

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

No branches or pull requests

9 participants