Open noahtallen opened 1 year ago
Thanks for opening an issue, @noahtallen!
I and the rest of @Automattic/team-calypso-frameworks would love to aid with those.
Perhaps @sirbrillig and the rest of @Automattic/shilling folks could aid with the checkout-related ones?
I'm curious: in my testing, while passing the store to useSelect
does correctly provide types, passing the store to useDispatch
always seems to return any
. Is that expected or am I doing something wrong?
I'm curious: in my testing, while passing the store to
useSelect
does correctly provide types, passing the store touseDispatch
always seems to returnany
. Is that expected or am I doing something wrong?
This is expected, @sirbrillig, because useDispatch
types were added later in https://github.com/WordPress/gutenberg/pull/43528.
We'll improve the situation with useDispatch
types as soon as we upgrade to a newer version of the @wordpress
packages, which is on our radar.
Sounds good! I just wanted to make sure I was doing it right!
Many of the usages of those stores are in Gutenboarding, which I found to be unused. See #74475 where I explain in detail and suggest its removal.
Landing that will make part of the work refactoring those stores easier, since some may end up unused.
I ran into an issue with block-editor-nux (#74454). Essentially, with the way the wp data persistence plugin works, it only works if you use registerStore
and not the other methods. However, there has been a lot of work and deprecation around the plugin layer in general, so there's not a straightforward solution. Hopefully we can have a conversation about that in core here: https://github.com/WordPress/gutenberg/issues/11449
In this PR, there are suggestions that using the old registration approach for data stores improves tree shaking. Thoughts?
In this PR, there are suggestions that using the old registration approach for data stores improves tree shaking. Thoughts?
I'm not concerned about this for a few reasons:
"sideEffects": false
in a corresponding package.json file), tree shaking won't really work. We don't follow that practice often in Calypso, therefore we don't leverage tree shaking properly either. With that in mind, what difference does this make? Nothing measurable from what I can expect.register()
function is an additional layer of indirection, yet another abstraction, which I'm not sure is justified. register()
function we had to check the store for existence before registration. That pattern to me was yet another code smell and indication that we're likely not doing something properly, especially given that this pattern doesn't exist in Gutenberg. register()
function felt like a naming conflict. Is this our register()
data store registration function? Is it @wordpress/data
's register()
function? One would have to look at the imports to be sure.useDispatch()
a few months ago.Nice explanation, thanks! One related thought I had is that importing anything from @automattic/data-stores
probably registers every single store in the package, given that the file import in the top-level index file of that package will cause every store to register. This didn't happen before. I don't immediately have any concerns about it, though.
Nice explanation, thanks! One related thought I had is that importing anything from
@automattic/data-stores
probably registers every single store in the package, given that the file import in the top-level index file of that package will cause every store to register. This didn't happen before. I don't immediately have any concerns about it, though.
That's a valid one, indeed. I don't very much like the idea of re-exporting everything through the main package anyway, especially given that we have side effects. One way to beat that would be to not use a primary index
and re-export there, but rather to import from the specific stores only, using bare module specifier resolution:
import { AutomatedTransferEligibility } from '@automattic/data-stores/automated-transfer-eligibility';
importing anything from
@automattic/data-stores
probably registers every single store in the package
The every-store-registration shouldn't be happening. The data-stores
package has the sideEffects: false
flag enabled, and when there are re-exports like this in data-stores/index.js
:
import * as Foo from './foo';
import * as Bar from './bar';
export { Foo, Bar };
Then webpack will load ./foo
only if its exports are actually imported anywhere. Reexports are "pass-through", i.e., if some useFoo.js
file imports Foo
:
import { Foo } from 'data-stores';
webpack will not consider the intermediate index.js
file, and will treat it as "useFoo.js
is importing Foo
from data-stores/foo.js
". Cut out the middleman!
The caveat is that the Foo
store will be registered only if Foo
is imported anywhere. In other words, you are kind of forced to use the new store description convention:
import { Foo } from 'data-stores';
registry.select( Foo.store ).getFoo();
In other words, you are kind of forced to use the new store description convention
Nice, thanks for the explanation. This side effect stuff can get tricky :)
We are migrating how these stores are used at the same time. Previously, you still needed to import Foo
store and register it somewhere in the app. In most cases, the consumer also re-exported the store key and then used that to access the stores. So it's not a massive change -- just removing one or two layers of indirection
Details
The main reason we should do this is that
registerStore
is deprecated. But the main benefit we get is the new approach to using stores gives us much better typescript integration. Previously, one would have to declare types to override the entire wp data package.This is actually impossible to do now that the package provides its own typedefs, so we've had to rely on the temporary solution of casting to selector types like
(select( 'automattic/foo' ) as FooSelectors).selector()
. This is very clunky, and we also lost type info fordispatch
calls. (See this comment for more info.)As a result, we should migrate stores to use the "new" format (it's been available for a long time actually, though it wasn't supported by the WordPress versions we support at first.) And ideally, also start using stores via imports instead of via string names!
This will restore type data we lost in the upgrade, and also make types much easier to work with for WordPress data.
This is all made possible by our recent WordPress package updates done in #73890.
Checklist
A store is registered in each of these files. See PRs for example migrations.
Editing Toolkit Plugin
editing-toolkit-plugin/global-styles/src/store.js
@noahtallen #74394apps/editing-toolkit/editing-toolkit-plugin/whats-new/src/store.js
@noahtallen #74395apps/editing-toolkit/editing-toolkit-plugin/wpcom-block-editor-nav-sidebar/src/store.ts
@noahtallen #74396apps/editing-toolkit/editing-toolkit-plugin/starter-page-templates/store.ts
@noahtallen #74346Calypso data-stores
packages/data-stores/src/analyzer/index.ts
@tyxla #74414packages/data-stores/src/auth/index.ts
@tyxla #74418packages/data-stores/src/automated-transfer-eligibility/index.ts
@noahtallen #74550packages/data-stores/src/domain-suggestions/index.ts
@noahtallen #74551packages/data-stores/src/i18n/index.ts
@tyxla #74427packages/data-stores/src/plans/index.ts
packages/data-stores/src/products-list/index.ts
@tyxla #74566packages/data-stores/src/reader/index.ts
@tyxla #74425packages/data-stores/src/subscriber/index.ts
@flootr #74430packages/data-stores/src/user/index.ts
packages/data-stores/src/wpcom-features/index.ts
@tyxla #74473packages/data-stores/src/wpcom-plans-ui/index.ts
@tyxla #74468.register
instructions once all stores are migrated.Payments related
client/state/partner-portal/credit-card-form/index.ts
@tyxla #74656client/my-sites/checkout/composite-checkout/hooks/wpcom-store.ts
https://github.com/Automattic/wp-calypso/pull/74452client/my-sites/checkout/composite-checkout/payment-methods/netbanking.tsx
client/my-sites/checkout/composite-checkout/payment-methods/paypal.tsx
client/my-sites/checkout/composite-checkout/payment-methods/credit-card/store.ts
client/my-sites/checkout/composite-checkout/payment-methods/wechat/index.tsx
packages/wpcom-checkout/src/payment-methods/alipay.tsx
packages/wpcom-checkout/src/payment-methods/bancontact.tsx
packages/wpcom-checkout/src/payment-methods/eps.tsx
packages/wpcom-checkout/src/payment-methods/giropay.tsx
packages/wpcom-checkout/src/payment-methods/ideal.tsx
packages/wpcom-checkout/src/payment-methods/p24.tsx
packages/wpcom-checkout/src/payment-methods/sofort.tsx
On hold:
These two persist a single option to help keep a modal close. Could probably be migrated to wp preferences.
apps/editing-toolkit/editing-toolkit-plugin/wpcom-block-editor-nux/src/store.js
@noahtallen #74454apps/editing-toolkit/editing-toolkit-plugin/wpcom-global-styles/store.js
@noahtallen #74500These data stores persist several options. Since these persist much more of the store, it'd be harder to migrate them to wp preferences.
packages/data-stores/src/help-center/index.ts
packages/data-stores/src/launch/index.ts
@tyxla #75269packages/data-stores/src/onboard/index.ts
packages/data-stores/src/site/index.ts
packages/data-stores/src/stepper-internal/index.ts
Address this after double registration issue is solved: