Skip to content

feat(gamut-codemods): warn about esmExternals: false in next.config - #43

Open
dreamwasp wants to merge 4 commits into
cass-gmt-1790-scope-renamefrom
cass-gmt-1790-next-config
Open

dreamwasp wants to merge 4 commits into
cass-gmt-1790-scope-renamefrom
cass-gmt-1790-next-config

Conversation

@dreamwasp

@dreamwasp dreamwasp commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Overview

Breaking change: Next.js apps that set experimental.esmExternals: false can fail to build or prerender on @skillsoft/gamut. Gamut ships strict-ESM .mjs. With that flag, Next require()s server externals, so default imports from @emotion/styled and react-select get a module object. The result is styled(...) is not a function or Element type is invalid while Next collects page data.

Stack (split from #28, merge in order):

  1. feat(gamut-codemods): add the codemods CLI and an empty scope-swap preset #38 Scaffold, based on main
  2. feat(gamut-codemods): rename packages and replace gamut-kit in scope-swap #39 Package scope rename and gamut-kit removal, based on feat(gamut-codemods): add the codemods CLI and an empty scope-swap preset #38
  3. feat(gamut-codemods): move Video imports and add Markdown video overrides #40 Video and Markdown, based on feat(gamut-codemods): rename packages and replace gamut-kit in scope-swap #39
  4. feat(gamut)!: promote deep imports to the root, renaming Menu and SelectDropdown elements #41 Deep imports and Menu/SelectDropdown renames, based on feat(gamut-codemods): rename packages and replace gamut-kit in scope-swap #39
  5. feat(gamut-codemods): rename the ESLint plugin prefix in scope-swap #42 ESLint plugin prefix, based on feat(gamut-codemods): rename packages and replace gamut-kit in scope-swap #39
  6. feat(gamut-codemods): warn about esmExternals: false in next.config #43 Next.js esmExternals warning, based on feat(gamut-codemods): rename packages and replace gamut-kit in scope-swap #39 👈 this PR
  7. build(deps): make @skillsoft packages easier to install #44 Simpler dependencies (independent), based on main
  8. feat(gamut-agent-tools): add the gamut-scope-swap skill #45 gamut-scope-swap skill (open last), based on feat(gamut-codemods): rename packages and replace gamut-kit in scope-swap #39, includes feat(gamut-codemods): move Video imports and add Markdown video overrides #40–feat(gamut-codemods): warn about esmExternals: false in next.config #43
  • next-config is report only. It warns about esmExternals: false in next.config.* and adds a checklist item to remove it, along with any @emotion/* aliases or transpilePackages entries that were working around it.
  • Why it doesn't rewrite the config: dropping the flag can take other config with it, so it warns instead.
  • README: "Known limits" now points at the warning. The fallback for apps that can't drop the flag yet (NEXT_EMOTION_INTEROP.md) ships with the agent skill PR.

PR Checklist

  • Related to designs: N/A
  • Related to JIRA ticket: GMT-1790
  • Changeset added
  • I have run this code to verify it works
  • This PR includes unit tests for the code change
  • This PR includes testing instructions for the code change
  • Package previews from this PR are passing end-to-end tests in all relevant consuming repositories

Testing Instructions

  1. yarn nx test gamut-codemods. Expect 68 tests to pass.

  2. Build and run on a throwaway repo:

    yarn nx build gamut-codemods
    mkdir -p /tmp/swap && cd /tmp/swap && git init -q
    printf "import { Box } from '@codecademy/gamut';\n" > a.tsx
    echo 'module.exports = { experimental: { esmExternals: false } };' > next.config.js
    git add -A && git commit -qm init
    node <repo>/packages/gamut-codemods/dist/bin.js scope-swap .

    Expect a [next-config] warning for next.config.js and the "Some next.config files set..." next step. next.config.js itself is unchanged.

PR Links and Envs

Repository PR Link
Mono N/A

🤖 Generated with Claude Code

@skillsoft/gamut ships strict-ESM .mjs. With experimental.esmExternals
off, Next require()s server externals and default imports from
@emotion/styled and react-select break while it collects page data.
next-config is report-only: dropping the flag can take other config with
it, so it warns and adds a checklist item instead of rewriting.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@dreamwasp
dreamwasp marked this pull request as ready for review October 20, 2026 16:56
@dreamwasp
dreamwasp requested a review from a team as a code owner October 20, 2026 16:56

This branch has not been deployed

No deployments
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.

1 participant