-
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
Refactored @wordpress/i18n to be an instantiable #20318
Refactored @wordpress/i18n to be an instantiable #20318
Conversation
🤦♂ I just started on this in #20332 |
@sirreal Are you saying tree shaking won't work unless I use the |
No, I'm saying that if the index only re-exports from other modules, we'll get better tree shaking. As it is This module structure seems ideal (see #20332):
|
I've made the changes as desired but as per my example in the rollup repl I'm pretty confident that the exports were already tree shakable and that the refactor won't result in an improvement to what gets outputted. |
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.
Overall this looks great, thanks! I've left some notes, but there are no major blockers.
I am concerned about effectively loosing all the documentation for the module. It's important to find a solution for that before this can be released.
💯. I think the short term solution is to duplicate the JS docs (or because the tool doesn't document the class anyway, move the documentation to the module methods which do get documented by the tool). Longer term it might be worth looking at a tool that has a few more smarts e.g. typedoc or traversing the TS AST - I think thats well beyond the scope of this PR though. |
Rollup and webpack are different bundlers and their tree shaking algorithms are different. The same example won't be tree shaked in webpack. The Rollup algorithm seems to be more aggressive and it's looking at more things. For example, in the unoptimized program, the But once I add a Webpack's tree shaking is much simpler. It only looks at the |
I agree, it's not trivial: #18045 The best way for now may simply be to reproduce the types in the index: /**
* Merges locale data into the Tannin instance by domain. Accepts data in a
* Jed-formatted JSON object shape.
*
* @see http://messageformat.github.io/Jed/
*
* @param {LocaleData} [data] Locale data configuration.
* @param {string} [domain] Domain for which configuration applies.
*/
export { setLocaleData } from './default-i18n'; In my testing, that works well enough. |
We'll need to rebase this and add the |
packages/list-reusable-blocks/src/components/import-dropdown/index.js
Outdated
Show resolved
Hide resolved
@aduth Do you have any opinions around the tests? Do you think we should keep test coverage on both, the |
I don't think we need to repeat the same tests for the default methods. It should be enough to test methods on an instance created by |
export default instance updated the changelog instantiate locale in constructor refactor as per feedback rename I18N to I18n updated docs added isRTL
return 'rtl' === _x( 'ltr', 'text direction' ); | ||
}; | ||
|
||
setLocaleData( initialData, initialDomain ); |
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.
Should we always be calling this, even if initialData
and/or initialDomain
are possibly undefined
(per the documented types)?
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.
Related to this, are there specific use-cases in mind for setting the initial data? It seems like something which could be useful, but just wondering if we might be getting ahead of ourselves.
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 requested this. It seems helpful to be able to populate with initial data, but there's not much lost if we require package consumers to first create then set the data. I don't have strong feelings.
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 still odd to me that we call setLocaleData
if there is nothing to set. It works, but only by a combination of the fact that data
is an optional argument of setLocaleData
(pretty counter-intuitive), and that object spread is tolerant of undefined (i.e. { ...undefined }
), when instead we could just add an if
here, and make setLocaleData
's data
argument non-optional.
setLocaleData( initialData, initialDomain ); | |
if ( initialData ) { | |
setLocaleData( initialData, initialDomain ); | |
} |
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.
@jameslnewell Do you mind addressing 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.
I addressed this in #21182. I believe that's the remaining feedback that needed to be addressed.
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 works well in my testing.
I don't like that we've moved away from a class which nicely encapsulated state and behavior, but if that's the project convention and preference I'll concede. The end result isn't all that different.
When considering types, now we'll likely end up accessing them as something along the lines of:
// Create function
type __ = ReturnType< typeof createI18n >['__'];
// Class
type __ = I18n['__']
Would we consider using a class internally and exposing a create function that wraps it like was suggested here #20318 (comment)
const createI18n = ( ...args ) => new I18n( ...args );
I'd like to get this merged, it seems to be in good shape so I'll plan to land it early next week unless there's additional feedback. cc: @youknowriad @aduth @jsnajdr who've been actively involved in discussion. |
Is the idea that the type of the class |
I did some testing and this may not be an issue because the type is defined independently. With #18942, it may require this change in the index to export the export * from './create-i18n'; We should be able to sort this out after, I'm not concerned about getting this change into this PR. |
This appears to be abandoned. I've created #21182 to address feedback as I can't work on this branch. |
Closing in favor of #21182. |
Description
As per the proposed solution in #19210 I've refactored the
@wordpress/i18n
module to expose an instantiable class. e.g.There are no changes to the existing external interface of the module other than the addition of the
I18N
class.How has this been tested?
Via the existing suite of unit tests and an additional unit test.
Screenshots
N/A
Types of changes
New feature.
Checklist: