Skip to content

[Bug]: experiments.advancedEsm default value true causes __webpack_require__ runtime in ESM output and build failures #1487

@laowudui

Description

@laowudui

Version

System:
    OS: Linux 6.6 Ubuntu 24.04.3 LTS 24.04.3 LTS (Noble Numbat)
    CPU: (12) x64 12th Gen Intel(R) Core(TM) i5-12450H
    Memory: 4.34 GB / 7.64 GB
    Container: Yes
    Shell: 5.2.21 - /bin/bash
  npmPackages:
    @rslib/core: ^0.19.6 => 0.19.6

Details

Since rslib v0.19.0, the default value of experiments.advancedEsm changed from false to true. This causes ESM format library output to include __webpack_require__ runtime code and export a separate runtime file (e.g., rslib-runtime.js).

This behavior change is unexpected for most library developers because:

  1. ESM output should be as clean as possible: Standard ESM format should not contain webpack runtime
  2. Exporting __webpack_require__ pollutes the consumer's environment: This can cause issues with build tools like Vite, Rollup, esbuild, etc.
  3. Unnecessary additional files: The extra runtime file increases library size and complexity
  4. Breaking change not clearly documented: The default value change may cause existing projects to break after upgrading

Critical Issue: Build Fails When Subdirectories Contain index.ts

When the source directory structure contains subdirectories with index.ts files, the build fails completely with advancedEsm: true (the default).

Example directory structure:

src/
├── index.ts
├── core/
│   └── index.ts
├── utils/
│   └── index.ts
├── component/
│   └── index.ts
└── ...

This is a common pattern in library development where each module has its own index.ts for barrel exports. With advancedEsm: true, the build process incorrectly treats these as separate entry points, causing build failures.

Reproduction Steps

// rslib.config.ts
import { defineConfig } from "@rslib/core";

export default defineConfig({
  lib: [
    {
      format: "esm",
      output: {
        target: "web",
        filename: {
          js: "lib.esm.js",
        },
      },
    },
  ],
});

With @rslib/core@0.19.0+, the output contains:

// rslib-runtime.js
var __webpack_module_cache__ = {};
function __webpack_require__(moduleId) { ... }
export { __webpack_require__ };

// index.js
import { __webpack_require__ } from "./rslib-runtime.js";
// ...

Expected Behavior

ESM format libraries should output clean ESM code by default, without webpack runtime:

// index.js
// Clean ESM code using standard export statements
export { foo, bar };

Suggestions

  1. Revert experiments.advancedEsm default value back to false
  2. Or at least document this behavior change and its implications more clearly in the documentation and CHANGELOG
  3. If features from advancedEsm: true (like code splitting) are needed, users should explicitly enable it

Workaround

Users can manually set experiments.advancedEsm: false:

export default defineConfig({
  lib: [
    {
      format: "esm",
      experiments: {
        advancedEsm: false,
      },
    },
  ],
});

Version Information

  • @rslib/core: 0.19.0+

Reproduce link

no

Reproduce Steps

no

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions