Skip to content
This repository has been archived by the owner on Feb 2, 2024. It is now read-only.

Communicate AdonisJs version more efficiently #12

Closed
RomainLanz opened this issue Oct 8, 2018 · 24 comments
Closed

Communicate AdonisJs version more efficiently #12

RomainLanz opened this issue Oct 8, 2018 · 24 comments
Assignees

Comments

@RomainLanz
Copy link
Member

RomainLanz commented Oct 8, 2018

Hi everyone! 👋

Since the beginning, Adonis follows a modular approach with the Service Provider concept. When you look at your package.json file in a default boilerplate you will see many different packages added per default.

The issue with this approach is that people never knew which version of Adonis they are using because there’s none Adonis package. Adonis is many different packages that work together and not one big package.

Currently, you could be using Adonis 4.1 but having @adonisjs/lucid at version 6!

This is very confusing for newcomers and even people that are working daily with Adonis.

This is why I want to propose a Rolling Release system for Adonis!

What’s a Rolling Release System?

A Rolling Release is the concept of frequently delivering updates to an application instead of having a large major version. (If you are a Linux guy you can take as example Ubuntu which uses standard release and Arch Linux that follows the rolling release concept)

What that means for Adonis?

Adonis is already following this principle for its modules. Each module is individual and follows semver. This is why you are currently using @adonisjs/lucid at version 6 while Adonis is at version 4.1.

If this RFC is accepted, Adonis will have no version of itself. Only Modules will have their versions.

What changes for the final developer?

  1. It would be easier to update the application since small breaking change will come each week/month and not all at once.
  2. No need to wait X months for new features, you can always be at the edge of Adonis very easily.
  3. No confusion about what version you are using. You will use Adonis with version X of module Y.

How the doc will be?

Each module will have their own Update Guide & Changelog. In the documentation, each function will have a hint with the version when it has been added. So you can quickly know if the function X is available in the release you are using of the module Y.

If we remove a function from a module (after deprecating it for months), we will remove the documentation of it, and the Update Guide will help you understand what to do to replace it.

@RomainLanz RomainLanz changed the title RFC Rolling Release Rolling Release Oct 8, 2018
@assertchris
Copy link

I don't have strong feelings on monolith vs. the current structure. What I would prefer to avoid is a situation where it is impossible to know what "version" of the "framework" a tutorial or screencast or news article is about.

Sorry to reference our favourite PHP framework (again!) but it's unmistakable which set of "components" a news article entitled "What's new in Laravel 5.7" is for.

"Is a tutorial, published 2 years ago, still ok? Let me find a list of package versions in it to check. No such list? Oh well, guess I can't depend on what's said in the tutorial..."

@assertchris
Copy link

An Adonis "version" doesn't need to be anything more than a number to represent that a collection of differently versioned components actually work when used together. Perhaps it just requires a page on the site to say; "Version X of Adonis certifies that these versions of components function well together. Upgrade individual components at your own risk".

@PazzaVlad
Copy link

I personally think that merging core packages (like described here #2) will be more useful. Let me explain why.

  • Rolling Release imho doesn't take away confusion for newcomers. Because people like to think in terms of framework version, like django, laravel etc.
  • Monolith with less frequent updates generally has fewer bugs, because we don't have geometric progression variants mix of packages. It's easier to discuss because we know if someone create issue and said that he uses Adonis 4.2.1, we don't have to think what combination of packages he uses.
  • Given that example with Lucid 6. It's now that obvious if I can update from version 5 to 6 right now, maybe Lucid 6 was created for Adonis v5 etc. If we would have monolith with core packages, we don't have to think about compatibility this core packages.

@PazzaVlad
Copy link

Agree with @assertchris

@EremenkoAndrey
Copy link

Agree with @assertchris
Me too

@bitkidd
Copy link

bitkidd commented Oct 8, 2018

Not sure about the benefits of this for three reasons:

  1. Too many packages to consider
  2. Too hard to follow the changelogs
  3. Too unopiniated

The monolyth approach seems much more stable, kinda there is a set of packages that work together we'll, and this combination is called Adonis 4.5.1, for example.
It feels natural.

@thetutlage thetutlage assigned thetutlage and unassigned thetutlage Oct 8, 2018
@thetutlage
Copy link
Member

thetutlage commented Oct 8, 2018

As I shared in the other thread about merging some packages to the core. Yes, we will merge them together and form a single package called @adonisjs/framework.

Adding anything apart from those packages is making the framework too bloated. For example: Laravel has to create Lumen, in order to serve people who doesn't need everything and maintaining a parallel framework isn't that simple and has it's own drawbacks.

No to monoliths

No matter what you choose, you get downsides for free. By keeping certain packages separate, we make the framework more approachable for people, who are not building full blown server rendered apps.

I myself have projects running with

  • Server rendered apps with sessions for auth.
  • API server, removing packages related to Web security like (iframe injection, xss protection or content-type sniffing) and sessions.
  • A simple server, that doesn't even need a database to run.

For all these use-cases, asking people to run a full blown framework is not fair.


Now, as we are clear that Monoliths is something I doesn't want (which maybe debatable, but there is no point debating), let's move forward

I am interested in finding the best way to release multiple packages, but still keep it clear for the users about the internal dependencies.

In nutshell we will have following packages (the list may grow in future).

  • @adonisjs/framework
  • @adonisjs/lucid
  • @adonisjs/websocket
  • @adonisjs/session
  • @adonisjs/mail
  • @adonisjs/antl
  • @adonisjs/ally
  • @adonisjs/redis

I am happy using @adonisjs/framework version as the main version for everything (docs, creating content and so on) and all other packages can have their own release cycle.

This concept is not new and many other frameworks are already doing it.

VueJs does this with their own packages, like vue-router, veux and so on.

screen shot 2018-10-08 at 5 35 21 pm

Same is done by Ember with Ember data

screen shot 2018-10-08 at 5 19 49 pm

For the community, by the community

I am not rigid on the versioning scheme (just no to complete monoliths). I want it to be easier for everyone to understand, how versioning works and how to upgrade their apps easily.

@assertchris
Copy link

assertchris commented Oct 8, 2018

As I said before (and to try and recover a clear position in spite of the +1s): I don't have strong opinions of monolith vs. how you're planning to structure independent repos. What I don't want to see is a situation where it is unclear which versions of components are referred to in a given situation because there is no compatibility version number.

That compatibility number is what you get for free when structured as a monolith. You've stated reasons why you don't wan a monolith and I understand them. That doesn't mean we can't have Adonis version X which makes it clear which versions of components are working together.

When you place the burden of figuring out which components are (or should be) used together, you make it much harder to know if teaching materials are outdated or even if the application is still going to work post npm up.

Hiding that info in the docs is not much better than omitting it altogether, because now someone has to study the docs in their entirety to get a handle on the constraints of each package. You're making the developer do dependency resolution instead of NPM. Folks well acquainted with the ecosystem might not struggle much with this task, but the average (or new) developer definitely will.

@mourad-ghafiri
Copy link

Angular stragtegy of version alignement had a great success... skipping version 3 to bring all modules to version 4...

you can do the same and bring everything to Adonis 6 or so...

Gooe luck :)

@thetutlage
Copy link
Member

thetutlage commented Oct 8, 2018

My comment clearly says that I am using @adonisjs/framework version as the main version of the framework. So my approach is different from what Romain lanz shared.

To make sure I am not making it confusing. Here’s what I mean

  • AdonisJs does have a version, which is same as the version of @adonisjs/framework
  • All other first party packages like @adonisjs/lucid or mail have their own version.
  • If they rely on specific version of Adonis core, then that will be mentioned in docs. This is same as Vue router, for example: you cannot use current version of vue router with vue@1 and you have to read docs to know that.

@assertchris
Copy link

assertchris commented Oct 10, 2018

and you have to read docs to know that

😞

Do you think it would be possible to put a dependencies version constraint on the first party packages, so that NPM/Yarn could "read the docs" for the developer?

@RomainLanz
Copy link
Member Author

RomainLanz commented Oct 10, 2018

If you believe that you can take a framework and work with it while never reading its doc you are wrong.

Also, peerDependency will be used to warn the user.

@assertchris
Copy link

That's a misrepresentation of what I said. From what @thetutlage has said, it doesn't even sound like the docs he is referring to are the framework's docs; so there's that too.

I'm not saying it should never be in the docs, or that nobody should have to use the docs. I'm saying NPM and Yarn provide a mechanism for this to happen without the developer needing to read the docs about version constraints. Given that, it seems like an unnecessary stumbling block.

@assertchris
Copy link

assertchris commented Oct 10, 2018

Also, peerDependency will be used to warn the user.

From what I've read about peerDependencies, the developer will need to resolve the version conflicts themselves. If the first-party packages must be used with specific versions of AdonisJS, then it seems strange to allow them to be installed with other (non-compatible) versions: even if the developer is warned otherwise.

Am I understanding the mechanics of peerDependencies correctly, or will it not be possible to install Lucid with...say...an incompatible version of AdonisJS..?

@thetutlage
Copy link
Member

@assertchris how do u stop installation of incompatible packages at first place using npm or yarn? I’ll be the happiest person on planet, if npm can help me do that

@assertchris
Copy link

Unless I'm missing something obvious: Lucid requires framework 6, so it specifies "@adonis/framework": "^6.0.0" in dependencies. When someone tries to install Lucid, it will make sure version 6 is installed or NPM/Yarn won't install Lucid to begin with.

@thetutlage
Copy link
Member

@assertchris Nope.

Let's say lucid relies on "@adonis/framework": "^6.0.0"
Your app is running "@adonis/framework": "^5.0.0"

Then npm will install a different 2 copies of @adonis/framework, and Lucid will use a different version then your app. Which is more dangerous.

As @RomainLanz said peerDependencies are the way to tell users about the mis-match, since npm does warn you about it.

@assertchris
Copy link

Lucid will use the version in it's node_modules folder, which would still be version 6.

@RomainLanz
Copy link
Member Author

RomainLanz commented Oct 11, 2018

Unless I'm missing something obvious

You are.

Using peerDependencies let the final developer install the correct package.
If your application is using "@adonis/framework": "^5.0.0", and the new version of Lucid use "@adonis/framework": ">6.*" in its peer dependencies, NPM will warn you that you cannot use this version of Lucid because your version of @adonis/framework doesn't match the required version.

@assertchris
Copy link

@RomainLanz

You are.

And, then you repeat exactly what I said here:

...the developer will need to resolve the version conflicts themselves.

peerDependencies warn but don't enforce. dependencies enforce (for that specific node_modules folder). That appears to be what the docs are saying. Do you still think I'm missing something in that definition?


I know it's difficult to read tone on the internet, and I am assuming the best here. Please try to remember that I'm not arguing against you – I'm arguing for making things easier for the developer.

@thetutlage
Copy link
Member

@assertchris

Lucid will use the version in it's node_modules folder, which would still be version 6.

But the framework version has to be shared between your app and Lucid. Ideally framework is not right dependency here. Let's talk about IoC container instead.

If lucid is running a different copy of IoC container, and your app is running a different copy, then bindings in the IoC container won't be shared.

This is what peer dependencies is for. If npm Warns then it is npm who decided to warn. All packages, which want to use main app dependencies works on top of peerDependencies only. It is true for babel, eslint or any other.

https://github.com/babel/eslint-plugin-babel/blob/master/package.json#L30
https://github.com/vuejs/vuex-router-sync/blob/master/package.json#L41

So the idea of peerDependencies is not debatable and also dependencies is not the right way to achieve what we want.

@assertchris
Copy link

assertchris commented Oct 11, 2018

I see what you're saying. Thanks for taking the time to explain. Just to be clear – the global mutable state, shared between framework and the first-party components, is forcing peerDependencies over dependencies then?

In that case, I now have strong opinions over monolith vs. the proposed structure. As you've already explained you won't budge over that issue, I guess there's nothing more for me to talk about here.

@thetutlage thetutlage self-assigned this Oct 11, 2018
@thetutlage
Copy link
Member

Finally going with the approach shared in #12 (comment)

@RomainLanz
Copy link
Member Author

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

7 participants