-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
i18n: Replace Jed with Tannin #11493
Conversation
I have no objections. Would like @herregroen to sign off on this being parsable by https://github.com/wp-cli/i18n-command/ |
Also, if we end up using this, I'd suggest bringing this into Gutenberg and publishing as |
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.
Looks good, and nice job humbly hiding the fact you wrote Tannin ;)
The only minor concern I have here is that there seems to be a decrease in useful dev feedback when something is wrong. Intentional?
packages/i18n/src/index.js
Outdated
} | ||
|
||
return i18n; | ||
} |
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.
Do we need a replacement for this?
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.
Do we need a replacement for this?
No, I don't think so. It's not exposed as a public API, and its previous purpose of in-time initialization is now served instead by combination of initialize-at-assignment and preparing domain data within dcnpgettext
.
} | ||
} ); | ||
|
||
return i18n.dcnpgettext( domain, context, single, plural, number ); |
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.
so I'm guessing this is to prevent errors when locale data for the domain has not been set yet? I'm concerned about the potential for silent fails here. Should we at least throw a development warning (a-la invariant or equivalent) when this is needed?
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.
so I'm guessing this is to prevent errors when locale data for the domain has not been set yet? I'm concerned about the potential for silent fails here. Should we at least throw a development warning (a-la invariant or equivalent) when this is needed?
Related: #11493 (comment)
I'll look into what the error paths would be and consider whether they're likely to be encountered and if there's a way to preempt / capture them.
Do you mean publishing Tannin as |
@nerrad yes. If we are going to depend on this, we might as well transfer ownership to the WordPress community right? |
I think it's fine to keep it separate. Andrew worked on this as a personal project and we can use it like we use any other personal project. We already use other personal packages from Andrew and Me and other people outside of the community. While I'd be fine giving my projects to WordPress, I think it doesn't make sense to tell people: if you want to us use this project, move it to WordPress. |
I don't think we have to in order to use it, but it certainly is early enough in its creation to encourage doing so. |
try { | ||
return getI18n().dcnpgettext( domain, context, single, plural, number ); | ||
} catch ( error ) { | ||
logErrorOnce( 'Jed localization error: \n\n' + error.toString() ); |
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.
This would make wp.i18n
silent on errors if I'm reading everything correctly.
logErrorOnce
should be passed to the onMissingKey
option from Tannin in my opinion.
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.
The previous try
/ catch
existed largely because Jed is rather throw
-happy with how it deals with unexpected inputs. Though it's similarly fair that Tannin, called incorrectly, could also throw (as unhandled). It's maybe curious to think on how much it could make sense to validate inputs from the @wordpress/i18n
.
I'm not so sure about providing the missing key callback, only because for the default English locale, we don't provide any initialization data, meaning we rely on the missing key behavior intentionally as the default behavior.
packages/i18n/src/index.js
Outdated
|
||
let i18n; | ||
export { default as sprintf } from '@tannin/sprintf'; |
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 wondering if it wouldn't be preferable to simply use something like https://github.com/alexei/sprintf.js instead of introducing our own new library for this. sprintf
seems like something that would already have a well-test well-maintained library.
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.
Agreed. Jed uses that library as well.
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.
It's an easy swap. I'd assumed sprintf-js
to be quite bloated in its full-featuredness, though in truth it's fairly reasonable and efficient. It's still 6x the size of @tannin/sprintf
(3x gzipped), though also includes functionality not supported by sprintf -- albeit the lesser-used functionality of printf patterns.
As far as implementation and performance, it holds an internal cache for format strings, which could be argued as a minor memory leak. Without caching, they perform similarly.
Maturity is a fair point to argue. In all, it's a fair swap I think.
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.
Swapped for sprintf-js
in 9e07b80
Should be no issues here. |
Although I don't understand why you'd want to keep those personal, I am fine either way. |
Without belaboring the point, it was a hobby / passion project intentionally developed outside regular constraints / commitments. While I don't have a strong resistance to transferring ownership, I also don't see that it be strictly necessary, nor think there should be an expectation that all hobby projects of any WordPress contributor be brought under the umbrella of the organization. And as with any permissibly-licensed open-source project, it's entirely forkable should I at any point go rogue 😇 ☠️ |
Placeholders should be consistent across all variations
I've pushed a rebased copy of the branch. Regarding error handling, I've restored the I'd actually reinstated it to |
I'd appreciate a review on this one. |
Thanks @nerrad |
Don't forget the |
Good call 😄 See #11867 |
Related: WordPress/packages#101
This pull request seeks to propose an internal refactoring of the
@wordpress/i18n
module to replace Jed with the largely-compatible Tannin library. This has no impact on the public interface of the module, and instead serves as an overall performance, memory use, and bundle size improvement (see benchmarks).Context: Summarized at WordPress/packages#101, Jed's implementation has a critical performance flaw in that it parses and compiles the locale plural forms expression every time a translation function is called with pluralization or when locale data is not explicitly provided (e.g. default English). While memoization remedies the issue, it's more a bandaid solution in that (a) the underlying operation is still expensive† and (b) it incurs an additional cost of memory storage of redundant cached data. Tannin addresses these issues by computing the parsed evaluator of plural forms at most a single time, and by having more efficient expression parsing and evaluation to begin with.
† Even with caching, the current Gutenberg master incurs a plural forms parse nearly 300 times during the initial load.
Testing Instructions:
There should be no impact on the application. There are numerous layers of unit testing to validate variations of translations, but verify that the correct strings are shown in general usage, notably:
Ensure unit tests pass: