Skip to content

CodeMirror 6 Package Deduplication Issue in Webpack #19615

Open
anisaedalati-lgtm/webpack
#2

Description

@hackerstanislav

Summary

When integrating CodeMirror 6 in applications bundled with webpack, multiple instances of critical CodeMirror packages (@codemirror/state and @codemirror/view) are created, causing broken functionality, incompatible state objects, and rendering problems. This requires manual deduplication configuration in both bundlers, which should ideally be handled automatically.

Environment
Webpack: v5.58.0
Webpack CLI: v4.9.2
Webpack Dev Server: v4.15.2
@codemirror/state: v6.5.2
@codemirror/view: v6.36.4
React: v18.2.0
Node.js: (latest stable)
OS: macOS

Description
CodeMirror 6 is modular and consists of several packages that work together. When integrated into a project using webpack or vite, the bundlers fail to properly deduplicate the CodeMirror packages, leading to multiple instances of the same package being loaded. This causes critical issues with the editor functionality.

The two most affected packages are:

@codemirror/state: Manages the editor state and transactions
@codemirror/view: Handles the DOM representation of the editor

Without proper deduplication, the following issues occur:

  • Multiple instances of CodeMirror packages leading to broken functionality
  • Errors related to incompatible state objects
  • Rendering problems in the code editor

Steps to Reproduce

  • Create a new React application using webpack or vite
  • Install CodeMirror 6 packages: @codemirror/state, @codemirror/view, and other required CodeMirror packages
  • Create a component that uses CodeMirror
  • Import this component in another part of your application
  • Run the application and observe the console errors or broken functionality

Current Workarounds

// In webpack.config.js/cjs

resolve: {
    // Dedupe packages to avoid duplicate instances
    alias: {
        "@codemirror/state": path.resolve(__dirname, "node_modules/@codemirror/state"),
        "@codemirror/view": path.resolve(__dirname, "node_modules/@codemirror/view"),
    },
},

Expected Behavior

The bundlers should automatically deduplicate these packages without requiring manual configuration. This is especially important for packages like CodeMirror that rely on singleton instances of certain modules to function correctly.

Actual Behavior

Without the manual deduplication configuration, multiple instances of CodeMirror packages are created, causing the editor to malfunction with errors related to incompatible state objects and rendering issues.

Possible Root Cause

The issue may be related to how webpack handle module resolution and deduplication, particularly for packages that require singleton instances or are mark as sideEffect false. The problem might be exacerbated by the modular nature of CodeMirror 6, where different parts of an application might import different CodeMirror packages that internally depend on @codemirror/state and @codemirror/view. I think that is somehow related to agresive tree shaking that cause some parts of codemirror package are created more than once and than some inner check for instanceof are not working. Without alias rule i was observe that state object create was called 2 times from 2 different places in final bundle, but with allias is also called 2times but from 1 place now.

Additional info

We use in project packages that internally use codemirror multiple times, but always its same version of this package.

Activity

  1. alexander-akait commented on Jun 20, 2025

    @alexander-akait
    Member

    I don't think webpack related to this problem, sounds like you have monorepo and do not hoist your dependecies, otherwise it is expected behavior, can you provide your structure of a project with small examples, thank you

  2. hackerstanislav commented on Jun 24, 2025

    @hackerstanislav
    Author

    Thank you @alexander-akait for the quick response!

    I’ve prepared a minimal reproduction inside our boilerplate template (gdc-template.zip). It includes both Webpack and Vite configurations. After extracting the archive, you can simply run:

    npm install
    npm run start
    

    This will launch the Webpack version.

    A few important notes:

    • The app connects to our internal backend, and while I’m not allowed to share credentials or provide access, the issue can still be simulated without backend access. You can observe the problem just by analyzing the build output.
    • Specifically, the final bundle will contain two instances of @codemirror/state and @codemirror/view.
    • If you uncomment the deduplication/aliasing lines in the Webpack config, you'll see that these packages are properly deduplicated and appear only once in the bundle, resolving the issue.

    For context, we’re not directly importing CodeMirror in our codebase. These packages are pulled in transitively by dependencies (including 3rd-party ones). All are using the same version, but deduplication does not occur automatically without explicit config.

    Let me know if you need a stripped-down version that runs fully offline—I can work on that if needed.

    Thanks again for your help!

    gdc-template.zip

  3. Yashwanth1124 commented on Nov 3, 2025

    @Yashwanth1124

    Hi @alexander-akait @hackerstanislav!
    Prepping for GSoC 2026—this dedup issue hits many React/CodeMirror setups. Downloaded the repro zip and tested on webpack 5.94.0/Node 22/macOS.

    Quick Update: Built on the fork PR (anisaedalati-lgtm#2) for SingletonModulePlugin.

    • Verified it fixes the dupe in the zip (single @codemirror/state instance now).
    • Added CodeMirror integration test + docs note.
    • PR to main incoming: [link once pushed].

    Thoughts on auto-enabling for known singletons like CodeMirror? Happy to iterate!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions