Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backwards compatibility with previous versions #46398

Closed
gund opened this issue Jun 16, 2022 · 4 comments
Closed

Backwards compatibility with previous versions #46398

gund opened this issue Jun 16, 2022 · 4 comments

Comments

@gund
Copy link

gund commented Jun 16, 2022

Which @angular/* package(s) are the source of the bug?

core

Is this a regression?

Yes

Description

Hi, I want to apologize in advance if this is not a place for this type of request/discussion.

Basically I would like to understand on official position of Angular framework on backwards compatibility with previous versions, especially in the context of libraries that are built using latest Angular compiler and then are used in an older Angular application.

Previously this was not a problem (it was possible to use library built with Angular v13 inside of an Angular v12 app) but with the release of Angular v14 a library built with it is no longer compiles within Angular v12 app (see the error here) even when the library works fine inside of the storybook environment.

Hence comes the question is this a regression or expected behavior "by design" as I could not find any resources that elaborate on this topic.

Please provide a link to a minimal reproduction of the bug

No response

Please provide the exception or error you saw

TypeError: Cannot create property 'message' on string '.\node_modules\ng-dynamic-component\fesm2015\ng-dynamic-component.mjs: This application depends upon a library published using Angular version 14.0.1, which requires Angular version 14.0.0 or newer to work correctly.

Consider upgrading your application to use a more recent version of Angular.
  26 | }
  27 | /** @nocollapse */ ComponentOutletInjectorDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.1", ngImport: i0, type: ComponentOutletInjectorDirective, deps: [{ token: i1.NgComponentOutlet, host: true }], target: i0.ɵɵFactoryTarget.Directive });
> 28 | /** @nocollapse */ ComponentOutletInjectorDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.0.1", type: ComponentOutletInjectorDirective, selector: "[ngComponentOutlet]", providers: [
     |                                                            ^
  29 |         {
  30 |             provide: DynamicComponentInjectorToken,
  31 |             useExisting: ComponentOutletInjectorDirective,'

Please provide the environment you discovered this bug in (run ng version)

Library compiled with:

Angular CLI: 14.0.1
Node: 16.15.1
Package Manager: npm 8.12.1
OS: linux x64

Angular: 14.0.1
... cli, common, compiler, compiler-cli, core, language-service
... platform-browser, platform-browser-dynamic

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1400.1
@angular-devkit/build-angular   14.0.1
@angular-devkit/core            14.0.1
@angular-devkit/schematics      14.0.1
@schematics/angular             14.0.1
ng-packagr                      14.0.2
rxjs                            7.5.5
typescript                      4.7.3

Library consumed with Angular v12.

Anything else?

No response

@alxhub
Copy link
Member

alxhub commented Jun 16, 2022

What you describe is not backwards compatibility but forward compatibility. That is, you're asking if Angular 12 can/should support dependencies from applications on libraries that were built with a future version of Angular (e.g. v14).

For backwards compatibility, our general policy is to support the previous 2 major versions. v14 Angular projects should be able to depend on v12 libraries, for example. In practice, often libraries will work for longer than this.

Angular's forward compatibility is defined by how semantic versioning works, and the restriction is actually pretty strong: forward compatibility only extends to future patch releases. Minor releases may contain new features which break forward compatibility.

For example, suppose Angular introduces a new component ViewEncapsulation mode in Angular 14.1, and someone publishes a library fancy-lib which uses the new mode. No Angular 14.0 applications can use this library, because the 14.0 runtime does not support the new mode. So technically and pedantically, libraries built with 14.1 can only be used with Angular 14.1+ and should express a peer dependency on @angular/core to that effect.

In practice, forward compatibility will vary. If the library doesn't make use of the new mode, maybe it'll work just fine with 14.0. Many libraries may choose to omit any peer dependency restrictions for that reason, or may simply not be aware of the case for including one in the first place.

@alxhub alxhub closed this as completed Jun 16, 2022
@gund
Copy link
Author

gund commented Jun 17, 2022

Thanks for clarification and yes you are right it's about forward compatibility 🙂

So in theory if a library does not use any of the new features that were introduced in later versions of Angular it should be possible to use it in older versions?

Because this is exactly the case in the library that I'm maintaining and I specifically built a compatibility code for Angular 12 runtime however the app compiler throws an error during the build stating that the library is built for v14 and is not supported.

I've noticed in the error that a library compiler generates code that mentions minimum version like minVersion: "14.0.0", version: "14.0.1 which I assume is later used during app compilation to determine compatibility of particular library code with the app?

So I wonder if there is any way to instruct the compiler that my library may be used with Angular 12?
Maybe some kind of a metadata that may be given during a build of a library or an app to a compiler/builder?

Or just getting an understanding how this metadata is derived would also be good as I've seen some parts were having v12 as minimum version and other v14 in the same codebase.

Thanks!

@JoostK
Copy link
Member

JoostK commented Jun 17, 2022

I've noticed in the error that a library compiler generates code that mentions minimum version like minVersion: "14.0.0", version: "14.0.1 which I assume is later used during app compilation to determine compatibility of particular library code with the app?

Indeed, the output for libraries contains the exact version which was used during compilation, as well as a minimum target version. This was baked in from the start of v12 (the initial availability of Ivy's library output) to allow detecting libraries that require a later version at application build time.

In v14, the library output has changed for components to support standalone components. In particular, the initial format had separate arrays for the components, directives and pipes that were used in the template. In v14, these were combined into a single dependencies array to ensure that relative ordering of the various components, directives and pipes was maintained, as this is important for how DI providers are extracted from standalone components. But this is a forwards compatibility break, as it means that older versions no longer see any components, directives and pipes.

So I wonder if there is any way to instruct the compiler that my library may be used with Angular 12?
Maybe some kind of a metadata that may be given during a build of a library or an app to a compiler/builder?

This is not possible and won't be supported, as there's loads of potential forwards compatibility hazards as Alex mentioned; you'll have to build with the version that you want to support as a minimum.

@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Jul 18, 2022
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

3 participants