Skip to content
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

fix: compat with emotion v11.14 #3054

Merged
merged 3 commits into from
Feb 7, 2025
Merged

fix: compat with emotion v11.14 #3054

merged 3 commits into from
Feb 7, 2025

Conversation

emmenko
Copy link
Member

@emmenko emmenko commented Feb 5, 2025

When upgrading to Emotion v11.14.0, we get some type errors from the generated declaration files about imports import("@emotion/react/types/jsx-namespace").EmotionJSX.Element.

I reported the issue: emotion-js/emotion#3310.

Then I tried looking at using different options of the moduleResolution option. It seems that the "better" choice would be to use the bundler option, which actually might be more appropriate anyway for a component library.

I went ahead and asked Gemini for some clarification:

Q: For a component library, is it recommended to use `moduleResolution: bundler`?

A: For a component library, `moduleResolution: bundler` is generally a good choice and often recommended, especially if you're targeting modern JavaScript environments and want to optimize for bundle size and code splitting. However, there are some nuances to consider.

Advantages of `moduleResolution: bundler`:

* Optimized Bundles:  Bundlers like Webpack, Rollup, or Parcel are designed to analyze your code and create highly optimized bundles.  They can eliminate dead code (tree-shaking), minify code, and perform code splitting to load only the necessary parts of your library on demand. This leads to smaller bundle sizes and faster load times for users of your library.

* Modern JavaScript Features: `moduleResolution: bundler` works seamlessly with modern JavaScript features like ES modules (`import/export`), which are essential for code splitting and efficient bundling.

* Dependency Management: Bundlers handle dependency resolution efficiently, ensuring that the correct versions of your library's dependencies are included in the bundle.  They also help avoid issues with conflicting dependencies.

* Flexibility: Bundlers offer a lot of flexibility in terms of how you configure your build process. You can customize how your library is bundled, how assets are handled, and much more.

Recommendation:

For most component libraries, `moduleResolution: bundler` is the recommended approach.  The benefits of optimized bundles, modern JavaScript support, and dependency management usually outweigh the added complexity.  Choose a bundler that suits your needs (Webpack, Rollup, or Parcel are all good options).  If your library is exceptionally small and you have very specific constraints, you might consider `moduleResolution: node` or classic, but this is less common.

Key takeaway: The "not portable" error you were getting is directly related to the way `moduleResolution: bundler` works and its desire to avoid long paths.  So, sticking with bundler is still the right choice, and the solutions provided earlier (type annotations or importing types) are the correct way to address the error within the bundler context.

@emmenko emmenko requested a review from a team as a code owner February 5, 2025 14:12
@emmenko emmenko requested review from stephsprinkle, jaikamat, ddouglasz, tylermorrisford, ByronDWall and misama-ct and removed request for a team February 5, 2025 14:12
Copy link

changeset-bot bot commented Feb 5, 2025

🦋 Changeset detected

