-
Notifications
You must be signed in to change notification settings - Fork 12k
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
Extracted translations include unused translations #24145
Comments
This is currently working as intended as since tree-shaking and dead-code elimination are not done during extraction. Let me bring this up with the rest of the team. |
@alan-agius4 - a related question. Asking this, because |
Thanks for your input, @bridzius. @alan-agius4, thanks for the feedback. Do you have any update on the team's decision? |
@fischeversenker, we still didn’t get to this issue. We should be able to discuss this the next or following week. |
It is often desirable to extract messages from unused components to support a workflow such as:
This is useful because translations can often take a long time O(days) and the process is not easily started in an automated fashion without merging the new component first. Otherwise you need to add the new component to an existing one but then hide it via a flag so international users don't see untranslated content. It takes a certain scale before this workflow is useful, but we use it a lot in Google. There's a separate question here about whether to extract libraries which has a lot more nuance. It's come up before in #17140 so we can continue the discussion there. |
Thanks for the feedback, @dgp1130 👍 I understand your internal use case. I'll have a look at the linked issue and try to find a workaround for my use case. What might not have been perfectly clear in the title of this issue is that there is a certain inconsistency in the extracted translations, which might be relevant to the workflow you are using at Google: Unused components that use the global You might want to investigate this. Have a look at the reproduction repository (upgraded to Angular 15) that I provided in the issue description for a quick start 🚀 |
Ah sorry @fischeversenker, didn't see the difference with If we switch import { Component } from '@angular/core'; // Carried over from user-space.
import { $localize } from '@angular/localize/init'; // Carried over from user-space.
import * as i0 from "@angular/core"; // Added by compiler.
// Carried over from user-space.
export class LibraryWithLocalizeComponent {
constructor() {
this.name = $localize `my name`;
}
}
// ...
// Added by compiler (simplified).
LibraryWithLocalizeComponent.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({
// ...
consts: () => {
const = $localize `unused library template with localize`;
return [i18n_0];
},
}); Both of these use the imported Beyond that immediate problem, this does bring up a few rough edges we can hopefully improve.
I'll file some issues in the main repository for these and see if we can improve this particular footgun. Thanks for pointing this out, lots of interesting tidbits here. 😁 |
@dgp1130, thanks for taking the time to create those new issues and improve the i18n behaviour 🙏 Coming back to the main issue, I would like to question the decision of not taking action on supporting the removal of unused translations in the i18n extraction. The workflow you described in your comment above is completely valid in my eyes and I think it is sensible that Angular supports it. But I don't think this should exclude the use case described by @fischeversenker in this issue. I consider it at least as valid as the one you described, and should therefore be supported in addition to what already is in place. I don't think the Angular experts that spend the day working with the framework are happy to invest a lot of effort on tree shaking their applications for better performance, and end up having translation files that include (many) unused translations. This is a ton of work in terms of maintenance of the translations and I think Angular should save the community this considerable amount of unnecessary effort, which can be much better invested on building great Angular apps. I (my whole team and I am sure many Angular developers) would be very grateful if you would reconsider your position about this topic and provide a solution to the issue initially described by @fischeversenker. I don't think it should be much effort on your side, though I might be wrong since I am of course missing knowledge on the angular codebase. Would you consider providing this feature to the i18n extraction? 🙏 |
#17140 is intended to track figuring out the full story for using libraries with i18n. There's a lot more complexity here than just excluding library messages when extracting the app, given that we'd need to define if / how libraries ship their own translations, how those translations are consumed by the application, how to handle differences in language / locale, how to override library translations, etc. There's definitely a lot of rough edges there, and it's something we'd like to improve, it just hasn't been prioritized yet. Tree-shaking the app before message extraction is also more narrow than extracting messages only from application code, given that unused messages would be dropped. So I don't think applying optimizations would be the right mechanism for limiting extracted messages to application code.
Just to be clear, Angular embeds translations directly in generated code for production builds, so there's no performance impact to having unused messages. We don't ship extracted |
I'd like to pick up on this, to explain more of my motivation: We don't worry about shipping unused translations to our users. We worry about shipping unused translations to our translators. In the project that I'm currently working on we are working with a lot of big component libraries and we create a lot of small applications that each uses >=1 of these libraries. The majority of the extracted translations from these applications are unused since they are coming from the unused components from these libraries. But we are not easily able to tell our translators which ones are actually needed and which ones aren't. This means that we either have to have them translate everything (separately for each of these apps), or we very carefully scan the app and figure out which of the trans-units are actually required to be translated. I understand that a lot of this is covered in #17140, but I can imagine a solution that's somewhere in the middle. Not to move the translation files into the libraries, but to eliminate unused trans-units in apps. Something like the suggestion from @jesusreal, where we have a flag that determines whether the i18n-extraction happens before or after tree-shaking. |
Tree shaking messages is one approach we can consider as part of #17140, but ultimately this will require a lot more thought and investigation to determine the ideal solution to library localization and it just hasn't been prioritized yet. |
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
Command
extract-i18n
Is this a regression?
The previous version in which this bug was not present was
No response
Description
The extracted translations from the
extract-i18n
builder include trans-units from unused templates/components unless these components import and use the$localize
function. This is the case for both app components as well as library components.Minimal Reproduction
Reproduction repository: https://github.com/fischeversenker/ng-decorator-tree-shaking
(don't be fooled by the name of the repository. I re-used an existing repro-repo.)
In essence:
$localize
functionextract-i18n
on your app and verify that the generatedmessages.xlf
file contains unused translations from these componentsException or Error
No response
Your Environment
Anything else relevant?
No response
The text was updated successfully, but these errors were encountered: