Package-maintenance: A practical approach is to only support the LTS version

Created on 19 Dec 2018  路  33Comments  路  Source: nodejs/package-maintenance

If the aim is to make sure that the enterprise can adopt and choose to subsequently support node then the LTS path makes the most sense. Enterprise upgrade less often and stick to the LTS versions.

We have to also be practical in that the weight of maintenance would eventually not be sustainable for anything other than the current LTS.

_Originally posted by @ghinks in https://github.com/_render_node/MDU6SXNzdWUzOTIyNzk4MTA=/issues/unread_timeline#issuecomment-448401317_

discussion

Most helpful comment

Maybe I am missing your point here, but it seems like we (this WG) should not be in the business of recommending a tooling infrastructure like this as a solution to node version support.

Node version support is easy in almost all cases, and we should treat it as such. No complicated tooling, no large concessions in the code, just look up which features are supported in the current LTS and only use those.

If you want to use something to author in a different language, GREAT! But that is a separate issue we should also not take an opinion on.

All 33 comments

I think it is worthwhile openly addressing what the intent and goals would be of only supporting LTS. My concern is that the work of doing otherwise will eventually not be practical.

I highly disagree that we should be encouraging this.

If I'm on node 4 (which is EOL), and I'm using a package that suddenly drops support for node 4, then my future node 6 upgrade is harder because i'd have to upgrade the package and the platform simultaneously. This happens all the time in practice.

The thing that ensures that people can most smoothly upgrade to the latest version of the platform is when packages support as far back as possible, to minimize variables and thus risk and complexity of the upgrade.

As I said here, supporting the current/future versions at the time of a major release is the only way to follow semver as dropping node version support is a breaking change. That being said, I agree with @ljharb on the goal being as wide of support for modules as possible.

@wesleytodd totally agree, in the sense that nothing about "only support LTS" or "support as far back as possible" either forces compliance nor violation of semver :-)

Yeah, I think my phrasing in both of those comments was ambiguous. My intent was to say that "changing node version support without major version bumping breaks semver". And secondly, the process express uses is to support all current and future supported node versions at the time of release. In the past this has been "as far back as possible" by happenstance (4.0 being years old now). With the release of 5.0 we will officially support all current supported versions, which will be 6 or 8 I think.

@wesleytodd my personal opinion is that that approach for express is fine as long as you're diligent about backporting both bugfixes and new features to v4; that way the upgrade from v4 to v5 will have minimal consequences for a user trying to upgrade to v5.

Yep, we are very diligent :)

Sadly this diligence coupled with the number of support requests we get means the 5.0 branch has been in development since 2015.

As a reference for this diligence: https://github.com/expressjs/express/pull/3714

This feature was made originally as a breaking change for 5.0, but we back ported it to 4 and it still might not land there lol.

Maybe could be a good practice to tag the older versions of a module with an @node4, @node6 etc.. where the @lastest supports the current/future versions instead?
I think this could help some semver errors

Unfortunately, the engine property on package.json is not so used (and engine-strict was removed)

That鈥檚 because declaring enforced explicit engine compat is harmful to the ecosystem; it鈥檚 a good thing npm no longer enforces it.

So I am glad there is lots of discussion on this topic. It is important to clarify what our intent is so we can fully understand the outcome of that intent. I was allowing a good gap between my initial post and my response. So @ljharb you are correct. It is best to support all. But we have to be practical. There will be a finite amount of work possible and the majority of users will not be using the older versions. I completely agree this is a brutal dictatorial view but this is a group of volunteers, energy and time must be allocated carefully.

  • Compromise will be inevitable
  • Resources will be finite
  • Enthusiasm may wane

My caution is based on the past eco systems that have waxed and waned. I know some of what I'm saying is a little unpalatable but I am counseling caution in our initial intent.

All of that is true! I鈥檓 claiming tho that the effort is minimal what with CI and babel :-) we鈥檒l have to look at it case by case.

All of that is true! I鈥檓 claiming tho that the effort is minimal what with CI and babel :-) we鈥檒l have to look at it case by case.

Node.js landed 280 breaking changes in Node 10.0.0. Depending on the module, maintaining support for different version of Node.js is _extremely hard_. Express was broken in Node.js 10 for more than 6 months without anybody noticing.

I maintained readable-stream@2 that worked from Node 0.8 to Node 8. I'm sorry, but the changes are not just on the language syntax (that you can easy polyfill), but also on changes in Node.js itself. Maintaining backward compatibility is hard work, and most maintainers prefer not to do it.

Node.js landed 280 breaking changes in Node 10.0.0.

Express was broken in Node.js 10 for more than 6 months without anybody noticing.

This is specifically what CITGM is for. The reason it was not caught was because the module effected was not in CITGM. If we had #84 this would go a long way to making this more manageable.

most maintainers prefer not to do it.

I think the opportunity here would be to help them do it. Things like common codemods we could provide would also help.

This is specifically what CITGM is for. The reason it was not caught was because the module effected was not in CITGM. If we had #84 this would go a long way to making this more manageable.

I 100% agree. I made this example to show that it is not simple to support multiple Node.js versions, and it is not only about JS syntax or transpiling. I think we could make it simpler.

From some of the discussions on other issues I think that as long as we can focus on a small number of key packages to begin with we could rest this until the number of packages being addressed would require a rethink of which node versions to support. Perhaps @ljharb focus on highly used express modules will provide enough scope to limit the work.
But this question of node versions will keep running till we cannot deliver or limit it to very defined modules. Perhaps not all modules get all node versions? That would be a practicle compromise.

I think it should be case by case. I鈥檝e seen very very few cases where it鈥檚 actually a requirement to drop support for any older engine; and even those can often be mitigated with minimal effort.

Slightly off topic, but in an effort to improve this I did this "poor mans" method of cross node version testing: https://github.com/wesleytodd/setprototypeof/pull/7/commits/fc0e119af5a0f0395fbf9b882a1d68eaec6d2f79

The original PR was in an effort to push forward support for https://github.com/nodejs/citgm/issues/631 but this was a nice way to run it locally with just docker.

I鈥檓 happy to help anyone set up their travis.yml for testing in virtually every minor version of node and io.js (like most of my packages); once set up it requires relatively minimal upkeep.

As suggested by @ljharb I went and looked at his travis.yml and took the bits for multiple node version builds and added it to one of mine. It was straight forward enough.

(Hopefully travis-ci adds some sort of shared config feature, at which point i could maintain the config for everyone with minimal consumer cost)

Should .travis.yml maintainenance be a bot? Or a feature in renovate and/or greenkeeper (using those is a best practice we need to advocate anyways)? Is there a way to engage with travis/appveyor to provide node master / next testing, but without marking the whole build as failed (i.e. treat these failures on a package as a warning, ideally feeding back to citgm)? Opt-in, ofc, but this group could then advocate that opting in on relevant repos.

Should .travis.yml maintainenance be a bot?

It would be nice if CI configuration was automated. Back when I used Travis CI, I would use the allow_failures option to enable _Current_ releases of Node in my build matrix, but allow it to fail until it became LTS.

It would be neat to see dependency upgrade platforms automate upgrading the build matrix.

It could even be used to feedback that information to Node (Community discussion on Renovate about creating a feedback mechanism. Other platforms may be considering the same.)

@ljharb would documenting the travis.yml creation as you have suggested be a good first "resource" for package maintainers to capture in this repo ?

Seems like we should work on putting together a section on the node site for these resources. Maybe in here? https://nodejs.org/en/docs/guides/

@wesleytodd that's probably a good place on the Node.js website. I'm a bit torn between starting by capturing some content in this repo and then when we have critical mass/concensus pushing it up to the website or just starting by pushing to the website.

I think that is a great idea. Maybe just start with a docs directory we can expand on and keep the PRs centralized?

@wesleytodd created this PR to add the docs and a docs/drafts directory that we can start using.

Considering #136 and this thread.

For what is is worth, @bevry got burned years ago when we upgraded to use a for of loop, which babel compiled in a way that broke node 0.10 which broke meteor as they used one of our packages.

Since then we publish everything with Editions https://editions.bevry.me which allows us to write our source in esnext, TypeScript, coffeescript whatever, and compile editions for each of our targets, then the edition autoloader then selects the best one for the users environment. Boundation https://github.com/bevry/boundation automates the edition creation for us, determining which editions are necessary for our targets.

But what about dev tooling like babel and eslint that only run on latest node? Well we have a solution to that too. https://github.com/bevry/awesome-travis will run compilation and linting using the desired node version (defaults to lts) but runs tests against the ci intended node version. Boundation also sets up this travis configuration automatically.

Maybe I am missing your point here, but it seems like we (this WG) should not be in the business of recommending a tooling infrastructure like this as a solution to node version support.

Node version support is easy in almost all cases, and we should treat it as such. No complicated tooling, no large concessions in the code, just look up which features are supported in the current LTS and only use those.

If you want to use something to author in a different language, GREAT! But that is a separate issue we should also not take an opinion on.

copy of my comment here https://github.com/nodejs/package-maintenance/issues/280#issuecomment-554855494


FWIW

@bevry accomplishes the goal of this automatically for all of its packages, through the following pieces

(cc @ghinks as you started this discussion)

Can we close this issue? I think the recommendations are covered in the testing and ci/cd guidelines (we advise all active release lines are supported). I will probably revisit the wording when I start working on #280. We also have the support levels so that people can indicate what they actually support.

+1 to closing

Was this page helpful?
0 / 5 - 0 ratings