web-infra-dev / web-infra-dev/rslib

[Feature]: Remove `_webpack_require__.*` + `__webpack_exports__.*` definitions for CJS format in bundleless mode

Open
#594 2 comments 3 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

💡 feature Rspack
Dominant language
TypeScript
Stars
1k
Forks
67
Avg merge
6h 9m
Merged PRs (30d)
57

Description

What problem does this feature solve?

I am in a similar situation to https://github.com/web-infra-dev/rslib/issues/219. I think it's not the same, so I'm posting a new issue.

From what I know, rsbuild and therefore rslib are reimplementing the webpack algo. And that's cool. What I didn't expect is to use the bundle: false, a.k.a. "bundleless" mode and get a ton of repeated __webpack_require__.* definitions in each file for cjs format.

For example if I get an input file called math.ts with:

export const round = (val: number | null, precision: number = 0) => {
  if (val === null) {
    return Number.NaN;
  }
  const factor = Math.pow(10, precision);

  return Math.round(val * factor) / factor;
};

The bundleless mode of rslib produces ESM output of:

const round = (val, precision = 0)=>{
    if (null === val) return Number.NaN;
    const factor = Math.pow(10, precision);
    return Math.round(val * factor) / factor;
};
export { round };

//# sourceMappingURL=math.mjs.map

Which is fantastic, but the cjs (common js) version of of the same is:

"use strict";
var __webpack_require__ = {};
(()=>{
    __webpack_require__.d = function(exports1, definition) {
        for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
            enumerable: true,
            get: definition[key]
        });
    };
})();
(()=>{
    __webpack_require__.o = function(obj, prop) {
        return Object.prototype.hasOwnProperty.call(obj, prop);
    };
})();
(()=>{
    __webpack_require__.r = function(exports1) {
        if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
            value: 'Module'
        });
        Object.defineProperty(exports1, '__esModule', {
            value: true
        });
    };
})();
var __webpack_exports__ = {};
__webpack_require__.r(__webpack_exports__);
__webpack_require__.d(__webpack_exports__, {
    round: function() {
        return round;
    }
});
const round = (val, precision = 0)=>{
    if (null === val) return Number.NaN;
    const factor = Math.pow(10, precision);
    return Math.round(val * factor) / factor;
};
var __webpack_export_target__ = exports;
for(var __webpack_i__ in __webpack_exports__)__webpack_export_target__[__webpack_i__] = __webpack_exports__[__webpack_i__];
if (__webpack_exports__.__esModule) Object.defineProperty(__webpack_export_target__, '__esModule', {
    value: true
});

//# sourceMappingURL=math.js.map

And that is for every file.

What does the proposed API look like?

No changes of API, changes of output to be more similar to other tools like tsc, rollup, etc.

If this is a fundamental thing for rsbuild and rslib then at least those __webpack_* definitions can be reused and not redefined in every file?

When targetingcjs format, rollup produces:

'use strict';

const round = (val, precision = 0) => {
    if (val === null) {
        return Number.NaN;
    }
    const factor = Math.pow(10, precision);
    return Math.round(val * factor) / factor;
};

exports.round = round;
//# sourceMappingURL=math.cjs.map

When targeting cjs format & configured specifically for node 22 (via tsconfig base), tsc produces:

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.round = void 0;
const round = (val, precision = 0) => {
    if (val === null) {
        return Number.NaN;
    }
    const factor = Math.pow(10, precision);
    return Math.round(val * factor) / factor;
};
exports.round = round;

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the bundleless CJS output using the issue's math.ts example and compare it with the shown ESM, Rollup, and tsc outputs. Trace where the CJS export helpers and _webpack* definitions are emitted; done means the generated files no longer repeat unnecessary definitions while preserving the expected exports and source maps.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, typescript
Domain
build-system, tooling
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.