Skip to content

build: remove babel and introduce swc as main test transpiler#8045

Draft
tomdavies73 wants to merge 1 commit into
masterfrom
say_bye_to_babel
Draft

build: remove babel and introduce swc as main test transpiler#8045
tomdavies73 wants to merge 1 commit into
masterfrom
say_bye_to_babel

Conversation

@tomdavies73

@tomdavies73 tomdavies73 commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Proposed behaviour

Removes all babel related dependencies and instead uses swc/jest as the main test transpiler. In order to transition to swc/jest some additional changes have also been made.

babel/jest's less aggressive tree-shaking meant it would often leave unused exports in place during transpilation. swc/jest takes a stricter approach - it analyses exports more carefully and expects us to be more explicit about what we're exporting and using.

All exports which are unused (not imported anywhere else internally) were highlighted and have had to be removed.

There were multiple instances of consts which were only used locally in one file being exported, or instances of some costs being exported and never being used locally or elsewhere.

In some files we have also "doubled up" our exports, exporting twice as a named export and a default export. Where possible the named export has been removed, and only the default export remains.

config.ts and index.ts files are now exempt from the coverage report, as config.ts consts are typically used in stories and therefore are treated as unused. index.ts files exports are consumer facing entry points, so they have also been exempt as some exports are never imported and used elsewhere.

Current behaviour

Currently, there are multiple babel dependencies which are unused and babel/jest is used for test transpilation.

Checklist

  • Commits follow our style guide
  • Related issues linked in commit messages if required
  • Screenshots are included in the PR if useful
  • All themes are supported if required
  • Unit tests added or updated if required
  • Playwright automation tests added or updated if required
  • Storybook added or updated if required
  • Translations added or updated (including creating or amending translation keys table in storybook) if required
  • Typescript d.ts file added or updated if required
  • Related docs have been updated if required

QA

  • Tested in provided StackBlitz sandbox/Storybook
  • Add new Playwright test coverage if required
  • Carbon implementation matches Design System/designs
  • UI Tests GitHub check reviewed if required

Additional context

Testing instructions

@tomdavies73 tomdavies73 self-assigned this Jun 25, 2026
@tomdavies73 tomdavies73 added DO NOT MERGE Work in progress This is a WIP PR so may not be ready for review labels Jun 25, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Warning

  • Copilot's review of this pull request may be incomplete because some of the changed files are excluded by your Copilot content exclusion settings. See Excluding content from Copilot for details.

Pull request overview

Updates the repo’s Jest transpilation pipeline by replacing Babel/Jest with SWC, and refactors a large number of modules to prefer default exports (plus a few coverage-oriented test additions) to keep tests/build tooling working consistently in the new setup.

Changes:

  • Replace babel-jest with @swc/jest for Jest transforms; remove Babel config/deps and add .swcrc.
  • Refactor many components/utils to use default exports (and remove some previously exported symbols).
  • Add/adjust a handful of tests to exercise previously-ignored styled-component/default-render paths for coverage.

Reviewed changes

Copilot reviewed 215 out of 216 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/style/utils/merge-deep.ts Switch to default export for mergeDeep.
src/style/utils/merge-deep.test.ts Update test import to default export.
src/style/utils/filter-styled-system-layout-props.ts Stop exporting internal layoutPropertyNames.
src/style/utils/filter-styled-system-grid-props.ts Stop exporting internal gridPropertyNames.
src/style/utils/filter-styled-system-flexbox-props.ts Stop exporting internal flexboxPropertyNames.
src/style/themes/base/index.ts Update mergeDeep import to default.
src/style/global-style.ts Import focus-trap constants from utils module.
src/hooks/internal/useStableCallback/useStableCallback.ts Convert to default-export-only implementation.
src/components/vertical-menu/vertical-menu.component.tsx Default-export component only (no named export).
src/components/vertical-menu/vertical-menu-trigger/vertical-menu-trigger.component.tsx Default-export component only (no named export).
src/components/vertical-menu/vertical-menu-item/vertical-menu-item.component.tsx Default-export component only (no named export).
src/components/vertical-menu/vertical-menu-full-screen/vertical-menu-full-screen.component.tsx Default-export component only (no named export).
src/components/vertical-menu/responsive-vertical-menu/responsive-vertical-menu.context.tsx Make context non-exported const; keep hook/provider exports.
src/components/vertical-menu/responsive-vertical-menu/responsive-vertical-menu.component.tsx Remove default export; keep named export.
src/components/vertical-menu/responsive-vertical-menu/responsive-vertical-menu-item/responsive-vertical-menu-item.stories.tsx Update story imports for default export.
src/components/vertical-menu/responsive-vertical-menu/responsive-vertical-menu-item/responsive-vertical-menu-item.component.tsx Default-export component only (no named export).
src/components/vertical-menu/responsive-vertical-menu/responsive-vertical-menu-divider/responsive-vertical-menu-divider.stories.tsx Update story imports for default export.
src/components/vertical-menu/responsive-vertical-menu/responsive-vertical-menu-divider/responsive-vertical-menu-divider.component.tsx Default-export component only (no named export).
src/components/vertical-menu/responsive-vertical-menu/internal/depth.context.tsx Remove default export of context value.
src/components/vertical-divider/vertical-divider.component.tsx Default-export component only (no named export).
src/components/typography/typography.component.tsx Default-export component only (no named export).
src/components/typography/list.context.tsx Convert ListContext to non-exported const; keep default export.
src/components/typography/internal/next/typography.component.tsx Make VARIANT_TYPES internal; default-export component.
src/components/tooltip/tooltip.component.tsx Default-export component only (no named export).
src/components/tokens-wrapper/tokens-wrapper.component.tsx Default-export component only (no named export).
src/components/toast/toast.component.tsx Default-export component only (no named export).
src/components/tile/tile.component.tsx Default-export component only (no named export).
src/components/tile/tile-header/tile-header.component.tsx Default-export component only (no named export).
src/components/tile/tile-footer/tile-footer.component.tsx Default-export component only (no named export).
src/components/tile/flex-tile-divider/flex-tile-divider.component.tsx Default-export component only (no named export).
src/components/tile/flex-tile-container/flex-tile-container.component.tsx Default-export component only (no named export).
src/components/tile/flex-tile-cell/flex-tile-cell.component.tsx Default-export component only (no named export).
src/components/tile-select/tile-select-group/tile-select-group.component.tsx Default-export component only (no named export).
src/components/textbox/textbox.component.tsx Default-export component only (no named export).
src/components/textbox/internal/next/text-input.component.tsx Default-export component only (no named export).
src/components/textbox/internal/next/index.ts Adjust type re-exports to reference default export.
src/components/textarea/textarea.component.tsx Remove OriginalTextarea re-export; keep default export.
src/components/text-editor/text-editor.style.ts Convert StyledTextEditor to default-only export.
src/components/text-editor/text-editor.component.tsx Update getTheme import; default-export component only.
src/components/text-editor/internal/utils/theme.ts Convert to default export (getTheme).
src/components/text-editor/internal/utils/helpers.ts Update getTheme import to default.
src/components/text-editor/internal/ui/Toolbar/buttons/typography.component.tsx Make helper function non-exported.
src/components/text-editor/internal/ui/ReadOnlyEditor/read-only-rte.component.tsx Update getTheme import to default.
src/components/text-editor/internal/ui/Mentions/mentions.test.tsx Add coverage test for portal render path.
src/components/text-editor/internal/ui/Mentions/mentions-typeahead-menu-item.component.tsx Default-export component only (no named export).
src/components/text-editor/internal/ui/Mentions/mention-typeahead-option.class.ts Convert to default export class only (no named export).
src/components/text-editor/internal/ui/Mentions/constants.ts Make most constants internal; keep list-length limit export.
src/components/text-editor/internal/ui/CharacterCounter/character-counter.style.ts Remove unused default export.
src/components/text-editor/internal/plugins/FormSubmission/form-submission.plugin.tsx Default-export component only (no named export).
src/components/tabs/tabs.component.tsx Remove default export from legacy wrapper component.
src/components/tabs/tab/tab.stories.tsx Update story import for default export.
src/components/tabs/tab/tab.component.tsx Default-export component only (no named export).
src/components/tabs/next/tabs.test.tsx Add coverage tests for styled exports; mock resize observer.
src/components/tabs/next/tabs.style.ts Remove istanbul ignore comments now covered by tests.
src/components/switch/switch.component.tsx Default-export component only (no named export).
src/components/step-sequence/step-sequence.component.tsx Default-export component only (no named export).
src/components/step-sequence/step-sequence-item/step-sequence-item.component.tsx Default-export component only (no named export).
src/components/step-flow/step-flow.component.tsx Default-export component only (no named export).
src/components/step-flow/step-flow-title/step-flow-title.component.tsx Default-export component only (no named export).
src/components/split-button/split-button.component.tsx Default-export component only (no named export).
src/components/simple-color-picker/simple-color/simple-color.component.tsx Default-export component only (no named export).
src/components/simple-color-picker/simple-color-picker.component.tsx Default-export component only (no named export).
src/components/sidebar/sidebar.component.tsx Default-export component only (no named export).
src/components/settings-row/settings-row.component.tsx Default-export component only (no named export).
src/components/select/simple-select/simple-select.component.tsx Default-export component only (no named export).
src/components/select/multi-select/multi-select.component.tsx Default-export component only (no named export).
src/components/select/filterable-select/filterable-select.component.tsx Default-export component only (no named export).
src/components/search/search.component.tsx Default-export component only (no named export).
src/components/search/search-button.style.ts Remove unused styled export.
src/components/radio-button/radio-button.component.tsx Default-export component only (no named export).
src/components/radio-button/radio-button-group/radio-button-group.component.tsx Default-export component only (no named export).
src/components/profile/profile.component.tsx Default-export component only (no named export).
src/components/preview/preview.component.tsx Default-export component only (no named export).
src/components/portrait/portrait.component.tsx Default-export component only (no named export).
src/components/portal/portal.tsx Default-export component only (no named export).
src/components/popover-container/popover-container.test.tsx Add coverage tests for default renderOpen/renderClose.
src/components/popover-container/popover-container.component.tsx Default-export component only (no named export).
src/components/pill/pill.component.tsx Default-export component only (no named export).
src/components/password/password.component.tsx Default-export component only (no named export).
src/components/pager/pager.component.tsx Default-export component only (no named export).
src/components/numeral-date/numeral-date.component.tsx Make allowed formats internal; default-export component.
src/components/number/number.component.tsx Default-export component only (no named export).
src/components/note/note.component.tsx Default-export component only (no named export).
src/components/navigation-bar/navigation-bar.component.tsx Default-export component only (no named export).
src/components/navigation-bar/internal/fixed-navigation-bar-context.test.tsx Update resize observer mocking approach.
src/components/multi-action-button/multi-action-button.component.tsx Default-export component only (no named export).
src/components/message/message.component.tsx Default-export component only (no named export).
src/components/menu/scrollable-block/scrollable-block.component.tsx Default-export component only (no named export).
src/components/menu/menu.component.tsx Default-export component only (no named export).
src/components/menu/menu-segment-title/menu-segment-title.context.tsx Make context non-exported const; keep default export.
src/components/menu/menu-item/menu-item.component.tsx Default-export component only (no named export).
src/components/menu/menu-full-screen/menu-full-screen.component.tsx Default-export component only (no named export).
src/components/loader/loader.component.tsx Default-export component only (no named export).
src/components/loader/next/loader.style.ts Remove unused styled export.
src/components/loader-spinner/loader-spinner.component.tsx Default-export component only (no named export).
src/components/loader-bar/loader-bar.component.tsx Default-export component only (no named export).
src/components/link/link.component.tsx Default-export component only (no named export).
src/components/link-preview/link-preview.component.tsx Default-export component only (no named export).
src/components/link-preview/internal/placeholder.component.tsx Convert styled component to default-only export.
src/components/image/image.component.tsx Default-export component only (no named export).
src/components/i18n-provider/i18n-provider.component.tsx Default-export component only (no named export).
src/components/hr/hr.component.tsx Default-export component only (no named export).
src/components/help/help.component.tsx Default-export component only (no named export).
src/components/help/help-test.stories.tsx Update story import for default export.
src/components/heading/heading.component.tsx Default-export component only (no named export).
src/components/grouped-character/grouped-character.component.tsx Default-export component only (no named export).
src/components/form/required-fields-indicator/required-fields-indicator.component.tsx Default-export component only (no named export).
src/components/form/form.config.ts Remove exported alignment constant; keep type + spacing map.
src/components/form/form.component.tsx Default-export component only (no named export).
src/components/form/internal/form-summary.component.tsx Default-export component only (no named export).
src/components/flat-table/sort/sort.component.tsx Default-export component only (no named export).
src/components/flat-table/flat-table.component.tsx Default-export component only (no named export).
src/components/flat-table/flat-table-row/flat-table-row.component.tsx Default-export component only (no named export).
src/components/flat-table/flat-table-row-header/flat-table-row-header.component.tsx Default-export component only (no named export).
src/components/flat-table/flat-table-header/flat-table-header.component.tsx Default-export component only (no named export).
src/components/flat-table/flat-table-head/flat-table-head.component.tsx Default-export component only (no named export).
src/components/flat-table/flat-table-checkbox/flat-table-checkbox.component.tsx Default-export component only (no named export).
src/components/flat-table/flat-table-cell/flat-table-cell.component.tsx Default-export component only (no named export).
src/components/flat-table/flat-table-body/flat-table-body.component.tsx Default-export component only (no named export).
src/components/flat-table/flat-table-body-draggable/flat-table-body-draggable.component.tsx Default-export component only (no named export).
src/components/file-input/file-input.component.tsx Default-export component only (no named export).
src/components/file-input/internal/file-upload-status/file-upload-status.component.tsx Default-export component only (no named export).
src/components/fieldset/fieldset.component.tsx Default-export component only (no named export).
src/components/duelling-picklist/picklist-placeholder/picklist-placeholder.component.tsx Default-export component only (no named export).
src/components/duelling-picklist/picklist-item/picklist-item.component.tsx Default-export component only (no named export).
src/components/duelling-picklist/picklist-group/picklist-group.component.tsx Default-export component only (no named export).
src/components/duelling-picklist/duelling-picklist.component.tsx Default-export component only (no named export).
src/components/duelling-picklist/components.test-pw.tsx Update Checkbox import for default export.
src/components/drawer/drawer.component.tsx Remove named context export; keep default component export.
src/components/divider/divider.component.tsx Default-export component only (no named export).
src/components/dismissible-box/dismissible-box.component.tsx Default-export component only (no named export).
src/components/dialog/dialog.component.tsx Default-export component only (no named export).
src/components/dialog/internal/next/dialog.style.ts Narrow exported styled/public constants list.
src/components/dialog/internal/next/dialog.component.tsx Stop re-exporting withDialogHeader from this module.
src/components/dialog/internal/next/dialog-test.stories.tsx Update story imports for withDialogHeader.
src/components/dialog/internal/next/components-test.pw.tsx Update Playwright test imports for withDialogHeader.
src/components/dialog-full-screen/dialog-full-screen.component.tsx Default-export component only (no named export).
src/components/detail/detail.component.tsx Default-export component only (no named export).
src/components/decimal/decimal.component.tsx Default-export component only (no named export).
src/components/date/date.component.tsx Default-export component only (no named export).
src/components/date/internal/weekday/weekday.component.tsx Default-export component only (no named export).
src/components/date/internal/navbar/navbar.component.tsx Default-export component only (no named export).
src/components/date/internal/date-picker/date-picker.component.tsx Default-export component only (no named export).
src/components/date-range/date-range.component.tsx Default-export component only (no named export).
src/components/content/content.component.tsx Default-export component only (no named export).
src/components/confirm/confirm.component.tsx Default-export component only (no named export).
src/components/checkbox/checkbox.component.tsx Default-export component only (no named export).
src/components/checkbox/checkbox-group/checkbox-group.component.tsx Default-export component only (no named export).
src/components/card/card.style.ts Make size maps internal instead of exported consts.
src/components/carbon-provider/carbon-provider.component.tsx Default-export component only (no named export).
src/components/carbon-provider/internal/top-modal-provider.component.tsx Default-export provider only (no named export).
src/components/button/next/button.style.ts Convert styled root to default-only export.
src/components/button/next/button.component.tsx Default-export component only (no named export).
src/components/button-toggle/button-toggle.component.tsx Default-export component only (no named export).
src/components/button-minor/button-minor.component.tsx Default-export component only (no named export).
src/components/button-bar/button-bar.component.tsx Default-export component only (no named export).
src/components/breadcrumbs/crumb/index.ts Update crumb export to default-based re-export.
src/components/breadcrumbs/crumb/crumb.style.ts Change default export shape (component instead of object).
src/components/breadcrumbs/crumb/crumb.component.tsx Update style imports; default-export crumb only.
src/components/breadcrumbs/breadcrumbs.component.tsx Default-export component only (no named export).
src/components/box/box.component.tsx Default-export component only (no named export).
src/components/batch-selection/batch-selection.component.tsx Default-export component only (no named export).
src/components/badge/badge.component.tsx Default-export component only (no named export).
src/components/alert/alert.component.tsx Default-export component only (no named export).
src/components/advanced-color-picker/advanced-color-picker.component.tsx Default-export component only (no named export).
src/components/adaptive-sidebar/adaptive-sidebar.component.tsx Default-export component only (no named export).
src/components/action-popover/action-popover.component.tsx Default-export component only (no named export).
src/components/action-popover/action-popover-menu-button/action-popover-menu-button.component.tsx Default-export component only (no named export).
src/components/accordion/accordion.component.tsx Default-export component only (no named export).
src/components/accordion/accordion-group/accordion-group.component.tsx Default-export component only (no named export).
src/internal/validations/validation-icon.component.tsx Default-export component only (no named export).
src/internal/popover-menu/popover-menu.component.tsx Update hook import; make List styled component internal.
src/internal/popover-menu/hooks/useHandleDropdownMenuKeyDown.ts Convert hook + helpers to internal; default export hook.
src/internal/popover-menu/hooks/index.ts Switch barrel to default export only.
src/internal/legacy-label/label.component.tsx Default-export component only (no named export).
src/internal/legacy-hint-text/hint-text.component.tsx Default-export component only (no named export).
src/internal/label/label.component.tsx Default-export component only (no named export).
src/internal/hint-text/hint-text.component.tsx Default-export component only (no named export).
src/internal/focus-trap/focus-trap.component.tsx Move tab-guard constants to utils import.
src/internal/focus-trap/focus-trap-utils.ts Add exported tab-guard constants; adjust export list.
src/internal/field-help/field-help.component.tsx Default-export component only (no named export).
src/internal/ai-icon/ai-icon.component.tsx Default-export component only (no named export).
package.json Remove Babel deps; add @swc/jest.
jest.config.ts Switch transform to @swc/jest; expand coverage ignores.
babel.config.cjs Remove Babel configuration file.
.swcrc Add SWC config for Jest transpilation.
package-lock.json Content excluded (dependency lock updated).
skills/carbon-react/index.md Content excluded (skills docs update).
skills/carbon-react/components/pod.md Content excluded (skills docs update).
skills/carbon-react/components/list.md Content excluded (skills docs update).
skills/carbon-react/components/link.md Content excluded (skills docs update).
skills/carbon-react/components/icon.md Content excluded (skills docs update).
skills/carbon-react/components/form.md Content excluded (skills docs update).
skills/carbon-react/components/badge.md Content excluded (skills docs update).
skills/carbon-react/components/option.md Content excluded (skills docs update).
skills/carbon-react/components/number.md Content excluded (skills docs update).
skills/carbon-react/components/textbox.md Content excluded (skills docs update).
skills/carbon-react/components/sidebar.md Content excluded (skills docs update).
skills/carbon-react/components/decimal.md Content excluded (skills docs update).
skills/carbon-react/components/textarea.md Content excluded (skills docs update).
skills/carbon-react/components/password.md Content excluded (skills docs update).
skills/carbon-react/components/checkbox.md Content excluded (skills docs update).
skills/carbon-react/components/grid-item.md Content excluded (skills docs update).
skills/carbon-react/components/accordion.md Content excluded (skills docs update).
skills/carbon-react/components/typography.md Content excluded (skills docs update).
skills/carbon-react/components/date-input.md Content excluded (skills docs update).
skills/carbon-react/components/button-next.md Content excluded (skills docs update).
skills/carbon-react/components/split-button.md Content excluded (skills docs update).
skills/carbon-react/components/radio-button.md Content excluded (skills docs update).
skills/carbon-react/components/multi-select.md Content excluded (skills docs update).
skills/carbon-react/components/loader-spinner.md Content excluded (skills docs update).
skills/carbon-react/components/grid-container.md Content excluded (skills docs update).
skills/carbon-react/components/grouped-character.md Content excluded (skills docs update).
skills/carbon-react/components/filterable-select.md Content excluded (skills docs update).
skills/carbon-react/components/option-group-header.md Content excluded (skills docs update).
skills/carbon-react/components/multi-action-button.md Content excluded (skills docs update).
Files excluded by content exclusion policy (30)
  • package-lock.json
  • skills/carbon-react/components/accordion.md
  • skills/carbon-react/components/badge.md
  • skills/carbon-react/components/button-next.md
  • skills/carbon-react/components/checkbox.md
  • skills/carbon-react/components/date-input.md
  • skills/carbon-react/components/decimal.md
  • skills/carbon-react/components/filterable-select.md
  • skills/carbon-react/components/form.md
  • skills/carbon-react/components/grid-container.md
  • skills/carbon-react/components/grid-item.md
  • skills/carbon-react/components/grouped-character.md
  • skills/carbon-react/components/icon.md
  • skills/carbon-react/components/link.md
  • skills/carbon-react/components/list.md
  • skills/carbon-react/components/loader-spinner.md
  • skills/carbon-react/components/multi-action-button.md
  • skills/carbon-react/components/multi-select.md
  • skills/carbon-react/components/number.md
  • skills/carbon-react/components/option-group-header.md
  • skills/carbon-react/components/option.md
  • skills/carbon-react/components/password.md
  • skills/carbon-react/components/pod.md
  • skills/carbon-react/components/radio-button.md
  • skills/carbon-react/components/sidebar.md
  • skills/carbon-react/components/split-button.md
  • skills/carbon-react/components/textarea.md
  • skills/carbon-react/components/textbox.md
  • skills/carbon-react/components/typography.md
  • skills/carbon-react/index.md
Comments suppressed due to low confidence (1)

src/components/tabs/tabs.component.tsx:208

  • The default export for Tabs was removed. Even if the intended public API is via src/components/tabs/index.ts, removing the default export is a breaking change for deep imports (import Tabs from "…/tabs.component"). If this wasn’t intended as a breaking change, keep the default export alongside the named export.

return merge(newTarget, ...sources);
}

export default mergeDeep;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yeah, this is breaking upon reflection as consumers may be importing this in their projects. It may be worth having a wider discussion to see if this PR should be breaking as we're removing named exports and other "unused" exports from the codebase.

Whilst these may not be executed in our own tests, hence the uncovered statement, consumers in theory could be importing these and using them in their projects.

Even though consumers should not be importing anything into their project which is from .component or .style or .config some consumers may be doing this anyway. We could provide them with a bit of grace and just make this a major breaking change just to be safe.

@@ -1,5 +1,4 @@
export const FORM_BUTTON_ALIGNMENTS = ["left", "right"] as const;
export type FormButtonAlignment = (typeof FORM_BUTTON_ALIGNMENTS)[number];
export type FormButtonAlignment = "left" | "right";

@tomdavies73 tomdavies73 Jun 25, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Technically this is not a breaking change as consumers should only be importing from the components index, but it is possible consumers may have

@tomdavies73 tomdavies73 added Pending Review Pending QA No UX QA Required and removed DO NOT MERGE Work in progress This is a WIP PR so may not be ready for review labels Jun 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

2 participants