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

Why ngx-extractor only works with plainly injected i18N instance? #47

Open
luisfpg opened this issue Dec 4, 2018 · 2 comments
Open

Comments

@luisfpg
Copy link

luisfpg commented Dec 4, 2018

I'm building a fairly complex software, https://github.com/cyclosproject/cyclos4-ui.
Initially we had thought in our own i18n solution, because we need translations in services / components. But then we found i18n-polyfill and started using it.
We were happy, and did a lot of restructuring of the code.
As components have a lot of common dependencies, we've created a base class which receives the Injector instance and gets all the services it needs. We started doing the same with i18n.
Then I suddenly realized none of the keys in components were being catched by ngx-extractor, because the i18n instance was not injected directly, but obtained from the Injector.
The point is: why can't the i18n instance be passed around? I guess it would work if the string is set in the xlf file, but ngx-extractor ignores them.
To my surprise, when trying to find what happened, I found this answer: #37 (comment)
The point is: why does the processor needs to work on directly injected references of i18n? Couldn't it just parse all the usages of I18N, and that's it?

The requirement that i18n MUST be injected is not documented anywhere, and is something fundamental for the extractor to work. And without the extractor working, there's no point in using i18n-polyfill...

@skirilo
Copy link

skirilo commented Dec 20, 2018

Can we add the following code into extractor.ts
` protected _findI18nVariables(node: ts.Node): ts.VariableDeclaration[] {
let variableNodes = this._findNodes(node, ts.SyntaxKind.VariableDeclaration) as ts.VariableDeclaration[];
variableNodes = variableNodes.filter(varNode => {
if(varNode && varNode.type) {
if (varNode.type["typeName"] && varNode.type["typeName"]["escapedText"])
return varNode.type["typeName"]["escapedText"] === "I18n";
}
return false;
});

return variableNodes;

}
}
`

And this piece of code to the end of the extract method:
` const variableNodes = this._findI18nVariables(this._sourceFile);
variableNodes.forEach(i18nVariable => {
var name = i18nVariable.name['escapedText'];
});
variableNodes.forEach(varNode => {
const callNodes = this._findCallNodes(varNode.parent ? varNode.parent : this._sourceFile, varNode.name['escapedText']);
callNodes.forEach(callNode => {
entries.push(...this._getCallArgStrings(callNode));
});
});

`

This will cover the code like this:
When I18n service retrieved using a factory function
const i18n: I18n = getTranslationService(); let textMsg = i18n({value: "Text message", id:"msgId"});

@luisfpg
Copy link
Author

luisfpg commented Dec 28, 2018

Nice. Is there a planned release shortly to include this fix?
If not we'll have to do a heavy refactoring on the code to inject the I18n instances in all usages...

luisfpg pushed a commit to cyclosproject/cyclos4-ui that referenced this issue Jan 2, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants