-
Notifications
You must be signed in to change notification settings - Fork 368
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: refactor loadAndActivate #1609
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
size-limit report 📦
|
9a20fde
to
34bd46a
Compare
Codecov ReportPatch coverage:
Additional details and impacted files@@ Coverage Diff @@
## next #1609 +/- ##
==========================================
+ Coverage 75.40% 75.47% +0.07%
==========================================
Files 76 77 +1
Lines 1980 1986 +6
Branches 518 518
==========================================
+ Hits 1493 1499 +6
+ Misses 375 374 -1
- Partials 112 113 +1
... and 2 files with indirect coverage changes 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. |
I agree that may be my solution is not the best. But moving gluing to the userland will cause problems with proper integration of lingui for the users and as consequences lower retention rate. What is really should be done, probably, changes to the provider, implementing kinda "distinctUntilChanged" strategy. Instead of just deleting the functionality and leaving users hanging, maybe you could propose a better integration solution? Also, once this PR gets merged, all the examples should be updated to reflect the changes, or maybe that could be done as part of the PR. |
hello 🙂
Let's take it step by step. Right now, based on what I explained, we seem to have (3) and I'm aiming for (2).
please see changes to I think the Provider is doing fine the way it is; it takes an i18n instance, passes it to consumers via context, re-renders them when the locale changes. It's pretty simple and that's good. But it's up for discussion later. side question: I tested the changes locally.. the example projects have lingui installed in node_modules... maybe they could thanks |
if (notify) { | ||
this.emit("change") | ||
} | ||
this.emit("change") |
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.
just curious, what is the rationale here that always notify ? since previously, people may assume that change
is only notified if locale changed, this might break that assumption
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.
since previously, people may assume that change is only notified if locale changed
change
was (and still is) previously emitted when calling activate
or load
, so this is in line with the current behavior
Sure, I understand your point. i'm just thinking that this foundation could be made to support such integrations way easier. For example how @taozhou-glean is mentioned, don't fire a Something like: loadAndActivate({ locale, locales, messages }: LoadAndActivateOptions) {
this._locale = locale
this._locales = locales || undefined
this._messages[this._locale] = messages
if ((JSON.stringify(this._messages[this._locale]) !== JSON.stringify(messages)) || this._locale !== locale) {
this.emit("change")
}
}
The contribution guide suggest using local npm repository with Verdaccio. |
The current situation is this: whenever Second, I don't think we need to be smarter here (and neither in the Third, the JSON.stringify comparison: That's going to be slow for big message catalogs, and 99.9% of time the |
If naming is an issue - let's rename it.
It's not about performance, but about easiness of integration. For the simplicity, it even could be just reference comparison, because in most cases that would be enough. if ((this._messages[this._locale] !== messages) || this._locale !== locale) {
this.emit("change")
} |
Well, it's not about performance, but only while the perf is good. sorry, but I just don't see the issue with the event emitting here. What is the integration problem?
yeah but then when people take a message catalog, mutate it by adding a few strings in it, its reference will be the same, and event will not be emitted when it should. |
The issue is, it's quite hard to come up with this: const isClient = typeof window !== "undefined"
if (!isClient && locale !== i18n.locale) {
// there is single instance of i18n on the server
// note: on the server, we could have an instance of i18n per supported locale
// to avoid calling loadAndActivate for (worst case) each request, but right now that's what we do
i18n.loadAndActivate({ locale, messages })
}
if (isClient && i18n.locale === undefined) {
// first client render
i18n.loadAndActivate({ locale, messages })
}
useEffect(() => {
const localeDidChange = locale !== i18n.locale
if (localeDidChange) {
i18n.loadAndActivate({ locale, messages })
}
}, [locale]) for the regular developer. That issue I tried to tackle. Make integration more straightforward.
Anyway, this wouldn't work because messages should be compiled before. It's error-prone approach, because some messages added on the fly would work, some not. It's even better if it fails first. Let's finish this discussion, i agree with you, let's leave it as you wrote that. |
@vonovak @thekip @taozhou-glean let's merge this? |
// there is single instance of i18n on the server | ||
// note: on the server, we could have an instance of i18n per supported locale | ||
// to avoid calling loadAndActivate for (worst case) each request, but right now that's what we do | ||
i18n.loadAndActivate({ locale, messages }) |
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.
Arguments should not be an object here correct?
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.
hi, they should be an object:
js-lingui/packages/core/src/i18n.ts
Line 187 in 9989963
loadAndActivate({ locale, locales, messages }: LoadAndActivateOptions) { |
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.
Yes, I just rechecked, apologies. Nice job 💯
Description
this makes 2 changes to
loadAndActivate
: one changes the signature and the other is removing thenotify
param.First, there's a reason why the existing
activate
call acceptslocale
andlocales
separately, because when youactivate
as in https://lingui.dev/ref/core#optionslocalesthen the
locale
will be used for translating strings andlocales
will be used for number formatting herejs-lingui/packages/core/src/i18n.ts
Line 242 in 559a8c7
maintaining the behavior from the example (
locale="ar", locales="["en-UK", "ar-AS"]
) would not be possible with howloadAndActivate
is done currently, so I had to refactor it.Additionally, I removed the
notify
parameter, whose description was: "This is useful for integration with frameworks as NextJS to avoid race-conditions during initialization."However, the issues that were met when integrating with nextJS, as seen in lingui/swc-plugin#46 are just a result of not "gluing" nextJS / react with lingui correctly. The solution to the error is to change the gluing, not the i18n object.
Not emitting the
change
event is a workaround which, in fact, creates bugs as seen in lingui/swc-plugin@5fbcd0fThe React Provider relies on those events being emitted and giving the option to not emit is not going to help.
Thank you so much and sorry for maybe not sounding nice, I'm kinda busy, thank you for you review :)
more docs changes are needed but are out of scope of this PR. I plan another PR for the nextjs example to improve the "gluing".
Types of changes
Fixes # (issue)
Checklist