Skip to content

fix: CLIPlugin dynamic import interop under Bun#4799

Merged
alexander-akait merged 2 commits into
mainfrom
fix/cli-plugin-import-interop
Jul 4, 2026
Merged

fix: CLIPlugin dynamic import interop under Bun#4799
alexander-akait merged 2 commits into
mainfrom
fix/cli-plugin-import-interop

Conversation

@alexander-akait

Copy link
Copy Markdown
Member

Summary

The CLIPlugin lazy import unwraps .default twice, which is correct for Node's CJS interop but undefined under Bun (it honors the __esModule marker and unwraps once already), so every bun --bun webpack build fails with "undefined is not a constructor"; unwrap interop-safely like the existing parserModule pattern.

What kind of change does this PR introduce?

fix

Did you add tests for your changes?

No; covered by webpack/webpack#21334, which runs webpack's WebpackCli.longtest.js suite under Bun (existing suites here still pass).

Does this PR introduce a breaking change?

No

If relevant, what needs to be documented once your changes are merged or what have you already documented?

n/a

Use of AI

Written with Claude Code: it diagnosed the Bun interop failure and authored the fix and changeset; verified via tsc --build, a Bun/Node runtime repro, and webpack's WebpackCli suite under Bun.


Generated by Claude Code

Bun honors the __esModule marker when dynamic-importing the compiled
CJS, so the Node-interop double .default unwrap yields undefined and
every build crashes with 'undefined is not a constructor'.
Copilot AI review requested due to automatic review settings July 4, 2026 18:13
@changeset-bot

changeset-bot Bot commented Jul 4, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 5727a55

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

This PR includes changesets to release 1 package
Name Type
webpack-cli 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

@codecov

codecov Bot commented Jul 4, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.30%. Comparing base (b4ea5a7) to head (5727a55).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##             main    #4799   +/-   ##
=======================================
  Coverage   93.30%   93.30%           
=======================================
  Files          14       14           
  Lines        5463     5466    +3     
  Branches      792      793    +1     
=======================================
+ Hits         5097     5100    +3     
  Misses        364      364           
  Partials        2        2           
Files with missing lines Coverage Δ
packages/webpack-cli/src/webpack-cli.ts 96.71% <100.00%> (+<0.01%) ⬆️

Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update b4ea5a7...5727a55. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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.

Pull request overview

Fixes webpack-cli failing under Bun due to differing ESM↔CJS default-export interop behavior when lazily importing CLIPlugin.

Changes:

  • Adjust CLIPlugin dynamic import to unwrap .default in an interop-safe way across Node and Bun.
  • Add a changeset to publish the fix as a patch release.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
packages/webpack-cli/src/webpack-cli.ts Updates lazy import logic to handle Node/Bun CJS interop differences when resolving CLIPlugin.
.changeset/cli-plugin-import-interop.md Adds a patch changeset entry documenting the Bun interop fix.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +3253 to +3256
// Node's CJS interop nests the class under `.default.default`; Bun honors
// `__esModule` and unwraps once already, leaving the class one level up.
const cliPluginModule = (await import("./plugins/cli-plugin.js")).default;
const CLIPlugin = cliPluginModule.default ?? cliPluginModule;

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Added in 5727a55: test/api/cli-plugin-interop/ mocks the cli-plugin module to the shape Bun's __esModule-aware interop produces (the class itself, no nested .default) and asserts a build still applies CLIPlugin. Verified it fails with "CLIPlugin is not a constructor" against the previous double-unwrap code.


Generated by Claude Code

Mocks the cli-plugin module to the shape Bun's __esModule-aware interop
produces (the class itself) and asserts a build still applies CLIPlugin.
@alexander-akait alexander-akait merged commit 97c5541 into main Jul 4, 2026
19 checks passed
@alexander-akait alexander-akait deleted the fix/cli-plugin-import-interop branch July 4, 2026 19:56
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.

2 participants