You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
So maybe versioning numbers alongside Angular releases can be a good idea. Like: 18.x to be compatible with Angular v18 and so on and so forth. This doesn't misalign with being compatible with all Angular actively supported versions. Because 18.x can support 16, 17 and 18. Then, in 19.x, support for v16 is dropped and support for v19 is added. Hence it supports v17, v18 and v19.
Otherwise, being compatible with really old Angular versions can be a maintenance burden. Plus we won't be able to use newer APIs.
The idea of supporting all versions was because setting <meta> elements needs very few APIs from Angular. Plus they're quite important APIs that haven't changed much. So could be possible.
However many things have changed over time and right now the library isn't compatible with v14 or below. Due to the following APIs mainly:
inject() with inject options instead of flags. Options were introduced in v14.1 and flags deprecated at same time. Flags have been supported since inception of the function. However, at some point flags will be removed! Could be replaced by @Inject decorators in a service though. But then the ones needing those would need to be turned services hence increasing bundle size. Specifically metadata loader (to inject local registry) and metadata resolver (to inject optional route metadata strategy and optional defaults).
Environment'ish APIs are regarding the standalone approach and then there's the inject thing. But anyway, seems that even those fundamental APIs may be subject to changes over time. So having a versioning aligned with Angular releases would help updating to newer APIs (like takeUntilDestroyed that could simplify router listener). With 3 releases of difference to provide more support time. But at least at some point in time.
Angular does not support using an earlier version for the application.
Another alternative is to go with regular sem ver, then publish a compatibility table of which versions are compatible with which ones. Just publish a breaking change when an API has been removed hence it doesn't work anymore. This will reduce the amount of breaking changes. As if aligning with Angular releases, a new version may include breaking changes. In the library, a part from the Angular-related APIs ones.
Another thing to take into account is that maintaining support for many versions means more CI/CD minutes as for each major version we create an example app and run E2E tests against it to ensure everything goes fine.
We can take a look at several popular Angular libraries and see how they do it. So at least is not strange for developers:
Font Awesome: compatibility table.
NgRx: Angular versioning
Angular Material: Angular versioning
Angular ESLint: Angular versioning
PrimeNg: Angular versioning. However it goes one behind. Now the latest one is 18.2.8 but they're in 17.x still. Maybe due to that recommendation? As last release is quite recent.
NgBootstrap: Same as above
Angular Fire: Angular versioning
Ngxtension: regular semver, no compatibility table. Recent library done by Angular pros. Seems they are going same way as tried here 🤔
Angular three. Also baked by an Angular pro. Same as Ngxtension. However, it does view things. Hmmm.
It's quite normal that UI-related ones like Material, PrimeNg, NgBootstrap do the Angular versioning as many updates may happen in the view side of things. Regarding the linter, same but also taking into account way of doing things may switch in a major version hence the need to release along the major version release.
However, maintaining a major version can imply many things:
A new branch for that version v{major}.x
Footnotes
When a new major is released that drops support for older versions, it will be needed to know which versions are compatible with which ones. ↩
If we just do a major release every 1 year for instance, users will just experience breaking changes once per year. Breaking changes may be just dropping support for older Angular versions though (no code changes required if users update their Angular version frequently). Hence greater development experience. ↩
The text was updated successfully, but these errors were encountered:
Maintaining compatibility with older versions of Angular is starting to be a challenge. See for instance:
addRootProvider
forng-add
schematic #984NavigationEvent
enum chore: avoid importing EventType to compile with v17.1 #246So maybe versioning numbers alongside Angular releases can be a good idea. Like:
18.x
to be compatible with Angular v18 and so on and so forth. This doesn't misalign with being compatible with all Angular actively supported versions. Because18.x
can support 16, 17 and 18. Then, in19.x
, support for v16 is dropped and support for v19 is added. Hence it supports v17, v18 and v19.Otherwise, being compatible with really old Angular versions can be a maintenance burden. Plus we won't be able to use newer APIs.
The idea of supporting all versions was because setting
<meta>
elements needs very few APIs from Angular. Plus they're quite important APIs that haven't changed much. So could be possible.However many things have changed over time and right now the library isn't compatible with v14 or below. Due to the following APIs mainly:
makeEnvironmentProviders
: introduced in v15inject()
with inject options instead of flags. Options were introduced in v14.1 and flags deprecated at same time. Flags have been supported since inception of the function. However, at some point flags will be removed! Could be replaced by@Inject
decorators in a service though. But then the ones needing those would need to be turned services hence increasing bundle size. Specifically metadata loader (to inject local registry) and metadata resolver (to inject optional route metadata strategy and optional defaults).ENVIRONMENT_INITIALIZER
: introduced in v14 after renaming. It was originally calledINJECTOR_INITIALIZER
. However, rename happened during the pre-releases of the version, so no breaking changes. It was actually introduced here. To add moar, it will be deprecated in v19, and replaced by aprovideEnvironmentInitializer
function.Environment'ish APIs are regarding the standalone approach and then there's the
inject
thing. But anyway, seems that even those fundamental APIs may be subject to changes over time. So having a versioning aligned with Angular releases would help updating to newer APIs (liketakeUntilDestroyed
that could simplify router listener). With 3 releases of difference to provide more support time. But at least at some point in time.Also Angular.dev recommends building apps using the same or greater version than the library was build with. So according to this, the library should be compiled with the oldest version that supports. Hence supporting older versions becomes more difficult. In few words, quoting the Angular.dev link:
Another alternative is to go with regular sem ver, then publish a compatibility table of which versions are compatible with which ones. Just publish a breaking change when an API has been removed hence it doesn't work anymore. This will reduce the amount of breaking changes. As if aligning with Angular releases, a new version may include breaking changes. In the library, a part from the Angular-related APIs ones.
However, that approach implies yet another library to look for compatibilities when upgrading. Like: version X is compatible with Angular version Y. See https://github.com/FortAwesome/angular-fontawesome?tab=readme-ov-file#compatibility-table
Another thing to take into account is that maintaining support for many versions means more CI/CD minutes as for each major version we create an example app and run E2E tests against it to ensure everything goes fine.
We can take a look at several popular Angular libraries and see how they do it. So at least is not strange for developers:
@sentry/angular
: compatibility table.It's quite normal that UI-related ones like Material, PrimeNg, NgBootstrap do the Angular versioning as many updates may happen in the view side of things. Regarding the linter, same but also taking into account way of doing things may switch in a major version hence the need to release along the major version release.
The ones going free as we tried here are quite new. Angular three 1.0.0 version is from Jan 2023. Ngxtension 1.0.0 is from Nov 2023. Though breaking changes releases are done properly
Here's a comparison table to recap
npm
distribution tagslatest
n
: 1 per major release. Like Angular'sv{n}-lts
. Can be just one tooHowever, maintaining a major version can imply many things:
v{major}.x
Footnotes
When a new major is released that drops support for older versions, it will be needed to know which versions are compatible with which ones. ↩
If we just do a major release every 1 year for instance, users will just experience breaking changes once per year. Breaking changes may be just dropping support for older Angular versions though (no code changes required if users update their Angular version frequently). Hence greater development experience. ↩
The text was updated successfully, but these errors were encountered: