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

Versioning of Angular between Angular Applications and Angular Libraries #43949

Closed
EvanCarroll opened this issue Oct 26, 2021 · 10 comments
Closed
Labels
area: core Issues related to the framework runtime
Milestone

Comments

@EvanCarroll
Copy link
Contributor

EvanCarroll commented Oct 26, 2021

Description

I'm getting an error when I compile an angular library that uses a different version of Angular than the library it's including.

Please provide the steps to reproduce the issue

Create an Angular application in which your package.json has

"dependencies": {
    "@angular/forms": "^11",
}

Create an Angular library in which your package.json has

"dependencies": {
     "@angular/forms": "^11.2.12"
}

Then link the application to the library with ng link
Compile the application with with ng build.

Please provide the expected behavior vs the actual behavior you encountered

I would prefer to know can an application be versioned newer than a library? Can a library be versioned newer than the application it's compiled in? Or do all Angular things (applications and libraries) need to have the same version?

It would be nice to have a better warning and documentation on this.

Please provide the exception or error you saw

Error: src/app/components/forms/forms.component.ts:48:54 - error TS2345: Argument of type 'ValidatorFn' is not assignable to parameter of type 'ValidatorFn | ValidatorFn[] | AbstractControlOptions'.
  Type 'import("/root/libs/angular-validators/node_modules/@angular/forms/forms").ValidatorFn' is not assignable to type 'import("/root/demo-app/node_modules/@angular/forms/forms").ValidatorFn'.
    Types of parameters 'control' and 'control' are incompatible.
      Type 'import("/root/demo-app/node_modules/@angular/forms/forms").AbstractControl' is not assignable to type 'import("/root/libs/angular-validators/node_modules/@angular/forms/forms").AbstractControl'.
        Types have separate declarations of a private property '_parent'.
@EvanCarroll
Copy link
Contributor Author

The docs actually make mention of this here where they offer this as a solution,

{
  "compilerOptions": {
    // ...
    // paths are relative to `baseUrl` path.
    "paths": {
      "@angular/*": [
        "./node_modules/@angular/*"
      ]
    }
  }
}

HOWEVER I would still contend this is not a very good error. I'm not sure how this can be fixed as it seems to come from tsc, but it's a pretty bad user experience.

@petebacondarwin
Copy link
Member

In terms of compatibility:

I would prefer to know can an application be versioned newer than a library? Can a library be versioned newer than the application it's compiled in? Or do all Angular things (applications and libraries) need to have the same version?

We try to ensure that Angular applications can use libraries that are versioned up to 2 major versions prior to the version of the application. (But in practice, you can usually go much further back than that - there are a number of libraries that are built with v8, for example, that work fine with v12 applications).

We do not officially support an application using a library that was built with a newer version of Angular than the application. So if your application is built with Angular v11, then all the libraries it depends upon ought to be built with v11 or earlier. This actually also includes minor versions, but not patch versions. (Again, in practice, you may well be able to get away with using a library with a newer version, although v13 has a hard break in this regards since it is not possible to consume v13 libraries with ViewEngine applications).

@petebacondarwin
Copy link
Member

But this issue is not really about version skew. Instead it is more about the fact that if you use npm link to access a library, it is possible that the library and the application end up using different copies of the Angular libraries, which is what the TypeScript compilation is complaining about. In other words the "type" of the AbstractControl referenced in the library is actually a different type to the one referenced in your application.

@EvanCarroll
Copy link
Contributor Author

@petebacondarwin I agree though it's great to know that applications support libraries two major versions-back with partial-ivy. That should be published in the docs. It seems like a question that people will often ask (can their Angular library published on npm be used by older version of Angular).

Your follow up is exactly the problem. It would just be nice to know if during angular compilation if the problem was a result of Angular-version-mismatch the modifications necessary to the tsconfig to resolve the issue.

@jessicajaniuk jessicajaniuk added the area: core Issues related to the framework runtime label Oct 26, 2021
@ngbot ngbot bot added this to the needsTriage milestone Oct 26, 2021
@petebacondarwin
Copy link
Member

I think the main issues is that npm link is not really a good idea. I think we should actually remove that section from our docs. It is better to use a mono-repo approach, locally compile libraries on demand, and use tsconfig paths mappings to access them from the apps that consume the libraries.

@alan-agius4 may have more to say on this.

@alan-agius4
Copy link
Contributor

alan-agius4 commented Oct 27, 2021

I agree with @petebacondarwin, we should definitly remove the npm link section. We don't recommand using npm link as this is more of a legacy behaviour prior to Angular CLI version 6 which started to support multiple project in the same workspace. If you want to test/use a library in an application from a different workspace npm install would be the better approach.

One of the many problems with npm link is that it will create a symlink which causes the node_modules of the library including dev dependencies to also exist in the applications node_modules. This will cause errors similar to the above, because there are multiple versions of @angular/ in the node_modules tree. In additional to that, this can also lead to incorrect/broken runtime.

@EvanCarroll
Copy link
Contributor Author

EvanCarroll commented Oct 27, 2021

The monorepo approach has its own share of problems, not least of which is that it's totally unsupported with tooling (like semantic-release) and also remarkably undocumented.

This will cause errors similar to the above, because there are multiple versions of @angular/ in the node_modules tree.

This is the problem that I found, but this problem can be easily solved with this which worked for us and was documented.

Also important to point out, that I can fork an angular-library on GitHub build it and link it in with npm link. However, using the monorepo approach I would have to either (a) pull all the source into my repo, or (b) use some kind of hack like a git submodule which the build system doesn't support natively either.

@EvanCarroll EvanCarroll changed the title Versioning between Angular Applications and Angular Libraries Versioning of Angular between Angular Applications and Angular Libraries Oct 27, 2021
@alan-agius4
Copy link
Contributor

I do agree, that single and multi repos have their own goods and bads.

But, because a tool doesn't support mono-repos, doesn't make mono-repos bad. That just makes that tool not the suitable for that architecture. For mono-repos other tools should be considered instead of semantic-release, one tool that comes to mind right now as alternative is lerna.

I personally think that the popularity of mono repos will continue to grow in the coming years, especially now that NPM 7 fully supports workspaces. Previously, this was only possible by using Yarn.

alxhub pushed a commit that referenced this issue Oct 29, 2021
We update the `creating libraries` guide to remove View Engine references. This is because in version 13 users are no longer able to build libraries using View Engine.

In addition to the above, we also remove references to `npm link`. As this is actually not a recommended workflow, and was mostly needed in older versions of the CLI prior to version 6, were multi-projects workspaces were introduced.

Closes #43949

PR Close #43982
@alxhub alxhub closed this as completed in 6b8cdc9 Oct 29, 2021
@EvanCarroll
Copy link
Contributor Author

EvanCarroll commented Oct 30, 2021

This is going to just cause more questions now. I mean anyone writing an angular app that has to fork an angular library will be wondering how they build that angular library and get the code into their app. The assumption that this problem goes away because Angular supports workspaces won't hold true when the library is externally maintained.

@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 Nov 30, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area: core Issues related to the framework runtime
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants