-
Notifications
You must be signed in to change notification settings - Fork 390
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
feat: add js/node core translation api for usage without macros #1564
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
df43486
to
724103f
Compare
size-limit report 📦
|
1d90bbf
to
c0a9ef5
Compare
Codecov ReportPatch coverage:
Additional details and impacted files@@ Coverage Diff @@
## next #1564 +/- ##
==========================================
+ Coverage 75.41% 75.74% +0.32%
==========================================
Files 77 77
Lines 1973 1987 +14
Branches 517 522 +5
==========================================
+ Hits 1488 1505 +17
+ Misses 374 371 -3
Partials 111 111
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. ☔ View full report in Codecov by Sentry. |
Why need to create another api surface for quite rare case if you can directly write /*i18n*/ {id: "...", message: "..."} The problem with this exact implemetation - it fixes only your case, and you assume everyone would use it like that. The code doesn't check that import {i18n as lingui} from "@lingui/core"
lingui.t({id: "...", message: "..."}) // <-- Oops! There already a way to mark your messages for translation with |
Thanks for checking out my PR @thekip! I can adjust my PR to check for proper import and aliasing. The whole point of the PR is to allow users who don't want macros to avoid having to use |
@j4hr3n thank you for the contribution! I can remember a couple of recent similar cases mentioned somewhere in the Discord chat or here in the comments It might be a common issue for such cases when the macro is unacceptable |
9a97017
to
cf60285
Compare
@thekip I've added support for aliasing i18n now |
cf60285
to
58ee30f
Compare
Well, if we decided to go that way, may be it's better to improve extraction from i18n._ instead of creating an I'm not against creating alias for more aligned DX with macro, but with this PR we would have 2 functions which serve the same purpose but behave slightly differently. |
I can agree that it might not be the most optimal solution to the problem. That being said Lingui is advocated as a universal, use it everywhere, javascript library. If you have to use |
packages/babel-plugin-extract-messages/test/fixtures/js-call-expression.js
Show resolved
Hide resolved
packages/babel-plugin-extract-messages/test/fixtures/js-call-expression.js
Outdated
Show resolved
Hide resolved
58ee30f
to
c7b0acc
Compare
also |
e8dc9cf
to
da466ce
Compare
da466ce
to
dc0ada1
Compare
dc0ada1
to
84d611f
Compare
9758a69
to
eb92a7c
Compare
eb92a7c
to
58e3af9
Compare
website/docs/ref/core.md
Outdated
A small wrapper on the core translation meant for NodeJS/JS usage without macros. It uses the core `_` method, but currently only accepts message descriptor. This API is prone to breaking changes | ||
|
||
`messageDescriptor` is an object of message parameters. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@andrii-bodnar could you help @j4hr3n here to write more descriptive doc for the method? I think it should be stated from the doc that the main difference here is how this method is treated by extractor. (not the signature of the method, how some may understand from this doc)
And probably we also could state that if someone wants to use lingui without macro it's better to start from this method.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm going to release it within the v4.0.0-next.5
and then check the possibility of docs improvement in a separate PR
I just realized that there is a use case which is most likely would be a default on the server side: const i18n = setupI18n({})
// here extractor would not work
i18n.t(...) On the server side usually everything is linked to the current request to avoid leaking data from one user to another. // pseudocode
const app = express()
// init i18n middleware
app.use((req, res) => {
const locale = detectLocale(req);
req.i18n = setupI18n({locale});
next()
})
app.get('/', (req, res) => {
res.send(req.i18n.t('hello world'))
}) So this would not work. The only one, reliable way to extract in this case it is manual annotation what should be extracted and what should not. The same would be for client side usage without macro: function MyComponent(props) {
const {i18n} = useLingui();
<title>{i18n.t(...)}</title>
} So i'm still not sure that this solution is really needed for a lib where is already reliable way to do that exists. |
Even with that usecase in mind I feel like non-macro users deserve a slightly better DX than doing With this new core API marked as experimental I feel like we could incrementally add support to cases like this. I'd be happy to do so. |
58e3af9
to
37ef4b8
Compare
You are opened are pandora's box. Good luck |
Let me rephrase and summarize the problem which you want to solve with this pr.
Let's dig deeper into this statement. What exactly wrong with current DX? I think we can highlight pain points:
Let's start from the history. Originally, extractor did not extract from But that implementation had a lot of problems which we're still fixing! It works not consistently. It matches just It was a mistake, that should never be merged into sourceode in the form it was presented. This gives people false expectations about how this should work. The second attempt, happened in this PR. Made on wrong assumptions from that first There are simply no way to make it work in the form as it written right now. The static analysis is just not powerful enough to understand all usages which should be extracted. We would always have some trade-offs in extraction. Let's come back to the "root" of the issue. I think manual annotation is the root. They are hard to write by hand and easy to forget. What we can do about it? Could we look to a problem from the different perspective? If we don't like how it's made now, maybe annotation itself could be changed instead of trying to support all possible usage cases? I see few options which would "just work", thanks to typescript, and will lack all this issues. Annotations could be part of the code, part of the type system. type AnnotatedMessage = {
//...
}
i18n.t(message: AnnotatedMessage) {
// ...
}
function msg(string, placeholder): AnnotatedMessage {
// ...
}
// =======
i18n.t(`Hello`) // < -- typescript error. string is not assignable to AnnotatedMessage
i18n.t(msg`Hello`) // <-- no error, developer now will not forget to annotate! Extractor should be taught to search I don't like Does it make sense? |
A suggested change to add an additional core API method. This method can be used without including macros. It accepts a message descriptor and the babel message extraction plugin has been updated to handle extraction of this syntax.
Description
Types of changes
Fixes # (issue)
Checklist
CODE_OF_CONDUCT docs