Latest commit: 2133ee4

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 98 packages
Name Type
@commercetools-uikit/async-creatable-select-input Patch
@commercetools-uikit/creatable-select-input Patch
@commercetools-uikit/async-select-input Patch
@commercetools-uikit/flat-button Patch
@commercetools-uikit/select-input Patch
@commercetools-uikit/async-creatable-select-field Patch
@commercetools-uikit/inputs Patch
@commercetools-uikit/creatable-select-field Patch
@commercetools-uikit/data-table-manager Patch
@commercetools-uikit/async-select-field Patch
@commercetools-uikit/search-select-input Patch
@commercetools-uikit/filters Patch
@commercetools-uikit/password-field Patch
@commercetools-uikit/input-utils Patch
@commercetools-uikit/localized-money-input Patch
@commercetools-uikit/localized-multiline-text-input Patch
@commercetools-uikit/localized-rich-text-input Patch
@commercetools-uikit/localized-text-input Patch
@commercetools-uikit/multiline-text-input Patch
@commercetools-uikit/rich-text-input Patch
@commercetools-uikit/buttons Patch
@commercetools-uikit/pagination Patch
@commercetools-uikit/select-field Patch
@commercetools-uikit/fields Patch
@commercetools-frontend/ui-kit Patch
@commercetools-uikit/data-table Patch
@commercetools-uikit/search-select-field Patch
@commercetools-uikit/calendar-utils Patch
@commercetools-uikit/checkbox-input Patch
@commercetools-uikit/money-input Patch
@commercetools-uikit/number-input Patch
@commercetools-uikit/password-input Patch
@commercetools-uikit/radio-input Patch
@commercetools-uikit/rich-text-utils Patch
@commercetools-uikit/search-text-input Patch
@commercetools-uikit/selectable-search-input Patch
@commercetools-uikit/text-input Patch
@commercetools-uikit/time-input Patch
@commercetools-uikit/toggle-input Patch
@commercetools-uikit/localized-multiline-text-field Patch
@commercetools-uikit/localized-text-field Patch
@commercetools-uikit/multiline-text-field Patch
@commercetools-uikit/primary-action-dropdown Patch
@commercetools-uikit/date-input Patch
@commercetools-uikit/date-range-input Patch
@commercetools-uikit/date-time-input Patch
@commercetools-uikit/select-utils Patch
@commercetools-uikit/money-field Patch
@commercetools-uikit/number-field Patch
@commercetools-uikit/radio-field Patch
@commercetools-uikit/text-field Patch
@commercetools-uikit/time-field Patch
@commercetools-uikit/date-field Patch
@commercetools-uikit/date-range-field Patch
@commercetools-uikit/date-time-field Patch
@commercetools-uikit/design-system Patch
@commercetools-uikit/calendar-time-utils Patch
@commercetools-uikit/hooks Patch
@commercetools-uikit/i18n Patch
@commercetools-uikit/localized-utils Patch
@commercetools-uikit/utils Patch
@commercetools-uikit/accessible-hidden Patch
@commercetools-uikit/avatar Patch
@commercetools-uikit/card Patch
@commercetools-uikit/collapsible-motion Patch
@commercetools-uikit/collapsible-panel Patch
@commercetools-uikit/collapsible Patch
@commercetools-uikit/constraints Patch
@commercetools-uikit/field-errors Patch
@commercetools-uikit/field-label Patch
@commercetools-uikit/field-warnings Patch
@commercetools-uikit/grid Patch
@commercetools-uikit/icons Patch
@commercetools-uikit/label Patch
@commercetools-uikit/link Patch
@commercetools-uikit/loading-spinner Patch
@commercetools-uikit/messages Patch
@commercetools-uikit/notifications Patch
@commercetools-uikit/progress-bar Patch
@commercetools-uikit/quick-filters Patch
@commercetools-uikit/stamp Patch
@commercetools-uikit/tag Patch
@commercetools-uikit/text Patch
@commercetools-uikit/tooltip Patch
@commercetools-uikit/view-switcher Patch
@commercetools-uikit/accessible-button Patch
@commercetools-uikit/icon-button Patch
@commercetools-uikit/link-button Patch
@commercetools-uikit/primary-button Patch
@commercetools-uikit/secondary-button Patch
@commercetools-uikit/secondary-icon-button Patch
@commercetools-uikit/dropdown-menu Patch
@commercetools-uikit/spacings-inline Patch
@commercetools-uikit/spacings-inset-squish Patch
@commercetools-uikit/spacings-inset Patch
@commercetools-uikit/spacings-stack Patch
@commercetools-uikit/spacings Patch
visual-testing-app Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copy link

vercel bot commented Feb 5, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
ui-kit ✅ Ready (Inspect) Visit Preview 💬 Add feedback Feb 7, 2025 7:45am

Comment on lines +564 to +567
AsyncCreatableSelectInput.ClearIndicator =
customizedComponents.ClearIndicator as ComponentType<
ClearIndicatorProps<{}, false, GroupBase<{}>>
>;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These changes are related to the way the bundler option attempts to optimize to avoid long paths.

The error was something like this:

The inferred type of 'AsyncCreatableSelectInput' cannot be named without a reference to '../../../../../../../node_modules/react-select/dist/declarations/src/components/Menu'. This is likely not portable. A type annotation is necessary.

I asked Gemini:

The error arises because TypeScript's `moduleResolution: bundler` (and similar modern module resolution strategies) prioritize bundle size and efficient code splitting.  It's trying to avoid emitting very long, specific paths in your type declarations, which could bloat the output and cause issues in different build environments.

The core issue is that TypeScript is inferring a type that directly references an internal, implementation detail of `react-select`.  This is fragile because that path could change in future versions of react-select.  Your type declarations become tied to the internal structure of a dependency.

The most direct and usually best solution is to explicitly provide a type annotation [...].

Therefore, we are explicitly typing all those "re-exports".

PS: I'm not sure if it still makes sense to keep these "re-exports". We might want to remove them at some point and the consumer would need to import them from react-select directly.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

react-select types are consistently an issue, so it's no real surprise that the re-exports are causing module resolution issues.

The 're-exporting' is happening because of the 'custom' components from uikit that are replacing a subset of the 'default' components from react-select. The 'custom' components should be exported here, since they cannot come from react-select.

There is not a distinction between which components are 'custom' or 'default' in the uikit docs, and only exporting the 'custom' subset seems like it would only make it more confusing to understand how to implement an already fairly complex component.

@emmenko emmenko requested a review from a team February 5, 2025 14:18
Copy link
Contributor

@Rhotimee Rhotimee left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

Copy link
Contributor

@misama-ct misama-ct left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🙇‍♂️

@emmenko emmenko merged commit 3f97470 into main Feb 7, 2025
8 checks passed
@emmenko emmenko deleted the nm-compat-emotion-v11.14 branch February 7, 2025 11:27
@ct-changesets ct-changesets bot mentioned this pull request Feb 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants