Skip to content

HMR broken with separate styles entry after tapable 2.3.1 #20693

@FrozenPandaz

Description

@FrozenPandaz

Bug report

What is the current behavior?

When using webpack-dev-server with hot: true and a separate styles entry point, the compiled styles.js throws at runtime:

Error: [HMR] Hot Module Replacement is disabled.

This started happening after tapable@2.3.1 was published (2026-03-23).

What is the expected behavior?

module.hot should evaluate as truthy in the styles entry when HMR is enabled, so webpack/hot/dev-server.js doesn't throw.

Minimal reproduction

https://github.com/FrozenPandaz/webpack-hmr-styles-repro

git clone https://github.com/FrozenPandaz/webpack-hmr-styles-repro
cd webpack-hmr-styles-repro
pnpm install
pnpm serve
# Open http://localhost:4200 — browser console shows the error

Pinning tapable to 2.3.0 resolves the issue.

Root cause

HotModuleReplacementPlugin taps parser.hooks.evaluateIdentifier.for("module.hot") with before: "NodeStuffPlugin". This ensures module.hot evaluates as truthy so webpack keeps the if (module.hot) branch.

However, NodeStuffPlugin never taps evaluateIdentifier for module.hot, so the before reference is invalid.

  • tapable 2.3.0: invalid before → tap inserted at position 0 → module.hot evaluates truthy → works
  • tapable 2.3.1: tapable PR #198 deletes invalid before names → tap goes to natural position → module.hot evaluates falsy for styles entry → throws

Other relevant information:

  • webpack: 5.105.4
  • webpack-cli: 7.0.2
  • webpack-dev-server: 5.2.3
  • tapable: 2.3.1 (works with 2.3.0)
  • Node.js: v24.9.0
  • OS: Linux

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions